1

我有一段类似于以下的代码:

  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);

二维数组的长度是可变的,长度信息存储在 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);
4

1 回答 1

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)

所以看起来它在评估堆栈上放了一个双精度数,它应该是一个整数。

20.0,作为双精度,是这些字节:0x4034000000000000。您为 iTest1 获得的值是1077149696,即0x40340000

数组构造函数获取堆栈上的双精度数,并将字节解释为两个整数,并按照指示构造数组。

如您所见,它将第一个参数 (num5, 15.0) 正确转换为整数。这就是一维数组起作用的原因。

这让我觉得可能是 C++/CLI 编译器中的一个错误。

于 2013-07-02T17:09:48.320 回答