3

假设我有一个子程序:

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),它也需要是文字常量或parameter类型integer

有什么方法可以让 case 语句接受Nx我们知道的常量参数吗?有什么方法可以声明Nx为 pass-inparameter吗?

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

4

2 回答 2

5

只需使用 if 语句。子例程参数(称为参数)当然不是参数(命名常量)。intent(in)不会使其有效地成为参数,它只是一个您不会更改它的承诺,但有一些方法可以规避它。case 语句需要一个编译时常量。

于 2015-09-13T19:40:36.310 回答
3

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

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

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

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

于 2015-09-13T19:41:04.610 回答