包含声明 [英] Contains statement

查看:189
本文介绍了包含声明的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我并不了解 CONTAINS 声明在fortran 90中的重要性

例如

  PROGRAM BLABLA 

隐式无

INTEGER :: i,j,k

i = 1; j = 1; k = 1

PRINT *,i,j,k

呼叫ABC(i,j,k)

打印* ,i,j,k

CONTAINS

子程序ABC(r,s,t)

隐式无

INTEGER,INTENT(IN):: r,s
INTEGER,INTENT(OUT):: t

t = r + s

END SUBROUTINE ABC
结束程序BLABLA

以及通过在主程序外定义子程序。我理解函数,需要指定函数的类型,但对于子例程,它不是必需的。我有兴趣了解这样做是否有任何额外的警告?

 程序布拉布拉

隐式NONE

INTEGER :: i,j,k

i = 1; j = 1; k = 1

PRINT *,i,j,k

呼叫ABC(i,j,k)

打印* ,i,j,k

结束程序BLABLA

子程序ABC(r,s,t)

隐式无

INTEGER,INTENT(IN):: r,s
INTEGER,INTENT(OUT):: t

t = r + s

END SUBROUTINE ABC


解决方案

在第一个和第二个版本中, / p>

  CALL ABC(i,j,k)

  CALL ABC(i,j)

并且看看会发生什么,首先是在编译时,其次是在运行时。



<当你完成了这些工作并回报了你的发现后,我可以把它变成一个正确的答案。

好的,这里是答案,其中大部分是你我们已经知道:

过去,在Fortran 90之前,FORTRAN(当时所有人都喊出了这个名字)程序很常见在不同的'单位'中(现在仍然是)。在你的第二个版本中,程序和子程序是分开的单元并单独编译。编译器没有可用的信息来检查对子例程的调用是否与子例程签名相匹配 - 这是留给程序员检查的。不正确地调用子程序,几乎任何事情都可能发生 - 如果你幸运的话,程序崩溃或产生明显错误的结果,如果你不走运它会产生不明显错误但仍然错误的结果。 b
$ b

如果在程序单元的作用域中包含子程序的源代码,并使用 contains 部分,如第一个版本的程序,编译器会为子程序创建一个接口,并且可以检查对该子程序进行的任何调用在形式上是否正确。因此,你没有发现编译的问题。

另一种让编译器为子程序生成接口的方法,这些方法也可以用于函数,也就是将它们放入模块和在程序中使用模块。你会发现很多例子来说明如何在其他Q和As这里做到这一点。



将子程序放入模块并不完全等同于包含它在中包含部分。在包含部分中,子程序可以使用程序中声明的变量,而不通过子程序的参数列表。这是一个糟糕的编程习惯,但你确实在野外遇到了这个问题

I am not understanding the importance of CONTAINS statement in fortran 90

For example

PROGRAM BLABLA

IMPLICIT NONE

INTEGER :: i,j,k

i = 1; j = 1;k =1

PRINT *, i,j,k

CALL ABC(i,j,k)

PRINT *, i,j,k

CONTAINS

    SUBROUTINE ABC(r,s,t)

    IMPLICIT NONE

    INTEGER, INTENT(IN) :: r,s
    INTEGER, INTENT(OUT) :: t

    t = r + s

   END SUBROUTINE ABC
END PROGRAM BLABLA

and one by defining subroutines outside the main program. I understand for functions, one need to specify the type of the function, but for subroutines it is not required. I am interested in understanding whether there are any additional caveats in doing so?

PROGRAM BLABLA

IMPLICIT NONE

INTEGER :: i,j,k

i = 1; j = 1;k =1

PRINT *, i,j,k

CALL ABC(i,j,k)

PRINT *, i,j,k

END PROGRAM BLABLA

SUBROUTINE ABC(r,s,t)

IMPLICIT NONE

INTEGER, INTENT(IN) :: r,s
INTEGER, INTENT(OUT) :: t

t = r + s

END SUBROUTINE ABC

解决方案

In both your first and second versions try changing the line

CALL ABC(i,j,k)

to

CALL ABC(i,j)

and see what happens, firstly at compile time and secondly at run time.

When you have done that, and reported back on your findings, I can turn this into a proper answer.

OK, so here's the answer, most of which you've already figured out:

In the old days, before Fortran 90, it was common for FORTRAN (everyone shouted the name in those days) programs to be compiled in separate 'units' (it still is). In your second version the program and the subroutine are in separate units and are compiled separately. There is no information available to the compiler to check that the call to the subroutine matches the subroutine signature -- that is left to the programmer to check. Call the subroutine incorrectly and almost anything can happen -- if you're lucky the program crashes or produces obviously erroneous results, if you're unlucky it produces not-obviously-erroneous-but-still-erroneous results.

If you include the source code for the subroutine in the scope of the program unit, and use the contains section, as in your first version of your program, the compiler will create an interface for the subroutine and can check that any calls made to the subroutine are formally correct. Hence the failure to compile you discovered.

The other way to have the compiler generate the interface for subroutines, and these approaches work for functions too, is to put them into a module and use the module in the program. You'll find many examples of how to do this in other Qs and As here on SO.

Putting the subroutine into a module isn't exactly the same as including it in a contains section. In the contains section the subroutine can use variables declared in the program without their being passed through the subroutine's argument list. This is rather frowned upon as poor programming practice but you do come across it in the wild.

这篇关于包含声明的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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