2017-01-04 102 views
1

假設我有以下我的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 

編譯時它會導致錯誤:

Error: Parameter 'n' at (1) has not been declared or is a variable, which does not reduce to a constant expression

所以我的問題:有辦法解決這個問題(我仍然想使用case-statement)?

只是通過使用if語句而不是case-statement來避免這個錯誤是很容易的,但我想用case-來完成我的代碼。

+0

我編輯了我的問題。 – BogdanSikach

回答

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不爲0 (:n)選擇(不爲零)m小於或等於n 。如果(非零)m大於n,則選擇(default)。但是,函數參數之間唯一的區別就是執行什麼。這導致天然的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是不走這裏的路。

+0

真是太遺憾了。我沒有考慮ABS功能。謝謝你的想法。 – BogdanSikach