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

Parameters 在Fortran-90中将参数作为参数传递?,parameters,fortran,fortran90,intel-fortran,select-case,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"

假设我有一个子例程:

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值必须是常量表达式

换句话说,即使Nx通过
intent(In)
有效地声明为子例程常量,它也需要是
integer
类型的文本常量或
参数

有没有办法让case语句接受
Nx
作为我们知道的常量参数?是否有方法将
Nx
声明为传入的
参数


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

只需使用if语句即可。子程序参数(您称之为参数)当然不是参数(命名常量)。
intent(in)
并不能有效地将其作为一个参数,它只是一个承诺,您不会更改它,但有一些方法可以绕过它。case语句需要一个编译时常量。

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

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

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


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

FYI您在
“最大值
。还有一个
::
整数中,参数Nx
。你能定义一个包含你的参数和子例程的模块吗?如果可以,那会有帮助吗?:)顺便说一下,你说“换句话说,即使Nx通过
意图(in)
有效地声明为子例程常量”。我认为问题在于fortran在编译时需要知道
大小写
值,所以作为一个子程序常量是不够的。否则,我不明白为什么在不规定任何常量属性的情况下,动态地找出值会对编译器造成伤害。@安德拉斯达克:其他语言不要求switch/select/case构造具有编译时常量(它们通常不是!)。我承认语言规范,但我认为这更像是一个bug,而不是一个特性。(但我知道什么?:-)我认为模块的想法可能会奏效(个人ToDo:测试这个),尽管对于这个目的来说它并不优雅。关键是案例构造通常可以实现为跳转表,而不是像其他分支一样。C具有相同的属性。