我经常使用 FORTRAN,但我从未接受过以正确方式编写源代码的正式指导。我目前使用模块来存储全局变量,但我知道您也可以使用它们来存储子例程和函数。我使用的代码有很多子例程,因为它们非常庞大且复杂。所有函数和子程序都应该在模块中吗?如果是这样,为什么?
最佳答案
一般来说,您的第一个问题的答案是肯定的,稍后我会回答您的第二个问题。首先请注意,这是对一般问题的一般答案,围绕 SO Fortran 问题的明亮 Spark 很可能会提出模块不适用的特殊情况。我提前反驳说,这个答案是针对模块的新手。一旦您不再是新手,您就可以制定自己的问题答案。
模块对程序员最有用,可帮助组织和构建程序或程序套件。它们提供了一种机制来封装用户定义类型的定义以及对这些类型进行操作的函数/子例程。在 Fortran 90 和 95 中,这种封装有点特别,因为它依赖于程序员关于如何将程序分解为多个部分的想法。随着 Fortran 2003 中面向对象工具的引入,现在有了更清晰的“规则”来识别每个模块中属于哪些元素。
例如,您可以设想一个用于有理算术的类型和过程的模块。通过将所有实现您伟大想法的代码保存在一个模块中,您可以隐藏程序其他部分的实现(不需要知道细节)并只公开您希望公开的部分(查看 PRIVATE
和 PUBLIC
关键字)。您可以立即看到将代码组织成模块的另一个优势; USE
更容易你在一个新程序中的理性算术模块,而不是将你的巨型源文件中的代码剪切并传递到另一个巨型源文件中。当你想处理你的有理算术时,你在一个模块中处理代码,而不是在你的文件中散布的代码。
模块还允许您管理名称冲突。例如,您的有理算术模块可能会定义一个名为 add
的操作。 ,并且您可能还有一个多精度整数算术模块,它定义了一个名为 add
的操作.如果您尝试 USE
这两个模块都在一个程序(或另一个模块)中,然后编译器将警告(可能引发错误)相同的名称在使用模块的范围内定义了两次。使用关联模块实体时可以使用重命名。您也可以使用 ONLY
子句仅导入用户需要的那些模块实体。
注意模块 USE
是传递的,如果 A 使用 B 并且 B 使用 C 你不必同时声明 A 使用 C (尽管如果你已经重命名实体或指定 ONLY
子句你必须确保什么是传递特定的案子)。
简而言之,模块是处理程序复杂性的主要 Fortran 机制,通过将它们分成可管理的 block 。 Fortran 2008,当该功能由编译器实现时,引入 SUBMODULE
s 也是,它 promise 更好地支持以这种方式处理复杂性。
模块也很有用,因为语言标准要求编译器为模块中定义的过程生成显式接口(interface),以便在编译时对参数进行类型检查。请注意,这些接口(interface)(您从未真正看到)被称为显式接口(interface),以与隐式接口(interface)形成对比,隐式接口(interface)是未在模块内部定义的过程(或 CONTAIN
在使用它们的程序单元中编辑)具有。当然,您可以为此类过程编写显式接口(interface),但在短期和长期运行中,让编译器为您完成几乎总是更容易。
正如@Telgin 已经指出的那样,模块也有助于增量编译。
关于function - 在 Fortran 中正确使用模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11953087/