2013-07-02 28 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++,所以我仍然需要学习如何使用它,而不会犯大错误。一般来说,我知道使用双精度来定义一个数组是无稽之谈,但是如上所述,我认为尽管编译器警告它仍然可以工作。 顺便说一句:对于迟到的答案抱歉,我已启用电子邮件通知,但没有。 –