我有一段与以下内容类似的代码:
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 :(得分:2)
首先,正如汉斯所说,int^
是非标准的,你总是想要int
。重新写入gcnew array<int,2>(dTest1, dTest2)
后,我仍然会得到与您相同的结果。
我接受了代码,并使用.Net Reflector:
将其反编译为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)
所以看起来它在评估堆栈上放了两倍,它应该是一个整数。
作为double的 20.0
是这些字节:0x4034000000000000
。您获得的iTest1的值为1077149696
,即0x40340000
。
数组构造函数接受堆栈上的double,并将字节解释为两个整数,并按照告诉的方式构造数组。
如您所见,它将第一个参数(num5,15.0
)正确转换为整数。这就是一维数组工作的原因。
这让我觉得可能是C ++ / CLI编译器中的一个错误。