假设我有一个子程序:
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块就足够了,但后来我不知道这个问题的答案。 :-)
答案 0 :(得分:5)
只需使用if语句即可。子程序参数(您调用参数)当然不是参数(命名常量)。 intent(in)
没有使有效地一个参数,它只是一个你不会改变它的承诺,但有办法绕过它。 case语句需要一个编译时常量。
答案 1 :(得分:3)
你问是否有办法接受 Nx 作为我们知道的常数参数?"。我们不知道 Nx 形成一个常量表达式,我们确实知道它不。
Nx
作为常量表达式的唯一方法是将Nx
作为命名常量。作为一个命名常量与伪参数是不兼容的,即使是与intent(in)
或没有intent
属性相关联的参数,也具有命名常量。
从概念上讲,子程序foo
就主程序而言是一个外部程序(那里是一个接口块)。这意味着人们会期望它被编译为一个独立的东西,在后面的阶段被链接。无论最终用途如何,它都应该有效。 [也就是说,即使它不是一个外部程序,第一部分仍然保持在语言规范的范围内。]
当然,如果您不想使用Nx
构造重写此命名,还有其他方法可以在子例程中使if
命名常量。