我知道在Fortran中我可以声明一个N个元素的数组,如果N之前被声明为parameter
(并且被定义为某个值)。
另一方面,我知道我可以通过使用子例程get_command_arg
来获取程序来接受来自命令行的参数。
我的问题是:
从命令行调用程序时,我可以以某种方式声明由命令给出的多个元素的数组吗?
我正在寻找命令行之类的东西:
./main -30
其中main.f03
的开头是:
integer, parameter :: N = get_command_arg(1)
real :: x(N) ...
我试图不将数组定义为可分配的。
答案 0 :(得分:3)
在某些语言中,您可以从命令行初始化变量和命名常量(如chapel),但Fortran不是其中之一。
你说“我试图不将数组定义为可分配的。”但这就是问题所在。你只需要。没有其他办法。
您的代码
integer, parameter :: N = get_command_arg(1)
real :: x(N) ...
由于多种原因,是非法的。
您不能将GET_COMMAND_ARGUMENT()
放入常量表达式中,因为它不在允许的函数中。它不返回编译时常量值。并且必须在编译时设置parameter
初始值设定项。
GET_COMMAND_ARGUMENT()
是一个子程序,而不是一个函数。它可以返回更多的东西,不仅仅是值,还有长度和状态。它不纯粹,Fortran标准试图只使用纯函数。其他内容,如RANDOM_NUMBER()
,是子程序。在你自己的课程中也是一种很好的风格。
Fortran中创建从一次运行更改为运行的数组的唯一方法是创建数组allocatable
或pointer
。本地数组也有自动数组。
答案 1 :(得分:1)
你可以这样做,没有allocatables。您只需将大小(在将其转换为整数后)传递到子例程中。但实际上,我认为没有理由不将allocatables用于这样的事情。
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