1、common
虽然准确来说Fortran中没有所谓的全局变量,但common开辟公用区就是在定义全局变量!也就是我们无论在子程序还是主程序中给变量赋值了,那该变量就一直是这个值。而且注意,common开辟公用区时只要位置对应,无论定义的变量名是否一样,对应位置的参数就永远保持这个值。
For example:
Situation1:
program fcode
! Implicit None
common /group1/ inf , e
call SubOK()
write(*,*) inf , e !// 输出1,2.040000
End Program fcode
Subroutine SubOK()
! Implicit None
common /group1/ inff, xgasdf
inff = 1.04
xgasdf = 2.04
End Subroutine SubOK
Situation2:
program fcode
! Implicit None
common /group1/ inff, xgasdf
inff = 1.04
xgasdf = 2.04
call SubOK()
End Program fcode
Subroutine SubOK()
! Implicit None
common /group1/ inf , e
write(*,*) inf , e !// 输出1,2.040000
End Subroutine SubOK
以上这两种情况完全是等价的。不过为了避免混淆,一般公共区,同一个变量用同一个名字比较好。因此,必须保证对应变量的顺序、精度、大小、长度等完全一致。稍有差别就会出现对应“错位”。
PS:1、代码中的 /group1/ 就是给各个子程序中的公共变量分区,个人感觉就是使代码更工整一些,也没啥大作用。
2、这里没有采用Implicit None,所以common开辟了公共区之后我们可以不用定义变量类型,这里默认IN规则,即 “在程序中,凡是变量名以字母i、j、k、l、m、n(或I、J、K、L、M、N)开头的变量被默认为整型变量,以其他字母开头的变量被默认为实型变量。” 否则common 公共区的变量,需要在每一个使用它的函数内重新定义!!!
For example:
program fcode
Implicit None
common a , b
Integer :: a = 1 , b = 2 !// common 并不说明类型,需单独定义类型
call SubOK()
End Program fcode
Subroutine SubOK()
Implicit None
common a , b
Integer :: a , b
write(*,*) a , b !// 输出1,2,正确
End Subroutine SubOK
2、Include
当我们需要定义很多变量,或者声明很多常数(PS:利用parameter(MAXP=8000),常量MAXP将一直是8000),可以将这些变量、常量单独写成一个文件,然后用include 插入。可以简单理解为:打开你要include的 文件,全选,复制。粘贴在 include 语句处。
For example:
include 'kennet.inc',若kennet.inc不在同一目录下,也可以直接用绝对路径
3、Module
Moudle概念,不仅克服了COMMON的缺陷,可以完全替代COMMON,还进行了功能扩展。而且,Module中也可以定义COMMON。强烈建议放弃使用COMMON,用Module代替。
一个 Module 是一个代码单元,与主程序,外部子(例行)程序或函数是差不多的“等级”。但它的功能更强大,也更便捷。
在 Module 中,我们可以定义若干变量(含数组、type、可分配数组等) 。这些变量会存储在一个特定的空间内,而被所有 use 了该模块的程序单元直接使用。而且这种使用,是按照变量的名称而对应的,而非变量的内存字节顺序。
同时,use 了该模块的程序单元,也继承了这些变量的类型、精度、大小、长度等属性,而不必(也不能)重新定义。
Module modname
Implicit None
!// 明确变量类型,顺序无关
Integer , save :: a = 1 , b = 2
End Module modname
program www_fcode_cn
use modname !// 无需,也不能再定义 a b
Implicit None
write(*,*) b , a !// 输出 2,1 正确
a = 3
b = 4
!// 按变量名对应,因此倒序输出,其值也倒序
call Sub()
End Program www_fcode_cn
Subroutine Sub()
use modname !// 无需,也不能再定义 a b
Implicit None
write(*,*) a , b !// 输出 3,4 正确
End Subroutine Sub
在这段代码中,我们书写了一个 Module,名叫 modname。其中包含两个变量 a b,并含有初值 1 和 2
save 属性表明这些变量会被保存起来,以便在不同的程序单元间保持同样的值。
(虽然语法未明确指出,但所有的编译器都默许 Module 中的变量具有 save 属性,因此,很多时候 save 也可以忽略不写)
在主程序里,我们的 a b 输出顺序颠倒了。但可以看到,输出的结果是符合我们预期的。