假设我的Fortran程序中有以下代码:
recursive function T_GreCoDi( n, m ) result (GCD)
implicit none
integer, intent(in) :: n, m
integer :: GCD
select case(n)
case(0)
select case(m)
case(0)
print *, 'both of your numbers are zeros. GCD = -1'
GCD = -1
case default
GCD = m
end select
case(1)
GCD = 1
case default
select case(m)
case(0)
GCD = n
case(:n)!<--THIS IS PROBLEM
GCD = T_GreCoDi(n-m, m)
case default
GCD = T_GreCoDi(m-n, n)
end select
end select
end function T_GreCoDi
编译时会导致错误:
错误:参数&#39; n&#39; at(1)尚未声明或是变量,不会减少为常量表达式
所以我的问题:有没有办法解决这个问题(我仍然想使用case语句)?
很容易通过使用if-statement而不是case-statement来避免这个错误,但是我想使用case来保证代码的完整性。
答案 0 :(得分:2)
如果我写这篇文章,我真的不会使用select case
构造。我会根据这样的假设回答,尽管这样做是必要的。
一般的答案是使用案例选择器,无论哪种形式
(n)
(l:)
(l:u)
(:u)
它需要,每个(n
,l
或u
)都必须是标量常量表达式。这就是Fortran所说的。这就是你的编译器抱怨的原因。
要保留select case
构造,必须重写某些内容。但是什么?
让我们看一下这里的具体案例,以及
部分select case(n)
case(0) ...
case(1) ...
case default ! n is an integer not 0 or 1
select case(m)
case(0) ...
case(****) ! Something here for m<n and m.ne.0
GCD = T_GreCoDi(n-m, m)
case default
GCD = T_GreCoDi(m-n, n)
end select
end select
m
有两个选项,如果(非零)(:n)
小于或等于m
,则会选择n
。如果(非零)(default)
大于m
,则会选择n
。但是,执行的内容之间的唯一区别在于函数参数。这导致了自然if
构造
if (m<=n) then
GCD = T_GreCoDi(n-m, m)
else
GCD = T_GreCoDi(m-n, n)
end if
你不想这样做。是
GCD = T_GreCoDi(ABS(n-m), MIN(m,n))
更好?
select case(n)
case(0)
select case(m)
case(0)
print *, 'both of your numbers are zeros. GCD = -1'
GCD = -1
case default
GCD = m
end select
case(1)
GCD = 1
case default
select case(m)
case(0)
GCD = n
case default
GCD = T_GreCoDi(ABS(n-m), MIN(m,n))
end select
end select
老实说,我认为这证实了我怀疑case construct
不是去这里的方式。