2

如果这是一个微不足道的问题,我很抱歉。我的fortran-fu很差。

Fortran 有没有办法传递数组长度?使用common(从我收集到的内容等同于global)也是一种选择。我想要的是在主程序中调用带有数组的函数。例如(这是输入的,不是从任何地方复制粘贴的)

program prog
integer num
double precision x(num),v
double precision test

....
v=test(x,num)
....


function test(x,num)
double precision test
integer num
double precision x(num)
test=0.0d0
....
return
end

这不会编译,因为num它不是一个常数。重要的是要知道我传递的数组大小是多少。

编辑:我正在使用 GNU Fortran 95 编译器。

Edit2:我没有运气就尝试了高性能标记的解决方案:

  program prog
  integer v
  parameter (v=10)
  double precision x(v),test,k
  k=test(x)
  write (*,*) size(x)
  stop
  end

  function test(x)
  double precision, dimension(:),intent(in) :: x
  double precision test
  write (*,*) size(x)
  test = 0.0d0
  return
  end
  

输出应该是写入 10 的两行。相反,我得到了这个:

/scpc:niels: #$ f95 err.f
/scpc:niels: #$ ./a.out 
           0
          10
/scpc:niels: #$ 
4

3 回答 3

11

Fortran 数组“知道”它们有多长,您不需要将数组及其长度作为不同的参数传递。(除非,也就是说,你正在与旧的 Fortran 代码交互。)今天你会写这样的东西

function test(arr)
    real, dimension(:), intent(in) :: arr
    ...
    integer :: arrsize
    ...
    arrsize = size(arr)
    ...

如果您必须与传递数组大小的旧代码接口,您可以进行这样的调用

  call old_fortran_subr(array, size(array, 1), other_arguments)

common哦,当我在写作时,与你从头开始编写的任何代码无关,这是 70 年代及更早的(正确)弃用的功能。而是使用模块变量

于 2013-02-07T12:07:39.670 回答
2

好的,这里发生了很多事情,尤其是您使用的 Fortran 风格有点过时。让我们一步一步来...

首先确保你总是使用隐式无

其次,如果您先验地知道数组的大小,则可以使用符号常量来表示其大小。您可以通过参数执行此操作:

Program prog

  Implicit None ! ALWAYS USE THIS

  Integer, Parameter :: num = 36

  Double Precision x( num )
  Double Precision test
  Double Precision v

  Call Random_number( x )

  v = test( x, num )

  Write( *, * ) v

End Program prog

Function test( x, num )

  Implicit None ! ALWAYS USE THIS

  Double Precision test

  Integer num
  Double Precision x( num )

  Integer i

  test = 0.0d0
  Do i = 1, num
     test = test + x( i ) * x( i )
  End Do

End Function test
[luser@cromer stackoverflow]$ gfortran -O -std=f95 -Wall -Wextra -pedantic func.f90
[luser@cromer stackoverflow]$ ./a.out
   12.129812171430215     

注意 num 是如何设置为 36 的,但是参数位意味着我不能改变它的值——它是一个常数,因此可以用来设置数组的大小。

这就是直到 1990 年的情况。然后,语言中出现了许多改变答案的东西。与您的问题最直接相关的是可分配数组,它允许您在运行时指定数组的大小,以及假定的形状数组,这使得将数组传递给子程序更简单。然而,还有很多其他的东西出现了,我建议你看一本书来了解它们——新语言比旧语言更具表现力和安全性。作为一个例子,我现在会把上面的内容写成类似

[luser@cromer stackoverflow]$ cat func.f90

Module numbers_module

  Integer, Parameter :: wp = Selected_real_kind( 12, 70 )

End Module numbers_module

    Module funcs_module

      Use numbers_module

      Implicit None

      Public :: test

      Private

    Contains

      Function test( x ) Result( sum_sq )

        Implicit None ! ALWAYS USE THIS

        Real( wp ) :: sum_sq

        Real( wp ), Dimension( : ), Intent( In ) :: x

        sum_sq = Sum( x * x )

      End Function test

    End Module funcs_module

    Program prog

      Use numbers_module
      Use funcs_module

      Implicit None ! ALWAYS USE THIS

      Real( wp ), Dimension( : ), Allocatable :: x 

      Real( wp ) :: v

      Integer :: num

      Write( *, * ) 'How many elements ?'
      Read ( *, * ) num
      Allocate( x( 1:num ) )

      Call Random_number( x )

      v = test( x )

      Write( *, * ) v

    End Program prog

    [luser@cromer stackoverflow]$ gfortran -O -std=f95 -Wall -Wextra -pedantic func.f90
    [luser@cromer stackoverflow]$ ./a.out
     How many elements ?
    39
       14.151818513394156  

如果您决定采用这种方式,请确保您了解为什么要使用此方法,测试的接口需要在调用点的范围内 - 并且要做到这一点,请阅读一本书。

哦。常见的。拒绝吧。

于 2013-02-07T13:42:37.440 回答
-1

Fortran 的早期版本中使用了隐式变量声明。通过这种方法,可以简单地使用变量而不显式声明它。诸如 IMPLICIT REAL(AH, OZ ) 之类的语句将声明所有以字母 AH 和 OZ 开头的实变量。这现在被认为过于松散,并且更强大的语言 C 所要求的显式类型声明是首选。我的第一语言是 FORTRAN IV,但我学的第二语言是 QBasic,它和 C 一样要求在使用前明确声明所有变量。

于 2019-09-14T16:00:35.460 回答