Fortran 中的common,include和module

萧宏峻
2023-12-01

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 输出顺序颠倒了。但可以看到,输出的结果是符合我们预期的。
 

 类似资料: