2013-07-02 63 views
1

我有一段代碼,類似於以下內容:雙變量定義2D CLI陣列長度失敗

double dTest1, dTest2; 
    int iTest1, iTest2; 
    dTest1 = 15.0; 
    dTest2 = 20.0; 
    array<int^,2>^ arr2Test = gcnew array<int^,2>(dTest1, dTest2); 
    iTest1 = arr2Test->GetLength(0); 
    iTest2 = arr2Test->GetLength(1); 

2D陣列的長度是可變的,並且所述長度信息存儲在2個雙變量。原來不行:

iTest1 = 1077149696 
    iTest2 = 0 

這裏怎麼回事?編譯器或解釋器不能使用雙變量來存儲數組長度嗎?

其實它工作時,我有一維數組:

array<int^>^ arrTest = gcnew array<int^>(dTest1); 
    iTest1 = arrTest->GetLength(0); 
    --> iTest1 = 15 


上面的問題的解決方案是一個明確的轉換成int,這本來也應該做,但也被人遺忘(如果你不要給編譯器警告該死的):

array<int^,2>^ arr2Test = gcnew array<int^,2>((int)dTest1, (int)dTest2); 
+0

C++/CLI的兩種基本生存策略。一個是何時知道要使用帽子^,int是一個值類型,不應該寫成int ^。另一種是如何知道對它提出問題,「沒有工作」是一個糟糕的問題描述。當然,數組具有整數個元素,1.5個元素沒有多大意義。編寫有意義的代碼並消除許多問題。 –

回答

2

首先,正如漢斯說,int^是非標準的,你總是希望int。一旦重寫爲gcnew array<int,2>(dTest1, dTest2),我的結果仍然和你一樣。

我把代碼,並反編譯與.net反射C#語法:

int[,] numArray = null; 
double num5 = 15.0; 
double num4 = 20.0; 
numArray = new int[(int) num5, (double) ((int) num4)]; 

而這裏的實際IL的最後一行:

L_001a: ldloc.s num5 // Loads the local variable onto the evaluation stack. 
L_001c: conv.i4 // Converts the value at the top of the evaluation stack to int32 
L_001d: ldloc.s num4 // Loads the local variable onto the evaluation stack. 
L_001f: conv.i4 // Converts the value at the top of the evaluation stack to int32 
L_0020: conv.r8 // Converts the value at the top of the evaluation stack to float64 
L_0021: newobj instance void int32[0...,0...]::.ctor(int32, int32) 

所以它看起來像它的推杆評估堆棧中的雙精度值,它應該是一個整數。

20.0,作爲雙精度,是這些字節:0x4034000000000000。您爲iTest1獲得的價值是1077149696,即0x40340000

數組構造函數使用堆棧中的double值,並將字節解釋爲兩個整數,並按照它的說明構建數組。如你所見,它將第一個參數(num5,15.0)轉換爲一個正確的整數。這就是一維數組工作的原因。

這可能是C++/CLI編譯器中的一個錯誤。

+0

感謝您的幫助!我假設了這樣的事情,但我不確定。 另外,感謝您對C++/CLI的解釋。我之前沒有使用過CLI,我總是使用C++,所以我仍然需要學習如何使用它,而不會犯大錯誤。一般來說,我知道使用雙精度來定義一個數組是無稽之談,但是如上所述,我認爲儘管編譯器警告它仍然可以工作。 順便說一句:對於遲到的答案抱歉,我已啓用電子郵件通知,但沒有。 –