Fortran如何关联例程与子程序?common块传值错误怎么解决?
问题根因
你遇到的错误是由Fortran无名公共块(common)的匹配规则导致的:Fortran的公共块是按变量在块中声明的顺序对应内存地址,而非按变量名匹配。
你主程序中定义的无名公共块内存排布顺序为 a → b → c → d → e:
f1函数中声明的无名公共块包含3个变量,刚好对应公共块前3个内存位置,因此取值正常。f2函数中声明的无名公共块包含2个变量,会默认匹配无名公共块的前2个内存位置,也就是说f2里的d实际拿到的是主程序中a的值,e拿到的是主程序中b的值,最终计算结果自然不符合预期。
解决方案
方案1:使用命名公共块(兼容旧标准)
给不同用途的公共块分配独立名称,变量会按「块名+声明顺序」匹配,不会出现串位问题。修正后代码如下:
Program Example ! 声明两个命名公共块,分别给f1、f2传参 common /blk_f1/ a,b,c common /blk_f2/ d,e print*,"Enter a" read*,a print*,"Enter coefficient of x in f1(x)" read*,b print*,"Enter intercept in f1(x)" read*,c print*,"Enter coefficient of x in f2(x)" read*,d print*,"Enter intercept in f2(x)" read*,e Print*,f1(2.),f2(3.) pause end !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ function f1(x) common /blk_f1/ a,b,c f1=a*x**2+b*x+c return end !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ function f2(y) common /blk_f2/ d,e f2=d*y+e return end !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
方案2:使用Module模块(现代Fortran推荐写法)
Fortran90及以后标准更推荐用模块封装全局变量,完全规避公共块的匹配错误问题,代码可维护性更高:
! 定义模块封装全局参数 module param_mod implicit none real :: a,b,c,d,e end module param_mod Program Example use param_mod implicit none print*,"Enter a" read*,a print*,"Enter coefficient of x in f1(x)" read*,b print*,"Enter intercept in f1(x)" read*,c print*,"Enter coefficient of x in f2(x)" read*,d print*,"Enter intercept in f2(x)" read*,e Print*,f1(2.),f2(3.) pause end !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ function f1(x) use param_mod implicit none real :: x, f1 f1=a*x**2+b*x+c return end !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ function f2(y) use param_mod implicit none real :: y, f2 f2=d*y+e return end !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
内容的提问来源于stack exchange,提问作者seymatinsar
相关产品推荐
相关产品推荐

