不知道这个指针可能指向什么,也无法解释结果
这是考试中的过去问题,但我无法理解最后4个printf函数的结果。我得到的转换为十六进制为第2,但我实在不明白怎么会有在不知道这个指针可能指向什么,也无法解释结果
ptr[0] to ptr[3]
是字符这是被编译并运行的代码段。
int main(int argc, char *argv[]){
typedef unsigned char byte;
unsigned int nines = 999;
byte * ptr = (byte *) &nines;
printf ("%x\n",nines);
printf ("%x\n",nines * 0x10);
printf ("%d\n",ptr[0]);
printf ("%d\n",ptr[1]);
printf ("%d\n",ptr[2]);
printf ("%d\n",ptr[3]);
return EXIT_SUCCESS;
}
,这是相应的输出
3e7
3e70
231
3
0
0
这个代码显示的每个单独字节的值(假定为32位)的数nines
。
nines
的值是十进制999,3E7以十六进制,并根据印刷的值,它的存储在小端字节顺序(‘最小显著’字节至上)。
它很容易看到,如果你值转换为十六进制还有:
printf ("%x\n",ptr[0]);
printf ("%x\n",ptr[1]);
printf ("%x\n",ptr[2]);
printf ("%x\n",ptr[3]);
这将显示此:
E7
3
0
0
此外,你可以这样理解十进制值:
231 + 3*256 + 0*65536 + 0*16777216 = 999
nines
是栈上的一个无符号的32位整数(注意这是可能的对于int
是64位宽,但在这里似乎不是这种情况)。 ptr
是一个指针,它被初始化为地址nines
。由于它是一个指针,因此可以使用数组语法来访问指向地址的值。我们假设它是一个小端机器,所以ptr[0]
是nines
第一(最低显著)字节,ptr[1]
是下等 231
是那么至少显著字节的值,以十六进制是0xe7
当您执行byte * ptr = (byte *) &nines;
时,您将ptr
的地址设置为与nines
相同的地址。这有999
值和十六进制是0x3e7
从这个问题,我假设的int
有4个字节,这是一个小端系统。即像这样存储字节。
---------------------------------
| 0xe7 | 0x03 | 0x00 | 0x00 |
---------------------------------
ptr ptr+1 ptr+2 ptr+3
所以,当你打印出来,你得到的231
,3
,0
和0
值(231等于0xe7)
在小尾数系统,其次是英特尔处理器和大多数微控制器今天,最低有效字节首先被存储并且最高有效字节最后被存储。
另一方面,我们有大端系统,其次是一些较老的摩托罗拉控制器和电源电脑。在此,最重要的字节首先被存储。这些系统中的输出将是0,0,3和231。
如果你有这样的考试,我建议你尽快更换讲师。
unsigned int
的表示是指定的实现,它取决于你的机器的大小,字节顺序。
无论如何,铸造从unsigned int*
到char*
然后直接读取它的值应该是一个未定义的行为。
在像x86机器小端,你的999
unsigned int
表示为:
| 0xE7 | 0x03 | 0x00 | 0x00 |
-----------------------------
ptr ptr+1 ptr+2 ptr+3
与|
之间的数量是在byte
值。因此,将被打印为:
231 3 0 0
在另一台机器,比方说,一个32位,大端(例如爱特梅尔AVR32),它将被表示为:
| 0x00 | 0x00 | 0x03 | 0xE7 |
-----------------------------
ptr ptr+1 ptr+2 ptr+3
然后它将打印:
0 0 3 231
在另一台机器上,比方说,一个32位,中端,这将表示为:
| 0x03 | 0xE7 | 0x00 | 0xE0 |
-----------------------------
ptr ptr+1 ptr+2 ptr+3
那么它会打印:
3 231 0 0
在较老的机器,比方说,一个16位的小端机,它被表示为:
| 0xE7 | 0x03 | xx| xx |
------------------------
ptr ptr+1 ptr+2 ptr+3
与xx
是不确定的值,另外还有一个未定义的行为。
在64位大端机器,它被表示为:
| 0x00| 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x03 | 0xE7
-----------------------------
ptr ptr+1 ptr+2 ptr+3
它将打印:
0 0 0 0
这是说,有一个为考试的问题没有确切的答案。如果是的话,它仍然会调用未定义的行为。
进一步阅读有关Endianness,undefined behavior
该代码是依赖于平台的。
鉴于你的平台是:
- 的Little Endian
CHAR_BIT == 8
sizeof(int) == 4
999内存中的二进制表示11100111 00000011 00000000 00000000
。
因此,999在内存中的十进制表示形式为231 3 0 0
。
作为一个侧面说明,你应该把它带到你的老师在学校/学院/大学的注意,既然这个代码是依赖于平台的,它被赋予作为一项非常坏的榜样的考试。
提示:考虑到'unsigned int'变量最可能需要4个字节,写下'999'的二进制表示形式。 – SingerOfTheFall
将这些'%d'更改为'%x'并再次运行。它应该更清楚。 – WhozCraig
@SingerOfTheFall最重要的部分是'最有可能的',它取决于体系结构,那么这个问题就不能正确地回答。 – Danh