Gra*_*dos 9 fortran module interface procedure subroutine
我对在模块中使用接口块以及使用CONTAINS语句为模块内部的过程创建"显式接口"感到困惑.
我通常使用模块内的接口块编写一个过程.例如,
MODULE ModExample
INTERFACE
SUBROUTINE Sumatory(a, b, c)
IMPLICIT NONE
INTEGER, INTENT(IN)::a
INTEGER, INTENT(OUT)::b
INTEGER, INTENT(OUT)::c
END SUBROUTINE Sumatory
END INTERFACE
END MODULE ModExample
SUBROUTINE Sumatory(a, b, c)
IMPLICIT NONE
INTEGER, INTENT(IN)::a
INTEGER, INTENT(OUT)::b
INTEGER, INTENT(OUT)::c
!Executable statements here
END SUBROUTINE Sumatory
Run Code Online (Sandbox Code Playgroud)
这对我有用.但它也可以使用模块内部的CONTAINS语言编写,实际上这就是我参考过的Fortran书籍中编写示例程序的方法.
MODULE ModExample
CONTAINS
SUBROUTINE Sumatory(a, b, c)
IMPLICIT NONE
INTEGER, INTENT(IN)::a
INTEGER, INTENT(OUT)::b
INTEGER, INTENT(OUT)::c
!Executable statements here
END SUBROUTINE Sumatory
END MODOULE ModExample
Run Code Online (Sandbox Code Playgroud)
那么INTERFCE块有什么问题呢?两者都是等效结构吗?我应该使用哪两种方法?也许所有这些问题都可以用一个很大的"它取决于"来回答,但我希望你能解释一下它们之间的差异.提前致谢.
Ian*_*anH 12
这取决于,但除非你有充分的理由相反,否则使用模块程序("在包含之后").
第一种方法"错误"的是你必须指定过程的接口两次 - 一次在接口块中,一次在过程定义中.在第二种情况下,接口仅指定一次 - 在过程定义中.维护多个规范的需要是潜在的错误来源.
阐述:
在第一个代码示例中,后一个SUBROUTINE和END SUBROUTINE语句之间的源(不在接口块内)是所谓的外部子程序.这是一个独立的程序单元.外部子程序定义了外部程序.
在第二个代码示例中,在模块中的CONTAINS语句之后出现的SUBROUTINE和END SUBROUTINE语句之间的源是一个模块子程序.它是模块程序单元的一部分.该模块子程序定义了一个模块程序.
("子程序"是指源代码构造,而过程是指源代码定义的东西.)
还存在内部子程序(它们出现在主机外部或模块子程序或主程序中的CONTAINS语句之后),它定义了内部过程,以及单独的模块子程序,这是定义模块过程的另一种方式.
Fortran程序单元(主程序,模块,子模块,外部子程序,块数据)使用单独编译的模型.在编译特定程序单元时,编译器就好像它对程序中的任何其他程序单元一无所知,相反在源中明确规范.
这样做的一个结果是,如果您在范围中引用外部过程而没有明确告诉编译器外部过程是什么样的,那么编译器必须从引用的方式隐式地推断外部过程的接口(该过程具有隐式接口).以这种方式引用的过程不能使用该语言的许多较新的参数传递特性(因为编译器不知道如何调用并正确地将参数传递给过程).实际编译器也不太可能识别错误,例如不匹配的参数类型.
接口块(例如第一代码示例中的接口块)可用于显式指定外部过程的接口.在可以访问显式接口的源代码中引用外部过程可以使用所有现代参数传递功能,并且可能会获得更好的编译器错误检测.但是,程序员仍然有责任确保接口主体的相关特性和实际的外部过程定义是一致的.
该语言还要求在作用域单元中只能访问过程的一个接口.在定义它的外部子程序内部,该过程的接口已经是显式的,因此程序员有责任确保在外部过程中无法访问同一外部过程的接口主体.
允许在程序单元之间共享信息的显式规范之一是USE语句,该语句使得在USE语句出现的范围内可用的模块定义的事物的知识.这包括有关模块定义或声明的过程的知识.
(该语言要求在使用模块之前模块的公共部分的源"可用",这实际上意味着在编译模块的USE语句之前必须已经编译了模块的源.)
与外部过程不同,模块过程或内部过程的接口在其标识符可访问的范围内始终是显式的 - 不需要为模块过程或内部设置接口主体(除了单独的模块子程序,您不能有界面体).
综上所述:
第一个例子 - 你有一个带有接口体的模块用于外部过程,然后是外部过程本身.您可以引用该外部过程而无需使用该模块,在这种情况下使用隐式接口(功能有限,容易出错).或者,如果模块在引用范围内使用,则接口将是显式的.在这种情况下,程序员必须确保接口主体和外部过程定义匹配,并且外部过程内的外部过程的接口主体不可访问.这容易出错并且维护麻烦.
第二个例子 - 你有一个具有模块程序的模块.如果不使用相关模块,则无法通过其名称引用模块过程.这种引用的接口将始终是显式的.无需为该过程维护单独的接口主体.
对于我们来说,第一种形式优于第二种形式的唯一理由是,您需要打破编译依赖循环或以其他方式限制长编译依赖关系链.
| 归档时间: |
|
| 查看次数: |
3723 次 |
| 最近记录: |