【问题标题】:Passing array data to sub-programs with common blocks将数组数据传递给具有公共块的子程序
【发布时间】:2014-01-25 10:20:34
【问题描述】:

关于将数组传递给函数和/或子例程,我有点头疼。我的代码或多或少如下所示。

program test
implicit none

integer arraySize
parameter (arraySize = 10)

integer myFunction

integer someValue
integer array1(arraySize,arraySize)
...


...
someValue = myFunction(arraySize,array1)
...

end


integer function myFunction(arraySize,array1)
implicit none

integer arraySize
integer array1(arraySize,arraySize)

...

end

我可以编译这种类型的子程序,并对数组中的值进行相关的数学运算。这是通过几个 4 维数组完成的,所有这些数组都以上述相同类型的方式定义。

但是,我有一个子程序,我想传递其中的 5 个数组,并对这些值做一些数学运算。我想我会尝试使用通用语句来简化子例程语句,而不是将每个数组作为参数。所以我有以下内容:

program test2
implicit none

integer arraySize
parameter (arraySize = 10)

integer array1(arraySize,arraySize)
integer array2(arraySize,arraySize)
integer array3(arraySize,arraySize)
common /myArrays/ array1, array2, array3

...
call arraySum(arraySize)
...

end


subroutine arraySum(arraySize)
implicit none

integer arraySize

integer array1(arraySize,arraySize)
integer array2(arraySize,arraySize)
integer array3(arraySize,arraySize)
common /myArrays/ array1,array2,array3

...

end

我尝试编译,我得到这个错误

integer array1(arraySize,arraySize)
              1
Error: Variable 'arraysize' at (1) in this context must be constant

出于多种原因,我感到困惑。我是否误解了如何使用常用语句?当然,如果我可以像在第一个示例中那样将数组的大小传递给子程序,那么为什么这种方法会有所不同呢?还是我需要在子例程中重新定义另一个整数并使其成为等于arraySize 值的常数?或者它只是 F77 的一个怪癖,我应该咬紧牙关在子程序参数中传递所有 3 个数组?

我为代码的陈旧风格道歉,如果我对 Fortran 编程的原则有任何误解(我之前唯一的经验是使用 C 和 C++)。我想使用比 F77 更新的东西,但目前不是一个选项(学生)。

【问题讨论】:

    标签: arrays function fortran subroutine fortran77


    【解决方案1】:

    答案的总结是,当且仅当数组是子程序中的虚拟参数时,才能传递数组的大小。

    来自standard

    每个数组声明符要么是一个实际的数组声明符,要么是一个伪数组声明符。

    5.1.2.1 实际数组声明器。
    实际的数组声明符是一个数组声明符,其中数组名称不是虚拟参数。每个实际的数组声明符必须是一个常量数组声明符。 [..] COMMON 语句中允许使用实际的数组声明符

    5.1.2.2 虚拟数组声明器。
    虚拟数组声明符是一个数组声明符,其中数组名称是一个虚拟参数。一个虚拟数组声明符可能是 [..] 一个可调整的数组声明符 [..]。伪数组声明符只能出现在函数或子程序子程序中。

    如果你想在一个公共块中传递数组,那么你需要将边界作为一个整数常量表达式。正如您所说,您可以在子程序中再次定义数组大小。使用源预处理器可能是帮助保持一致性的一种方法。或者,正如@george 建议的那样,使用标准友好的include 语句(只要确保您使用的是构建系统)。

    也就是说,我建议最好将数组作为参数传递:当您想要使用“动态”数组方法时,事情会变得非常棘手,而不必担心存储关联。

    【讨论】:

    • 啊,很公平,我想这就是我所担心的。我没有在这里使用预处理器的选项,所以我将它们作为参数(使用大量的cmets!)。非常感谢!
    • 另一种保持重复静态声明一致的方法是将声明放在一个文件中,并将include 放在需要的文件中(丑陋,但确实有效)
    猜你喜欢
    • 2019-11-01
    • 2015-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-17
    • 2015-01-09
    • 2017-03-21
    • 2021-05-23
    相关资源
    最近更新 更多