Fortran命令行启动怎么往主程序输入参数


Fortran中主程序如何输入参数?

主要使用下面的三个函数实现:

第一个:
 
COMMAND_ARGUMENT_COUNT — Get number of command line arguments
 
Description:
COMMAND_ARGUMENT_COUNT returns the number of arguments passed on the command line when the containing program was invoked. 
Standard:
Fortran 2003 and later 
Class:
Inquiry function 
Syntax:
RESULT = COMMAND_ARGUMENT_COUNT() 
Arguments:
None 
 
Return value:
The return value is an INTEGER of default kind. 
Example:
          program test_command_argument_count
              integer :: count
              count = command_argument_count()
              print *, count
          end program test_command_argument_count
           
 
COMMAND_ARGUMENT_COUNT — Get number of command line arguments
 
Description:
COMMAND_ARGUMENT_COUNT returns the number of arguments passed on the command line when the containing program was invoked.
Standard:
Fortran 2003 and later
Class:
Inquiry function
Syntax:
RESULT = COMMAND_ARGUMENT_COUNT()
Arguments:
None
 
Return value:
The return value is an INTEGER of default kind.
Example:
          program test_command_argument_count
              integer :: count
              count = command_argument_count()
              print *, count
          end program test_command_argument_count
 


第二个:
 
GET_COMMAND_ARGUMENT — Get command line arguments
 
Description:
Retrieve the NUMBER-th argument that was passed on the command line when the containing program was invoked. 
Standard:
Fortran 2003 and later 
Class:
Subroutine 
Syntax:
CALL GET_COMMAND_ARGUMENT(NUMBER [, VALUE, LENGTH, STATUS]) 
Arguments:
NUMBER  Shall be a scalar of type INTEGER and of default kind, NUMBER \geq 0 
VALUE   (Optional) Shall be a scalar of type CHARACTER and of default kind. 
LENGTH  (Optional) Shall be a scalar of type INTEGER and of default kind. 
STATUS  (Optional) Shall be a scalar of type INTEGER and of default kind. 
 
Return value:
After GET_COMMAND_ARGUMENT returns, the VALUE argument holds the NUMBER-th command line argument. If VALUE can not hold the argument, it is truncated to fit the length of VALUE. If there are less than NUMBER arguments specified at the command line, VALUE will be filled with blanks. If NUMBER = 0, VALUE is set to the name of the program (on systems that support this feature). The LENGTH argument contains the length of the NUMBER-th command line argument. If the argument retrieval fails, STATUS is a positive number; if VALUE contains a truncated command line argument, STATUS is -1; and otherwise the STATUS is zero. 
Example:
          PROGRAM test_get_command_argument
            INTEGER :: i
            CHARACTER(len=32) :: arg
           
            i = 0
            DO
              CALL get_command_argument(i, arg)
              IF (LEN_TRIM(arg) == 0) EXIT
           
              WRITE (*,*) TRIM(arg)
              i = i+1
            END DO
          END PROGRAM
 
GET_COMMAND_ARGUMENT — Get command line arguments
 
Description:
Retrieve the NUMBER-th argument that was passed on the command line when the containing program was invoked.
Standard:
Fortran 2003 and later
Class:
Subroutine
Syntax:
CALL GET_COMMAND_ARGUMENT(NUMBER [, VALUE, LENGTH, STATUS])
Arguments:
NUMBER Shall be a scalar of type INTEGER and of default kind, NUMBER \geq 0
VALUE (Optional) Shall be a scalar of type CHARACTER and of default kind.
LENGTH (Optional) Shall be a scalar of type INTEGER and of default kind.
STATUS (Optional) Shall be a scalar of type INTEGER and of default kind.
 
Return value:
After GET_COMMAND_ARGUMENT returns, the VALUE argument holds the NUMBER-th command line argument. If VALUE can not hold the argument, it is truncated to fit the length of VALUE. If there are less than NUMBER arguments specified at the command line, VALUE will be filled with blanks. If NUMBER = 0, VALUE is set to the name of the program (on systems that support this feature). The LENGTH argument contains the length of the NUMBER-th command line argument. If the argument retrieval fails, STATUS is a positive number; if VALUE contains a truncated command line argument, STATUS is -1; and otherwise the STATUS is zero.
Example:
          PROGRAM test_get_command_argument
            INTEGER :: i
            CHARACTER(len=32) :: arg
         
            i = 0
            DO
              CALL get_command_argument(i, arg)
              IF (LEN_TRIM(arg) == 0) EXIT
         
              WRITE (*,*) TRIM(arg)
              i = i+1
            END DO
          END PROGRAM
第三个:

GET_COMMAND — Get the entire command line
 
Description:
Retrieve the entire command line that was used to invoke the program. 
Standard:
Fortran 2003 and later 
Class:
Subroutine 
Syntax:
CALL GET_COMMAND([COMMAND, LENGTH, STATUS]) 
Arguments:
COMMAND (Optional) shall be of type CHARACTER and of default kind. 
LENGTH  (Optional) Shall be of type INTEGER and of default kind. 
STATUS  (Optional) Shall be of type INTEGER and of default kind. 
 
Return value:
If COMMAND is present, stores the entire command line that was used to invoke the program in COMMAND. If LENGTH is present, it is assigned the length of the command line. If STATUS is present, it is assigned 0 upon success of the command, -1 if COMMAND is too short to store the command line, or a positive value in case of an error. 
Example:
          PROGRAM test_get_command
            CHARACTER(len=255) :: cmd
            CALL get_command(cmd)
            WRITE (*,*) TRIM(cmd)
          END PROGRAM
 
GET_COMMAND — Get the entire command line
 
Description:
Retrieve the entire command line that was used to invoke the program.
Standard:
Fortran 2003 and later
Class:
Subroutine
Syntax:
CALL GET_COMMAND([COMMAND, LENGTH, STATUS])
Arguments:
COMMAND (Optional) shall be of type CHARACTER and of default kind.
LENGTH (Optional) Shall be of type INTEGER and of default kind.
STATUS (Optional) Shall be of type INTEGER and of default kind.
 
Return value:
If COMMAND is present, stores the entire command line that was used to invoke the program in COMMAND. If LENGTH is present, it is assigned the length of the command line. If STATUS is present, it is assigned 0 upon success of the command, -1 if COMMAND is too short to store the command line, or a positive value in case of an error.
Example:
          PROGRAM test_get_command
            CHARACTER(len=255) :: cmd
            CALL get_command(cmd)
            WRITE (*,*) TRIM(cmd)
          END PROGRAM


 

最近在Fortran的数据传递设计上碰到了问题。现在略归纳下子程序间参数传递的实现办法。
首先,Fortran subroutine 独立地拥有属于自己的变量申明。有说:Fortran的变量作用域只有两类:一是全局作用域,二是子程序作用域,并且子程序内部不存在嵌套作用域。最后一点很重要哟。举例:在一个子程序里申明的变量,不能在与之并列的另外一个子程序里面使用。即两个子程序不能有变量重叠。即使在这个两个子程序里都使用了同名的某个变量,本质上讲,在这两个子程序里的同名变量也是没任何联系的。
那么,如果需要在子程序之间传递变量(参数),怎么办呢?还要细说一点:传参的结构有两类:第一类,诸如主程序-子程序、外层子程序-内层子程序(子程序嵌套)之间的参数传递,另外一类,就是并列的两个子程序(即它们之间不需要有关系,仅仅由于需求相同的变量)之间的参数传递。
第一类传参结构的实现常见传址调用。
第二类传参结构的实现常见申明公共内存块,将需求的相同变量申明成全局变量,那么各个子程序自然都可以用了。注意,仍然是地址,所以子程序可以修改这些全局变量的。
其中,FORTRAN77的公共块(全局变量申明)使用COMMON;FORTRAN90以后使用MODULE来包装公共块。

来看几个问题:
一、以数组A中满足某一条件的元素的编号构成新的数组B
    do  bi=1,bn
        do ai=1,an
           if(A(ai).eq.a0) then
           B(bi)=ai
   endif
        enddo
    enddo

二、以数组A的元素为编号,取数组B的元素进行其他运算
   do bi=1,bn
       do ai=1,an
           if (bi.eq.A(ai)) then
               fun(i)=fun(i)+fun2(bi)
           endif
       enddo
  enddo

补充总结:
fortran 中循环变量只读不可以当左值进行值修改。
我觉得 共享变量内存(采用module)比函数传参的优势:首先,没有形参的开销,这也是更重要的一个原因:不用列参数list了,一个()就解决调用。
复杂的FORTRAN程序一般会有很多层(变量)作用域的嵌套。最外层的变量自然可以在内层使用,但内层变量作用域不超过本层。对于每个当前层中申明的变量,相当于该层(子程序)的局部变量;任何包括该层(子程序)的外层(子程序)中定义的变量,都可理解为该层的“全局变量”。那么,对于这些“全局变量”,特别是当内层(子程序)会修改它们的值的时候,就合适使用Module声明共享内存的变量。如果嵌套的层数较多,使用Module会更清晰些。
复杂的FORTRAN程序,不仅有上述的深度嵌套,还有广度问题。比如:同一个子程序a,要被另外几个不同的子程序b, c, d...调用。sub_b, sub_c, sub_d之间的设计就是一个广度问题,重点在于它们包含了相同的方法(实现),即sub_a。采用面向过程的语言,写出sub_a, b, c, d, 然后传参调用即可。正如前述,这样就涉及函数传参,比较讨厌,而且不适合面向对象。但是采用面向对象,使用Module封装B, C, D呢,似乎每个module里面都必须重写一段sub_a这个方法,感觉又很啰嗦。 可惜一个方法,如何在三个对象里面重载啊。看来面向对象了,就必须有重写代码的麻烦。


 

Fortran程序可以通过以下两种方式接受接受命令行参数。

  1. GET_COMMAND_ARGUMENT
  2. 用法:CALL GET_COMMAND_ARGUMENT(NUMBER [, VALUE, LENGTH, STATUS])其中NUMBER是获取第几个参数,VALUE是相应的值(让NUMBER=0得到的是可执行程序的名字,如果输入参数个数比NUMBER小,得到的为空。);LEBGTH是第NUMBER个参数的长度;STATUS是获取这个参数后的状态(如果取这个参数发生错误,返回的是正数;如果VALUE是一个截断的参数,那么返回-1;其它情况返回0)。下面是一个示例程序,该程序将命令行参数逐个输出。

    PROGRAM test_get_command_argument
    INTEGER :: i,n
    CHARACTER(len=128) :: arg
    i = 0
    DO
    CALL get_command_argument(i, arg)
    IF (LEN_TRIM(arg) == 0) EXIT
    WRITE (*,*) i,arg
    i = i+1
    END DO
    END PROGRAM

    注:Windows平台下gfortran(GNU Fortran (GCC) 4.5.0)编译通过,运行正常。

  3. getarg与iargc
  4. getarg用法:call getarg(NUMBER,VALUE)其中NUMBER是获取第几个参数,VALUE是相应的值。iargc用法:n=iargc(),返回命令行中参数的数量。下面的是一个示例程序,该程序也是将命令行参数逐个输出。

    PROGRAM test_get_command_argument
    INTEGER :: i,n
    CHARACTER(len=128) :: arg
    n = iargc()
    DO i=0,n
    CALL getarg(i, arg)
    WRITE (*,*) i,arg
    END DO
    END PROGRAM

    注:Windows平台gfortran(GNU Fortran (GCC) 4.5.0)与Compaq Visual Fortran 6编译正常,运行正常。

  5.