2013-07-26 27 views
1

有此程序:Fortran:通過「CALL」命令將主程序中的標量傳遞給子程序中的矢量?

INTEGER i,k 
REAL*8 mp(15,48) 
REAL*8 sp(15) 
k=0 
do i=1,12 
    k=k+1 
    call Equaltensors(sp,mp(1,k),15) 
enddo 
end 

c===================== 

subroutine Equaltensors(tensA,tensB,n) 
REAL*8 tensA(n),tensB(n) 
INTEGER i 
do i=1,n 
    tensB(i)=tensA(i) 
enddo 
return 
end 

所以基本上熔點(1,1)等的值被傳入到該子程序作爲一個矢量tensB(15)中n = 15。我不明白的是如何在一個子程序中將實數存儲在一維數組中。

任何幫助,將不勝感激。

回答

1

編輯:糾正每IanH評論,誰指出,行爲是保證沒有做出關於參數傳遞約定的假設。

這種方法在早期的FORTRAN中開始,假設參數作爲地址傳遞,通常稱爲「通過引用調用」。定標器mp(1,k)的地址是該列k的第一個元素的地址。由於Fortran以列主格式(http://en.wikipedia.org/wiki/Row-major_order#Column-major_order)存儲數組,因此第k列的15個值將在內存中連續存在。因此,如果被調用的子程序將該地址解釋爲長度爲15的一維數組tensB的地址,則它將訪問第k列的元素。

在現代Fortran中,可以通過選擇帶有數組切片的列來更清晰地編寫參數:mp (:,k)

+0

無論參數傳遞執行的行爲是由標準保證的 - 見F2008 12.5.2.4p13和12.5.2.11下的闡述。 – IanH

+0

這和將C中的數組傳遞給'&array [0]'類似,是嗎? – dwwork

+0

是的。一個不同之處在於C對數組和Fortran列主要使用行主佈局。那麼,從一個地址開始訪問二維數組的哪一部分在語言之間會有所不同。 –

2

問題的標題有點誤導。 Fortran不允許將標量傳遞給數組。但是它允許的是將一個數組的單個元素傳遞給例程的數組僞參數 - 這在Fortran中稱爲「序列關聯」。正如IanH和其他人所說的那樣,以下元素將自動與啞元數組的元素相關聯,直到被調用例程的實際數組中的最後一個元素。

雖然這個功能有一些限制。如果元素是POINTER數組,則不能這樣做。回到你的標題,我已經看到許多程序將常量3傳遞給一個例程,其中dummy是一個數組。該例程僅使用第一個元素,但這不合法,較新的編譯器可能會檢測到錯誤併發出抱怨。一種解決方法是通過使用數組構造函數將參數轉換爲數組,例如,CALL FOO([3]),但只有當值被讀取,而不是寫入時,它纔有效。

我已經寫了一些博客文章對這個普遍問題 - 見http://software.intel.com/en-us/blogs/2009/03/31/doctor-fortran-in-ive-come-here-for-an-argumenthttp://software.intel.com/en-us/blogs/2009/07/10/doctor-fortran-in-ive-come-here-for-an-argument-side-2

相關問題