Fortran 77 函数 return 类型不匹配
Fortran 77 function return type mismatch
我一直在尝试为一个大学项目学习 Fortran 77,我在 windows 10 中编写了以下代码:
program Q_Value
real BEs(4),Masses(4)
real Q,Tthr
integer i,Nuclei(4,2),A,Z
do 10 i=1,4,1
write(*,100)'Give the info for Nuclei:',i
100 format(A,I1)
write(*,*)'A='
read(*,*)Nuclei(i,1)
write(*,*)'Z='
read(*,*)Nuclei(i,2)
if((Nuclei(i,1).EQ.0).OR.(Nuclei(i,2).EQ.0))then
BEs(i)=0.
else
BEs(i)=BetheWeiss(Nuclei(i,1),Nuclei(i,2))
endif
Masses(i)=Mass(Nuclei(i,1),Nuclei(i,2),BEs(i))
10 continue
[...]
end
real function Mass(A,Z,BE)
integer A,Z
real BE,mass
c local var's
parameter(Mp=938.2720813,Mn=939.5654133)
c statements
Mass=((A-Z)*Mn)+(Z*Mp)-BE
return
end
在 GNU Fortran (gfortran 8.1.0) 中编译时出现以下错误:
Masses(i)=Mass(Nuclei(i,1),Nuclei(i,2),BEs(i))
1
Error: Return type mismatch of function 'mass' at (1) (INTEGER(4)/REAL(4))
谁能帮我解决这个问题,因为就我而言,我的函数 return 是一个实数,而 Masses(i)
是一个实数变量。
默认的隐式类型规则是,如果名称的第一个字母是 I 、 J 、 K 、 L 、 M 或 N ,则数据类型为整数,否则为实数。
因为你的函数是mass()
,它以M开头,并且没有在主程序中声明,所以在那里被认为是一个整数函数。这与函数声明冲突并且编译器抱怨。如果你想保留极其古老的 FORTRAN 77,你需要的是
real mass
在主程序中。
最好使用现代 Fortran 的特性,从 IMPLICIT NONE
开始并将函数放入模块或使其成为主程序的内部。
您也可以在主程序中使用替代隐式语句来修复错误消息(请参阅我的评论),但我 强烈 不鼓励除 IMPLICIT NONE
之外的任何其他内容。 =14=]
Mass 函数声明在主程序范围之外。因此,编译器会推断 Mass 函数的类型,即使它是在同一源代码块中明确声明的。为了克服这个问题,您需要在调用程序中声明一个接口块:
program Q_Value
[...]
interface Mass
real function Mass(A,Z,BE)
integer :: A
integer :: Z
real :: BE
end function
end interface
end program
real function Mass(A, Z, BE)
[..]
end function
我在 https://onlinegdb.com/BkjLxcy9S 上有一个原始源代码的有效修改版本,其中包含此解决方案。我删除了对 BetheWeiss 的调用并将其替换为任意赋值,推断它只是您在原始 post 中省略的源代码中定义的函数。您在那里也需要相同类型的界面。
我一直在尝试为一个大学项目学习 Fortran 77,我在 windows 10 中编写了以下代码:
program Q_Value
real BEs(4),Masses(4)
real Q,Tthr
integer i,Nuclei(4,2),A,Z
do 10 i=1,4,1
write(*,100)'Give the info for Nuclei:',i
100 format(A,I1)
write(*,*)'A='
read(*,*)Nuclei(i,1)
write(*,*)'Z='
read(*,*)Nuclei(i,2)
if((Nuclei(i,1).EQ.0).OR.(Nuclei(i,2).EQ.0))then
BEs(i)=0.
else
BEs(i)=BetheWeiss(Nuclei(i,1),Nuclei(i,2))
endif
Masses(i)=Mass(Nuclei(i,1),Nuclei(i,2),BEs(i))
10 continue
[...]
end
real function Mass(A,Z,BE)
integer A,Z
real BE,mass
c local var's
parameter(Mp=938.2720813,Mn=939.5654133)
c statements
Mass=((A-Z)*Mn)+(Z*Mp)-BE
return
end
在 GNU Fortran (gfortran 8.1.0) 中编译时出现以下错误:
Masses(i)=Mass(Nuclei(i,1),Nuclei(i,2),BEs(i))
1
Error: Return type mismatch of function 'mass' at (1) (INTEGER(4)/REAL(4))
谁能帮我解决这个问题,因为就我而言,我的函数 return 是一个实数,而 Masses(i)
是一个实数变量。
默认的隐式类型规则是,如果名称的第一个字母是 I 、 J 、 K 、 L 、 M 或 N ,则数据类型为整数,否则为实数。
因为你的函数是mass()
,它以M开头,并且没有在主程序中声明,所以在那里被认为是一个整数函数。这与函数声明冲突并且编译器抱怨。如果你想保留极其古老的 FORTRAN 77,你需要的是
real mass
在主程序中。
最好使用现代 Fortran 的特性,从 IMPLICIT NONE
开始并将函数放入模块或使其成为主程序的内部。
您也可以在主程序中使用替代隐式语句来修复错误消息(请参阅我的评论),但我 强烈 不鼓励除 IMPLICIT NONE
之外的任何其他内容。 =14=]
Mass 函数声明在主程序范围之外。因此,编译器会推断 Mass 函数的类型,即使它是在同一源代码块中明确声明的。为了克服这个问题,您需要在调用程序中声明一个接口块:
program Q_Value
[...]
interface Mass
real function Mass(A,Z,BE)
integer :: A
integer :: Z
real :: BE
end function
end interface
end program
real function Mass(A, Z, BE)
[..]
end function
我在 https://onlinegdb.com/BkjLxcy9S 上有一个原始源代码的有效修改版本,其中包含此解决方案。我删除了对 BetheWeiss 的调用并将其替换为任意赋值,推断它只是您在原始 post 中省略的源代码中定义的函数。您在那里也需要相同类型的界面。