2017-05-23 121 views
2

我的FORTRAN 77碼的一部分轉化爲C++FORTRAN等價於C++語言

DIMENSION ARRAY(513),JRRAY(2,513) 
EQUIVALENCE (ARRAY(1),JRRAY(1,1)) 

這是每個變量名開始與I隱含代碼,J,K,L,M,N,O, P隱含地被視爲整數類型。因此,在這裏我們有一個名爲ARRAY的雙精度數組和一個名爲JRRAY的整型數組。

等價性語句將兩個數組的起點指向相同的內存位置。然而,不管怎樣,當ARRAY(I)被調用時,這些字節被解釋爲兩個不同的形式,或者當JRRAY(I,J)被調用時(至少我認爲會發生什麼),這些字節被解釋爲不同的形式。

C++中是否有類似的方法,其中相同的內存位置可以解釋爲不同的類型?

或者與FORTRAN中的EQUIVALENCE相同,但是在C++中。

+1

回想一下,在fortran數組中,按列的主要順序存儲,所以'JRRAY(1,X)'和'JRRAY(2,X)'指向'ARRAY(X)'的連續部分。 –

+0

您的意思是對錶示的實際重新解釋還是自動轉換?即如果我將pi存儲在'ARRAY'中並從'JRRAY'中讀出,我會得到'3'還是與'double'的位模式相對應的數字? – Quentin

+0

@Quentin FORTRAN只是重新解釋表示,所以這大概是他想在C++中做的。 – Barmar

回答

5

的類似特徵是union

union { 
    double array[513]; 
    int jrray[513][2]; 
} equiv; 

然後,您可以訪問equiv.array[i]equiv.jrray[i][j]

但是,請注意,訪問聯合的另一個成員而不是最後寫入的成員會導致C++中的未定義行爲。見Unions and type-punning。如果您想要將數據重新解釋爲不同的數據類型,則應使用reinterpret_cast<>,而不是類型雙擊。

+0

回想一下FORTRAN是列主要的,所以你必須在jrray中切換尺寸 –

+0

這是UB,所以你應該檢查你的實現是否真的支持它。 – Quentin

+2

@Quentin如果你訪問的是一位不同於你上次寫信的成員,那只有UB。工會自己支持。我已經添加了另一個問題的鏈接,解釋了在C和C++中使用類型雙擊的問題。 – Barmar

1

C union經常用於此目的,如Barmar的answer。然而,你可以使用類型轉換來將浮點數組引用爲整型數組。

考慮的array如下聲明和定義的jrray

double array[513]; 
int (*jrray)[2] = reinterpret_cast<int (*)[2]>(array); 

我們可以檢查該聲明的工作原理是在看指數如預期的實例。我們將在jrray[k][1]的位20-30中具有array[k]的指數。

例如,檢查,如果我們現在初始化數組的元素

array[0] = 1.23*2; // exponent is 1 
array[1] = 1.23*4; // exponent is 2 
array[2] = 1.23*8; // exponent is 3 

,我們將有

((jrray[0][1] >> 20) & 0x7FF) - 1023 == 1 
((jrray[1][1] >> 20) & 0x7FF) - 1023 == 2 
((jrray[2][1] >> 20) & 0x7FF) - 1023 == 3 

無論哪種方式,這違反了C++嚴格別名規則,並可能導致未定義的行爲。

+2

注意:這與上面的聯合技巧一樣沒有定義,但不同於那個,它不是**,通常是由實現定義的,並且會受到最輕微的干擾。有關示例,請參見[這裏](https://godbolt.org/g/2EUDU7)。 – Quentin

+0

@Quentin自OP正在移植FORTRAN代碼,其中函數參數可能不是別名,他可能是安全的。 –

+0

這只是一個例子。編譯器會高興地認爲這是兩個不同的數組,如果它允許它進行更多的優化(就像它在內聯函數時所做的那樣)。你不能依靠它工作。 – Quentin