0

次のように配列を初期化しようとしています。

program test
  n = 3
  call it(n)

contains

subroutine it(n)
  integer n,j
  integer, dimension(3*(n-1)) :: a=(/(j,j=4,3*n,1)/)
  write(*,*) a
end subroutine it

end program test

でコンパイルするとgfortran -o test.exe test.f、次のエラーが表示されます。

test.f:9.43:

        integer, dimension(3*(n-1)) :: a=(/(j,j=4,3*n,1)/)
                                           1
Error: Invalid character in name at (1)

何が問題ですか?私の知る限り、これは標準準拠のコードです。

4

2 に答える 2

5

コンパイラ エラーは紛らわしいかもしれませんが、サンプル コードは標準に準拠していません。

型宣言ステートメントの初期化子は、定数式でなければなりません。また、自動データ オブジェクトには SAVE 属性がない場合があります。

初期化 (修飾形容詞なし) は、Fortran では、プログラムの実行が開始される前に 1 回だけ行われます。したがって、初期化子で使用される式は、プログラムの実行が開始される前に評価できるものでなければなりません (そのような式で許可される内容の詳細 (および用語の側面) は、記述している Fortran 標準によって異なります)。

コード例の初期化子は、仮引数である n の値に依存します。プログラムが実行を開始する前に、仮引数の値を参照することはできません。これは本質的に定数ではありません。

同様に、ローカル変数の属性 (その形状) はa、仮引数の値に依存します。これにより、変数aが自動データ オブジェクトになります。自動データ オブジェクトに SAVE 属性を指定することはできません (オブジェクトの属性は呼び出しごとに異なる可能性があり、呼び出しごとに値を維持する SAVE とは矛盾します)。初期化子を指定すると、SAVE 属性も暗黙指定されます。

n仮引数ではなくパラメータである場合、コードは適合します。

于 2013-03-08T01:35:47.840 に答える
2

すでに IanH によって説明されているように、許可されているものの 2 つの例を次に示します。1 つのケースでは、イニシャライザはMパラメータであるため、定数式です。もう 1 つの例では、初期化は定数式ではありませんが、宣言の一部ではありません。

program test5
  integer :: j
  integer :: n = 3
  integer, parameter :: M = 4
  integer, dimension(3*(M-1)) :: b = [ (j,j=4,3*M,1) ]

  write (*,*) b
  call it(n)

contains

subroutine it(n)
  integer n,j
  integer, dimension(3*(n-1)) :: a
  a = [ (j,j=4,3*n,1) ]
  write(*,*) a
end subroutine it

end program test5
于 2013-03-08T01:41:16.047 に答える