在Fortran-90中将参数作为参数传递?

时间:2015-09-13 19:06:39

标签: parameters fortran fortran90 intel-fortran select-case

假设我有一个子程序:

subroutine foo(x, Nx)
    implicit none
    integer, intent(IN) :: x
    integer, intent(IN) :: Nx

    select case(x)
        case (1)
            write(*,*) "Minimum value"
        case (Nx)
            write(*,*) "Maximum value"
        case default
            write(*,*) "Somewhere in-between"
    end select
end subroutine foo

假设我的驱动程序如下所示:

program main
    implicit none

    interface
        subroutine foo(x,Nx)
            integer, intent(IN)  :: x
            integer, intent(IN)  :: Nx
        end subroutine foo
    end interface

    integer, parameter :: Nx = 100
    integer :: x

    call foo(20, Nx)

end program main

上述程序无法编译,因为在子程序中,case (Nx)无效。具体来说,ifort 16给出以下错误:

  

错误#6601:在CASE语句中,case-value必须是常量表达式。

换句话说,即使Nx通过intent(IN) 有效地声明为子例程常量,它也需要是{{1}的文字常量或parameter }}。

有没有办法让case语句接受integer作为我们知道的常量参数?有没有办法宣布Nx是传入的Nx

我意识到在这个简单的简短例子中,if-then-elseif-else-end块就足够了,但后来我不知道这个问题的答案。 :-)

2 个答案:

答案 0 :(得分:5)

只需使用if语句即可。子程序参数(您调用参数)当然不是参数(命名常量)。 intent(in)没有使有效地一个参数,它只是一个你不会改变它的承诺,但有办法绕过它。 case语句需要一个编译时常量。

答案 1 :(得分:3)

你问是否有办法接受 Nx 作为我们知道的常数参数?"。我们知道 Nx 形成一个常量表达式,我们确实知道它

Nx作为常量表达式的唯一方法是将Nx作为命名常量。作为一个命名常量与伪参数是不兼容的,即使是与intent(in)或没有intent属性相关联的参数,也具有命名常量。

从概念上讲,子程序foo就主程序而言是一个外部程序(那里是一个接口块)。这意味着人们会期望它被编译为一个独立的东西,在后面的阶段被链接。无论最终用途如何,它都应该有效。 [也就是说,即使它不是一个外部程序,第一部分仍然保持在语言规范的范围内。]

当然,如果您不想使用Nx构造重写此命名,还有其他方法可以在子例程中使if命名常量。