select case语句中的非常量变量

时间:2017-01-04 16:41:44

标签: fortran

假设我的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来保证代码的完整性。

1 个答案:

答案 0 :(得分:2)

如果我写这篇文章,我真的不会使用select case构造。我会根据这样的假设回答,尽管这样做是必要的。

一般的答案是使用案例选择器,无论哪种形式

  • (n)
  • (l:)
  • (l:u)
  • (:u)

它需要,每个(nlu)都必须是标量常量表达式。这就是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不是去这里的方式。