2013-08-22 74 views
2

我想了解我將向您展示的邏輯背後的邏輯。
如果我有一個 'module.f90':Fortran90中的動態數組分配

module def_dimens 
integer :: dimens=4 
end module def_dimens 

一個 'subr.f90':

subroutine sub(X) 
integer :: X 
integer :: S(1:X*5) 
S=1 
print*,S 
end subroutine sub 

和 'main.f90時':通過編譯

program test 
use def_dimens 
call sub(dimens) 
end program test 

gfortran module.f90 subr.f90 main.f90並運行結果沒有任何問題。

但是,隨着

program test 
use def_dimens 
integer :: A(1:dimens*5) 
A=1 
print*,A 
end program test 

給「main2.f90」和編譯gfortran module.f90 main2.f90我有一個錯誤,所以我必須使用可分配數組:

program test 
use def_dimens 
integer,allocatable :: A(:) 

allocate(A(1:dimens*5)) 
A=1 
print*,A 
end program test 

或我要指定' (但這對我沒用, ,因爲在比這更復雜的情況下,我需要一個變量,在使用它之前調用另一個子例程來修復它的值)。

所以我的問題是:爲什麼會有這樣的差異?爲什麼gfortran在 必須通過使用一個變量來修改其大小來在主程序中聲明一個數組時纔會抱怨,而在子程序中這樣做沒有任何問題?

回答

2

你不能有一個靜態定義數組與編譯器認爲是變量變量。錯誤代碼(你已打印的話)是相當清楚的:

Error: the module or main program array a at (1) must have constant shape

編譯器不知道dimens應該恆定。您可以通過聲明dimens作爲parameter解決這個問題:

module def_dimens 
    integer, parameter :: dimens=4 
end module 
+0

你說的事情已經很清楚了。例如(你讀得更好我的問題)我已經聲明,參數是一種解決問題的方法。我問你爲什麼可以將一個變量傳遞給一個子程序,該子程序使用它來設置一個數組的大小,但如果不使用子程序從模塊中取出它,則無法做到這一點。我在問是否有與內存使用方式相關的內容,例如,不僅僅是如何解決問題,因爲我已經知道如何做到這一點。 – Gippo

+0

然後我的第一行回答你的問題:你不能有一個具有可變參數的靜態定義數組。正如@VladimirF指出的那樣,子程序定義它是一個*自動數組*,它的處理方式與主程序*不同,因爲*它是一個子程序,它取決於所調用的值(而主程序有**無**稱爲變量)。 –

+1

@Gippo至於你的內存評論,一些編譯器會把自動數組放到堆棧而不是堆上。每個數組都是「靜態」或「動態」數組。正如Kyle所說,靜態數組不能用變量定義,因爲編譯器太愚蠢了,不知道它不會改變。你必須告訴它它不會改變。自動數組(參見弗拉基米爾的答案)是一種動態數組,它們被分配到子程序中並且被分配退出子程序,因此你可以使用一個可變參數。 – dwwork

2

要添加到凱爾的答案,如果你聲明的子程序陣列,這是不是一個僞參數或者不具有save屬性,它是一個automatic array。每次子程序開始運行時它都會自動分配。它根據表達式中變量的值爲其形狀分配。調用之間不保存數組中的值。