Fortran可选参数

时间:2014-12-27 12:11:42

标签: fortran

我正在编写一个编写字符串的例程。我需要吗? 检查哪些参数存在,或者我能避免吗?

Subroutine writes  & 
(                  &
 q1, q2, q3, q4    & 
)

Character (len=*), Intent(in) :: q1
Character (len=*), Intent(in), Optional :: q2, q3, q4

Character (len=65) :: s, fmt

fmt = "(x,4(a,x))"
Write (s,fmt) Trim (q1), Trim (q2), Trim (q3), Trim (q4)
Write (*,*) Trim (s)

End Subroutine writes

1 个答案:

答案 0 :(得分:4)

Fortran 2008 12.5.2.12中明确给出了有关使用可选伪参数的规则。如果在问题中给出的writes调用中存在所有参数,则代码有效且输出将按预期进行。但是,我们无法保证这一点,任何不存在的参数都会使代码无效。

特别是,传递q2,例如,TRIM不存在({1}}(不会选择参数)将是错误的。

有多种方法可以解决这个问题,但它们都涉及检查存在。您可以按照Fortran Fallback code for optional string argument中的参数进行操作,但以下是评论中给出的替代方法。

可以创建TRIM的替代方法,它取一个可选参数,如果参数不存在则返回零长度字符变量,如果是,则返回预期的修剪变量:

  subroutine writes(q1, q2, q3, q4)
    character(*), intent(in) :: q1, q2, q3, q4
    optional q2, q3, q4
    character(len=65) s

    write(s, '(4(a,:,x))') TRIM(q1), MY_TRIM(q2), MY_TRIM(q3), MY_TRIM(q4)
    print*, TRIM(s)

  contains
    function my_trim(str)
      character(*), intent(in), optional :: str
      character(:), allocatable :: my_trim

      if (PRESENT(str)) then
        my_trim = TRIM(str)
      else
        my_trim = ''
      end if

    end function

  end subroutine

注意,这会为结果使用延迟长度字符变量,以及自动分配(如果使用ifort,请记住必要的编译器标志以正确编译)。

最后,如果您想确保在两个非现有变量(''//' '//'')之间不打印空格,则需要额外的工作。但是,评论表明这不是必要的。