2013-10-13 85 views
0

我遇到了一個關於loacal變量初始化的問題。fortran結果變量未初始化

我得到了下面的函數來計算gammar

function gammar(z) result(gz) 
implicit none 
real(8),intent(out)::gz 
real(8)::z,t,low,up 
real(8),parameter::increment=1.0 
real(8),parameter::lower_t=0.0,upper_t=10.0 
integer(4)::i,n 
!gz=0.0 
n=(upper_t-lower_t)/increment 
do i=1,n 
low=lower_t+(i-1)*increment 
up=lower_t+(i)*increment 
gz=gz+(f(z,low)+f(z,up))*increment/2.0 
end do 
end function gammar 

Then I call this function in main program like 
df=9.0 
t=0.0 
write(*,*) gammar((df+1.0)/2.0)/sqrt(pi*df)/gammar(df/2.0) 

我得到了錯誤的答案! 0.126 我發現原因是在計算gammar((df + 1.0)/2.0)後,局部變量gz未設置爲0.因此,當計算gammar(df/2.0)時,gz仍然保留舊值24最終,gammar(df/2.0)得到了錯誤的答案34 .. 如果我在gammar函數中添加gz = 0.0,則此問題已修復。 這真的很令人驚訝。爲什麼當gammar每次被調用時,本地gz沒有初始化爲零?

非常感謝

問候 柯

回答

1

除非你有一個聲明的程序初始化一個局部變量,比如你已經註釋掉gz = 0,這些局部變量不會被初始化時程序被調用。它們的值是不確定的。它們可能具有先前調用留下的值或某個隨機值。

如果使用編譯器的完整警告選項,它可能會告訴你這個問題。 gfortran在編譯時警告未初始化的變量。 ifort在運行時檢測到問題。

另一個初始化方法是聲明。這仍然不會重複該過程的其他調用的初始化。如果使用聲明(例如integer :: count = 0)在過程中初始化局部變量,則只會在過程的第一次調用時完成初始化。但是...變量仍然定義,並且在下一次調用時將保留先前調用退出時的值。

P.S. real(8)不是一種獲得雙精度實數的便攜式方法。語言標準沒有爲類型指定具體的數值......編譯器可以隨意使用任何值。大多數編譯器使用字節數,但使用其他編號方法。最好使用selected_real_kindISO_FORTRAN_ENV和(雙精度)real64。見quad precision in gfortran

P.P.S.嘗試此代碼gfortran,該編譯器所指出的另一個問題gz

function gammar(z) result(gz) 
          1 
Error: Symbol at (1) is not a DUMMY variable 

所以去除intent(out)在聲明。