2017-11-24 7 views
1

Fortranでは、Nが前に定数として宣言されていて(ある値に定義されている場合)、N個の要素の配列を宣言できます。配列のサイズをコマンドライン引数から設定する

一方、サブルーチンget_command_argを使用してコマンドラインから引数を受け入れるプログラムを入手できることはわかっています。

私の質問は:

私は何とか、コマンドラインからプログラムを呼び出すときに、コマンドによって与えられた要素数の配列を宣言することはできますか?

私は、コマンドラインのようなものを探しています:

integer, parameter :: N = get_command_arg(1) 
real :: x(N) ... 

私が割り当て可能として配列を定義していないしようとしている:main.f03のようなもので始まります

main -30 

+0

が答えです割り当て。何故なの? – agentp

+0

割り当て可能な配列を使用し、コマンドラインからSIZEを読み取り、INTEGERに変換して配列を割り当てます。 –

答えて

2

変数や名前付き定数をコマンドライン(チャペルなど)から初期化できる特定の言語がありますが、Fortranはその1つではありません。

あなたはと言っています。「配列を割り当て可能と定義しないようにしようとしています。しかしそれが問題です。あなたは単にする必要があります。他の方法はありません。

あなたのコード

integer, parameter :: N = get_command_arg(1) 

real :: x(N) ... 

はいくつかの理由で違法です。

GET_COMMAND_ARGUMENT()は、許可されている関数ではないため、定数式に入れることはできません。コンパイル時の定数値は返されません。コンパイル時にparameterイニシャライザを設定する必要があります。

GET_COMMAND_ARGUMENT()は関数ではなくサブルーチンです。それは価値だけでなく、長さとステータスをより多くのものを返すことができます。これは純粋ではなく、Fortran標準は純粋な関数のみを使用しようとしています。 RANDOM_NUMBER()のようなものは、サブルーチンです。あなた自身のプログラムに従うのも良いスタイルです。

実行時に変更される配列を作成する唯一の方法は、アレイをallocatableまたはpointerにすることです。ローカル配列用の自動配列もあります。

1

この方法では、割り当て可能ファイルなしで行うことができます。サイズを(整数に変換して)サブルーチンに渡すだけで済みます。しかし、本当に、私はこのようなもののために割り当て可能物を使わない理由はないと思う。

program main 

implicit none 

integer :: n,arg_len,istat 
character(len=100) :: arg 

call get_command_argument(1,value=arg,status=istat) 
if (istat/=0) error stop 'error: cannot read first arg' 

read(arg,'(I100)',iostat=istat) n 
if (istat/=0) error stop 'error: first arg not an integer' 

call real_main(n) 

contains 

    subroutine real_main(n) 
    integer,intent(in) :: n 
    integer,dimension(n) :: ival 
    ival = 1 
    write(*,*) ival 
    end subroutine real_main 

end program main 

使用例:

> ./main 1 
     1 
> ./main 2 
     1   1 
> ./main 3 
     1   1   1 
+0

私は*自動アレイについて言及しました。理由は簡単です。まず、配列をサブルーチンより長くするようにしますが、 'real_main'からすべてを呼び出すことができます。まだ私には醜い。第二に、多くのコンパイラでスタックサイズに関する問題を避けるためです。特別なフラグを使用して、ヒープ上に自動配列を配置する必要があります。割り当て可能なものははるかに優れており、はるかに自然であり、プログラムの拡張が容易になります。 –

関連する問題