简体   繁体   English

通过命令行参数设置数组大小

[英]Setting array size from command line arguments

I know that in Fortran I can declare an array of a number N of elements if N is declared as a parameter before (and so defined to some value). 我知道在Fortran中,如果之前将N声明为parameter (并因此定义为某个值),则可以声明一个由N个元素组成的数组。

On the other hand I know I can get a program to accept arguments from the command line with the use of the subroutine get_command_arg . 另一方面,我知道我可以使用子例程get_command_arg从命令行接受程序接受参数。

My question is: 我的问题是:

Can I somehow declare an array of a number of elements given by a command when calling the program from the command line? 从命令行调用程序时,能否以某种方式声明由命令给定的多个元素组成的数组?

I'm looking for something like the command line: 我正在寻找类似命令行的内容:

./main -30 

where main.f03 would begin with something like: 其中main.f03将以类似以下内容的开头:

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

I'm trying not to define the arrays as allocatable. 我试图不将数组定义为可分配的。

There are certain languages where you can initialize variables and named constants from command line (like chapel), but Fortran is not one of them. 在某些语言中,您可以从命令行初始化变量和命名常量(例如chapel),但是Fortran并不是其中一种。

You say "I am trying not to define the arrays as allocatable." 您说: “我试图不将数组定义为可分配的。” but that is the problem. 但这就是问题所在。 You simply have to. 您只需要。 There is no other way. 没有别的办法了。

Your code 您的密码

integer, parameter :: N = get_command_arg(1)

real :: x(N) ...

is illegal for several reasons. 有几个原因是非法的。

You cannot put GET_COMMAND_ARGUMENT() into a constant expression because it is not among allowed functions. 您不能将GET_COMMAND_ARGUMENT()放入常量表达式中,因为它不在允许的函数中。 It does not return compile-time constant values. 它不返回编译时常量值。 And parameter initializers must be set at the compile time. 并且必须在编译时设置parameter初始化程序。

GET_COMMAND_ARGUMENT() is a subroutine, not a function. GET_COMMAND_ARGUMENT()是子例程,而不是函数。 It can return more stuff, not just the value, but also the length and status. 它可以返回更多的东西,不仅返回值,还返回长度和状态。 It is not pure and the Fortran standard is trying to use only pure functions. 它不是纯函数,并且Fortran标准正在尝试仅使用纯函数。 Other things, like RANDOM_NUMBER() , are subroutines. 诸如RANDOM_NUMBER()类的其他东西是子例程。 It is a good style to follow in your own programs too. 遵循自己的程序也是一种很好的风格。

The only way in Fortran to create arrays that change from run to run is to make the array allocatable or pointer . 在Fortran中创建每次运行都会更改的数组的唯一方法是使数组allocatablepointer There are also automatic arrays for local arrays. 也有用于本地阵列的自动阵列。

You can do it this way without allocatables. 您可以通过这种方式进行分配。 You just have to pass the size (after converting it to an integer) into a subroutine. 您只需将大小(将其转换为整数后)传递给子例程。 But really, I see no reason not to use allocatables for something like this. 但实际上,我没有理由不对此类内容使用可分配的数据。

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

Example use: 使用示例:

> ./main 1
       1
> ./main 2
       1           1
> ./main 3
       1           1           1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM