2012-03-01 72 views
0
unsigned char myArray[10]; 

myArray[0] = 0; 
myArray[1] = 0; 
myArray[2] = 0; 
myArray[3] = 22; 

cout << *((int *) (myArray)) << endl; 

我在一个类中显示了这段代码,但没有很好地解释它。我确定输出等于(256^3)* 22,但我不知道为什么这是它打印出来的。任何人都可以向我解释这个吗?这段代码在做什么?涉及字符数组和指针(C++)

+7

我希望你在一个低级别的编程课程中接受过这样的教育,他们告诉你,你得到的结果不能由C++保证,部分原因是平台问题。 – 2012-03-01 01:08:24

+0

将它分解:'(int *)myArray'是什么?那么什么是'*((int *)myArray)'?正如Nicol Bolas所提到的,打印出的内容取决于系统的字节顺序以及sizeof(int)。 – gregheo 2012-03-01 01:10:14

+0

您必须在英特尔机器上工作;其他地方(大端系统)会打印22,如果它们没有崩溃的话。当数组被充分对齐以被视为整数时,它“起作用”。在非英特尔芯片上,如果您在数组之后声明一个变量'char c1;'之前的数组和一个变量'char c2;',它可能无法工作。如果你有额外的变量,它会在许多编译器的Intel机器上运行得更慢。不过,它依赖于编译器。 – 2012-03-01 01:11:30

回答

3

该代码不安全且不可移植。

它(明显地)将值0,0,0和22存储在myArray的前4个元素中,每个元素是unsigned char(单个字节)。

表达式myArray是一个数组的名称,它在大多数情况下(包括这一个)“衰减”为指向数组的第一个元素的指针,类型为unsigned char*。演员阵将unsigned char*转换为int*,并且*运算符将该指针作为参数,产生一个int结果。

所以*((int *) (myArray))取第一个4个字节myArray重新解释它们作为int对象。

这里至少有3个问题。

  1. 不能保证myArray对于int对象正确对齐。它可能是是,但是如果不是这个行为是未定义的;你可能会遇到一个公交车错误,或者一个不正确的结果,或者其他的事情。 (x86处理器对齐并不是很挑剔,但其他系统都是。)
  2. 不保证sizeof (int) == 4。如果int是8字节,那么它将重新解释myArray的第一个字节作为int - 并且这些字节中的4个是垃圾。
  3. int的表示形式可以有所不同。主要问题是字节顺序。假设没有其他问题出错,结果可能是256 * 22或22 - 甚至是别的。
2

最后一行将myArray的地址重新解释为指向int的指针,将其解除引用并打印出来。在32位系统上,int的长度为4个字节,所以myArray[0]myArray[3]正在作为int被介绍。 int的感知值取决于endianness