2016-07-23 19 views
0

GNU FortranコードをCode :: Blocksのmain.f95、example.f95という2つの別々のファイルに書きました。 main.f95内容:Fortran:関数内の他の関数を呼び出す

program testing 

    use example 

    implicit none 
    integer :: a, b 

    write(*,"(a)", advance="no") "Enter first number: " 
    read(*,*) a 

    write(*,"(a)", advance="no") "Enter second number: " 
    read(*,*) b 

    write(*,*) factorial(a) 
    write(*,*) permutation(a, b) 
    write(*,*) combination(a, b) 

end program testing 

example.f95内容:

module example 


contains 


    integer function factorial(x) 

    implicit none 
    integer, intent(in) :: x 
    integer :: product_ = 1, i 

    if (x < 1) then 

     factorial = -1 

    else if (x == 0 .or. x == 1) then 

     factorial = 1 

    else 

     do i = 2, x 
      product_ = product_ * i 
     end do 

     factorial = product_ 

    end if 

    end function factorial 


    real function permutation(x, y) 

    implicit none 
    integer, intent(in) :: x, y 
    permutation = factorial(x)/factorial(x - y) 

    end function permutation 


    real function combination(x, y) 

    implicit none 
    integer, intent(in) :: x, y 

    combination = permutation(x, y)/factorial(y) 

    end function combination 


end module example 

私はこのコードを実行すると、出力は次のとおりです。

Enter first number: 5 
Enter second number: 3 
    120 
    0.00000000  
    0.00000000  

順列と組み合わせの機能が動作しません。正しく。答えをありがとう。

+1

これは、多くのC/C++プログラマーを驚かせるものです。 'integer :: i = 42'は' integer :: i;と等しくない。 i = 42'ではなく、 'save :: i = 42'の代わりに使用します。 'i'の値は呼び出し間で維持され、決して42にリセットされません。 – jlokimlin

答えて

2

私は、Fortranの有名人(それを知っている人)のうちの1人に悪いと思っています。しかし、あなたが行ったテストの量を尋ねなければならないことを明らかにする前に、私はその後、私は明らかに間違っている

factorial   1 =   1 
factorial   2 =   2 
factorial   3 =   12 
factorial   4 =   288 
factorial   5 =  34560 
factorial   6 =  24883200 
factorial   7 = 857276416 
factorial   8 = -511705088 
factorial   9 = 1073741824 
factorial   10 =   0 

を生成xのいくつかの小さな値のためfactorial機能をテストし

...、あなたのコードを実行した奇妙な結果を持って、分考えました。だから、助けを求める前にコードを正しくテストしなかったようです。 (私はあなたのcombinationpermutation機能をテストしていない。)

O TEMPORA、道徳観

oをあなたが行で変数product_

integer :: product_ = 1, i 

を初期化しましたし、これは自動的にいることを意味しproduct_は、属性saveを取得します。その値は呼び出しから呼び出しまで格納されます(gotcha!)。各コールの開始時(最初のコールを除く)には、product_には前のコールの終了時の値があります。

対策は簡単です。product_を初期化しないでください。

integer :: product_ = 1, i 

シンプル

integer :: product_ , i 
... 
product_ = 1 

には、まだ自分自身の階乗関数を記述しないことが、本来の product機能を使用することですが、それはまた別の話だ変更します。

関連する問題