问题描述
我正在学习Fortran的基础知识。我创建了一个简单的子程序来初始化矩阵:
程序测试
$ p $然后输出是
整数,参数:: n = 1024
真实:: a(n,n)
调用init(a)
write(*,*)a(1,1)
结束程序
子程序init(a)
real :: a(n,n)
a(:, :) = 3.0
结束子程序
0.0
,而不是预期的3.0
。除此之外,valgrind
表示:== 7006 ==条件跳转或移动取决于未初始化的值
== 7006 == at 0x400754:init_(在/ home / marcin / proj / mimuw / fortran / test)
== 7006 == by 0x4007A4 :MAIN__(在/ home / marcin / proj / mimuw / fortran / test)
== 7006 == by 0x40083B:main(在/ home / marcin / proj / mimuw / fortran / test)
为什么?
n
参数被编译器正确识别,应该是全局参数。
我用gfortran 6.3.1
解决方案
不是全局变量,它是主程序的局部变量。
该子程序是一个完全独立于主程序的编译单元,它们不共享任何信息。
一个子程序可以查看父模块的其他变量,如果它是一个模块程序,或者父程序或程序的变量(如果它是内部程序的话)。
请务必阅读Fortran程序的结构并尽可能使用模块。优先考虑内部程序模块。您将看到如何将子例程放入模块中,或者如何将其设置为链接中的主程序。
我没有提到常见的块,不使用它们,它们已经过时。并在每个编译单元中重新使用
implicit none
。I'm learning the basics of Fortran. I created a simple subroutine initializing a matrix:
program test integer, parameter :: n = 1024 real :: a(n, n) call init(a) write (*, *) a(1, 1) end program subroutine init(a) real :: a(n, n) a(:, :) = 3.0 end subroutine
Then the output is
0.0
instead of expected3.0
. Apart from that,valgrind
says that:==7006== Conditional jump or move depends on uninitialised value(s) ==7006== at 0x400754: init_ (in /home/marcin/proj/mimuw/fortran/test) ==7006== by 0x4007A4: MAIN__ (in /home/marcin/proj/mimuw/fortran/test) ==7006== by 0x40083B: main (in /home/marcin/proj/mimuw/fortran/test)
Why? The
n
parameter is correctly recognized by the compiler and should be a global one.I compiled the program with gfortran 6.3.1
解决方案
n
is not a global variable, it is a local variable of the main program.The subroutine is a completely independent compilation unit from the main program and they do not share any information.
A subroutine can "see" other variables of the parent module, if it is a module procedure, or variables of a parent (host) procedure or program if it is an internal procedure.
Be sure to read about the structure of Fortran programs and use modules as much as possible. Prefer modules over internal procedures. You will see how to put the subroutine into a module or how to make it internal to the main program in the link.
I did not mention common blocks, just don't use them, they are obsolete. And rember to use
implicit none
in every compilation unit.这篇关于在Fortran中使用全局变量时出现错误结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
08-23 15:25