计算化学公社
标题:
上古fortran代码中,用data给数组赋值的坑
[打印本页]
作者Author:
beefly
时间:
2022-8-26 09:53
标题:
上古fortran代码中,用data给数组赋值的坑
本帖最后由 beefly 于 2022-8-26 11:10 编辑
考古fortran代码的时候,经常遇到用data语句给数组赋初值,但是用现今的fortran编译器可能会导致错误结果。
例一
common /common1/ a1(3), a2(3)
call dat1
call dat2
write(*,*) 'in main:'
write(*,*) 'a1=',a1
write(*,*) 'a2=',a2
end
subroutine dat1
common /common1/ a1(3), a2(3)
data (a1(i),i=1,3)/ 1.0, 2.0, 3.0/
end
subroutine dat2
common /common1/ a1(3), a2(3)
data (a2(i),i=1,3)/-1.0,-2.0,-3.0/
end
复制代码
这段代码的本意,是在子程序dat1中给a1赋初值,在子程序dat2中给a2赋初值。ifort编译后运行,给出了预期的结果:
in main:
a1= 1.000000 2.000000 3.000000
a2= -1.000000 -2.000000 -3.000000
复制代码
而gfortran编译后,运行结果却是
in main:
a1= 1.00000000 2.00000000 3.00000000
a2= 0.00000000 0.00000000 0.00000000
复制代码
在两个子程序中,由于不存在可执行语句,也可以把“
subroutine
”改成“block data”,然后删除主程序中的两个call语句。此时gfortran编译运行的结果又变成了
in main:
a1= 0.00000000 0.00000000 0.00000000
a2= -1.00000000 -2.00000000 -3.00000000
复制代码
这说明对于gfortran,位于同一个common block里的多个数组,只能在同一个
subroutine
或block data里用data一起赋初值。如果在不同的
subroutine
或block data里赋初值,需要改为直接赋值的可执行语句(
subroutine
),或者把common block拆开:
common /common1/ a1(3)
common /common2/ a2(3)
复制代码
例二
dimension a1(3)
data a1/3*1.0/
data a1(2)/-2.0/
write(*,*) 'a1=',a1
end
复制代码
在给数组a1赋初值的时候,先全部设为1.0,再令第二个数组元素a(2)=-2.0。但是无论ifort还是gfortran,编译、运行的结果都是1.0!根据一些古籍提供的源代码,可能MS-V. Fortran编译器会给出想要的结果。这说明用data给某个数组赋初值的操作,能且只能做一次。
欢迎光临 计算化学公社 (http://bbs.keinsci.com/)
Powered by Discuz! X3.3