fortran 佛说如是甚深经典。我从昔来所得慧眼。未曾得闻如是之经。
手气不错
Article

005.implicitTypeDefaultRule_隐式类型默认规则

2026年5月12日入门级

fortran早期为了便于书写,提供了隐式类型默认规则。如果程序中没有写implicit none,编译器会根据变量名首字母自动推断类型。

  • 当变量名以i、j、k、l、m、n开头时,默认是integer
  • 变量名以其他字母开头时,默认是real

自动推断类型的方式确实能让旧代码少写大量声明,但也容易把拼写错误悄然变成新变量。再加上随着计算机应用的广泛发展,需用代码提高可读性、可维护性、可复用性,便默契的使用语义化命名。隐式声明天然与语义化命名冲突,因此现代fortran代码通常在单元开始写implicit none

先看一段不推荐但能说明规则的代码。

program implicitTypeDefaultRuleDemo
  ! 本例故意不写implicit none,用来观察fortran默认隐式类型规则。
  ! 1.当变量名以i、j、k、l、m、n开头时,默认是integer类型。
  ! 2.变量名以其他字母开头时,默认是real类型。
  ! 注意:这条规则会和语义化命名发生冲突,也会让拼写错误更难被发现。

  moleculeCount=6.8 ! m开头,默认是integer;6.8会先转换成6后再存储。
  atomCount=moleculeCount*3.0 ! a开头,默认是real;右侧表达式结果存入real变量。
  ionCount=2.5 ! i开头,默认是integer;2.5会先转换成2后再存储。
  nStep=10 ! n开头,默认是integer;适合保存步数。

  totalAtomCount=atomCount+ionCount ! t开头,默认是real;表示正确的原子总数。
  totlaAtomCount=totalAtomCount+1.0 ! 拼写错误:totlaAtomCount是新real变量,不会报错。

  print *, "隐式类型默认规则:"
  print *,"moleculeCount=",moleculeCount
  print *,"atomCount=",atomCount
  print *,"ionCount=",ionCount
  print *,"nStep=",nStep
  print *,"totalAtomCount=",totalAtomCount
  print *,"totlaAtomCount=",totlaAtomCount
end program implicitTypeDefaultRuleDemo

这段程序中没有任何显式变量声明,但几乎所有fortran编译器都能通过编译。

编译运行

(base) hong@hongdeMacBook-Pro 005.implicit-typing % gfortran exampleImplicitTyping.f90
(base) hong@hongdeMacBook-Pro 005.implicit-typing % ./a.out 
 隐式类型默认规则:
 moleculeCount=           6
 atomCount=   18.0000000    
 ionCount=           2
 nStep=          10
 totalAtomCount=   20.0000000    
 totlaAtomCount=   21.0000000    
(base) hong@hongdeMacBook-Pro 005.implicit-typing % 
  • moleculeCount从语义看是“分子数量”,似乎应该是整数数量,编译器允许其被赋值为6.8,但会把它转换成integer,只保留6。真实程序里这种行为很危险。
  • ionCount以i开头,默认也是integer,所以2.5会变成2。
  • totlaAtomCount是totalAtomCount的拼写错误,但因为没有implicit none,它会被当成另一个新变量,程序不会立刻报错。

还有一种可能更危险的是拼写错误,在这段代码中,我本想更新totalAtomCount,却误写成了totlaAtomCount。


! 仍然不存在implicit none的片段
  totalAtomCount=atomCount+ionCount ! t开头,默认是real;表示正确的原子总数。
  totlaAtomCount=totalAtomCount+1.0 ! 拼写错误:totlaAtomCount是新real变量,不会报错。

由于没有implicit none,编译器会把totlaAtomCount看作另一个合法变量,而不是拼写错误。程序能编译,结果却违反了我的本意。

推荐写法是明确关闭隐式类型,并声明每个变量。

program implicitTypeDefaultRuleWithImplicitNoneDemo
  implicit none
  real :: moleculeCount
  real :: atomCount
  real :: ionCount
  integer :: nStep
  real :: totalAtomCount

  moleculeCount=6.8
  atomCount=moleculeCount*3.0
  ionCount=2.5
  nStep=10

  totalAtomCount=atomCount+ionCount

  print *,"此为implicit none版本"
  print *,"moleculeCount=",moleculeCount
  print *,"atomCount=",atomCount
  print *,"ionCount=",ionCount
  print *,"nStep=",nStep
  print *,"totalAtomCount=",totalAtomCount
end program implicitTypeDefaultRuleWithImplicitNoneDemo

假设在这段推荐写法中写错了变量名,比如有一条新语句totlaAtomCount=totalAtomCount+1.0,编译器会直接报错Symbol ‘totlaatomcount’ at (1) has no IMPLICIT type,我会在错误代码分类中详解——不同编译器检查错误的报错与解决。也就是说,implicit none会把拼写问题提前变成编译期错误,相较于运行后才发现结果不对,会安全得多。

知识点总结:

  • 默认隐式类型规则是:I到N开头为integer,其余字母开头为real。
  • 隐式类型规则是历史遗留便利,并非现代代码的好习惯,只需掌握,不荐使用。
  • 现代fortran建议每个程序单元都写implicit none。
  • implicit none能帮助编译器发现未声明变量和拼写错误。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注