在Fortran中正确使用模块 [英] Proper use of modules in Fortran

查看:216
本文介绍了在Fortran中正确使用模块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我和FORTRAN一起工作了很多,但我从来没有以正确的方式编写源代码。我目前使用模块来存储全局变量,但我知道你也可以使用它们来存储子程序和函数。我使用的代码有很多子程序,因为它们非常大且复杂。是否所有的功能和子程序都在模块中?如果是这样,为什么?

解决方案

通常,第一个问题的答案是我马上就会回答你的第二个问题。首先需要注意的是,这是一般性问题的一般答案,谁在SO Fortran问题中出现的明亮火花可能会出现模块不适用的特殊情况。我事先反驳说,这个答案是针对模块的新手。一旦你不再是新手,你可以为自己的问题制定自己的答案。

模块对程序员最有用,可以帮助组织和构建程序或套件的节目。它们提供了一种机制来封装用户定义类型和函数/子例程的定义,这些类型在这些类型上运行。在Fortran 90和95中,这种封装有点特别,因为它依赖于程序员关于如何将程序分解成多个部分的想法。通过在Fortran 2003中引入面向对象的工具,现在有了更明确的规则来确定每个模块中的元素。

例如,您可以使用构想适用于合理算术的类型和程序的模块。通过将实现伟大想法的所有代码保存在一个模块中,您可以将程序的其他部分(不需要知道细节)隐藏起来,只显示您希望公开的部分(查看 PRIVATE PUBLIC 关键字)。您可以马上看到将代码组织到模块中的另一个优点;在一个新程序中对于 USE 您的理性计算模块要比将超级源文件中的代码剪切并移出另一个超级源文件要容易得多。当你想使用理性算术时,你可以在一个模块中处理代码,而不是在代码中传播所有文件。



模块还允许您管理名称冲突。例如,您的理性计算模块可能会定义一个名为 add 的操作,并且您还可能有一个多精度整数算术模块,该模块定义一个名为添加。如果你试图在程序(或另一个模块)中使用 USE 这两个模块,那么编译器会发出警告(可能引发一个错误),同一个名字在范围内定义两次使用模块。您可以在使用关联模块实体时使用重命名。您也可以使用 ONLY 子句仅导入用户需要的那些模块实体。



请注意,模块 USE 是可传递的,如果A使用B和B使用C,则不必声明A使用C(但如果您已重命名实体或指定 ONLY 子句,您必须确定在特定情况下传递的是什么)。



简而言之,模块是主体Fortran机制通过将程序分解为可管理的块来处理程序的复杂性。 Fortran 2008,当该功能由编译器实现时,也引入了 SUBMODULE ,这为以这种方式处理复杂性提供了更好的支持。



模块也很有用,因为语言标准要求编译器为模块中定义的过程生成显式接口,以便在编译时针对参数进行类型检查。请注意,这些接口(您从来没有真正看到过)被称为explicit,与隐式接口形成鲜明对比,这是在程序单元内没有定义的程序(或 CONTAIN )它使用它们)有。当然,您可以为这些过程编写明确的接口,但在短期和长期运行中,让编译器为您完成这些工作几乎总是比较容易。



由于@ Telgin已经注意到,模块也是增量编译的一个辅助。


I work with FORTRAN a lot, but I never had formal instruction in the proper way to write source code. I currently use modules to store global variables, but I understand you could also use them to store subroutines and functions. The codes I work with have many subroutines, as they are very large and complex. Should all functions and subroutines be in modules? If so, why?

解决方案

In general the answer to your first question is Yes and I'll come to an answer to your second question in a moment. Note first that this is a general answer to a general question and the bright sparks who hang around SO Fortran questions may well come up with special circumstances in which modules are inapplicable. I retort, in advance, that this answer is aimed at a newcomer to modules. Once you are no longer a newcomer you can formulate your own answer to your questions.

Modules are most useful to the programmer as an aid to organising and structuring a program or suite of programs. They provide a mechanism for encapsulating the definitions of user-defined types and functions/subroutines which operate on those types. In Fortran 90 and 95 this encapsulation was somewhat ad-hoc in the sense that it relied on the programmer's ideas about how to decompose a program into parts. With the introduction of the object-oriented facilities in Fortran 2003 there are now even clearer 'rules' for identifying what elements belong in each module.

You could, for example, conceive of a module for types and procedures for rational arithmetic. By keeping all the code which implements your great ideas in one module you can hide the implementation from other parts of your program (which do not need to know the details) and expose only those parts you wish to expose (look at the PRIVATE and PUBLIC keywords). You can, right away, see another advantage to organising your code into modules; it's much easier to USE your rational arithmetic module in a new program than it is to cut and past the code from your mega-source file into another mega-source file. When you want to work on your rational arithmetic, you work on code in one module, not in code spread all around your files.

Modules also allow you to manage name clashes. For example, your rational arithmetic module might define an operation called add, and you might also have a multiple-precision integer arithmetic module which defines an operation called add. If you attempt to USE both these modules in a program (or another module) then compiler will warn (possibly raise an error) that the same name is defined twice within the scope that uses the modules. You can use renaming when you use associate module entities. You can also use an ONLY clause to import only those module entities that the user needs.

Note that module USE is transitive, if A uses B and B uses C you don't have to also declare that A uses C (though if you've renamed entities or specified ONLY clauses you'll have to make sure what is transitive in a particular case).

In a nutshell, modules are the principal Fortran mechanism for dealing with complexity in programs by breaking them into manageable chunks. Fortran 2008, when the feature is implemented by compilers, introduces SUBMODULEs too, which promise even better support for dealing with complexity in this way.

Modules are also useful in that the language standards require that compilers generate explicit interfaces to procedures defined in modules for type-checking against the arguments at compile time. Note that these interfaces (which you never really see) are called explicit to contrast with implicit interfaces which is what procedures which are not defined inside modules (or CONTAINed within a program unit which uses them) have. You can, of course, write explicit interfaces for such procedures, but it's almost always easier in the short and long runs to let the compiler do it for you.

As @Telgin has already noted, modules are an aid to incremental compilation too.

这篇关于在Fortran中正确使用模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆