有人可以解释这段代码的工作原理以及原因吗?
int x = 0x1204;
char v0 = *reinterpret_cast<char*> (&x) + 3;
printf("%d %x %c \n", v0, v0, v0);
char v3 = *(reinterpret_cast<char*> (&x) + 1) + 11;
printf("%d %x %c \n", v3, v3, v3);
short w4 = *(reinterpret_cast<short*>(&y) + 1) + 11;
printf("%x %u %d \n", w4, w4, w4);
long w1 = *reinterpret_cast<long*>(&y) + 33;
printf("%lx %lu %ld \n", w1, w1, w1);
这是我的新手版本。
char v0 = *reinterpret_cast<char*> (&x) + 3;
printf("%d %x %c \n", v0, v0, v0);
我们正在使用x
的地址,然后将其类型从int
转换为char
,取消引用它,将3添加到地址值,最后分配给v0。
它如何看待位和字节?
我的猜测是这样的。我们得到4个字节的int,并且在转换之后我们将控制第一个位(因为char大小)。之后,我们取消引用该位并添加3.最后,v0的值为bit + 3.
它看起来像这样吗?
0001 0010 0000 0100 (int)
0001 (dereferenced char)
0100 (char + 3)
如果有人帮助我解决这4个演员阵容就好了。
答案 0 :(得分:1)
int x = 0x1204;
char v0 = *reinterpret_cast<char*> (&x) + 3;
你基本上是正确的,但我会把它分解一点。
int x
在某个地址分配4个字节的内存来存储int值。 (在大多数实现中可能是4个字节)
= 0x1204;
将00 00 12 04的十六进制值(0x前缀表示十六进制)分配给为'x'分配的4个字节。字节的顺序可能是特定于实现的。
我们现在分配了4个字节的内存,这些字节的值为00,00,12和04。变量x'指向'那4个字节,并将该值解释为整数。
在下一行中, &安培; X 表示“x的地址”
reinterpret_cast<char*> (&x)
意味着“看看x的地址是什么,好像我们正在看一个角色”。我们知道x确实指向形成整数的4个字节的数据。这是一种一次一个字节查看这4个字节中数据的方法。我们现在正在查看“第一个”字节。
*reinterpret_cast<char*> (&x)
表示reinterpret_cast(&amp; x)指出的“指向的内容”。
*reinterpret_cast<char*> (&x) + 3
表示“添加3”到指向x地址的字符。
char v0 = ....
表示在v0指向的地址处分配一个字节的内存,并将我们刚刚计算的值分配给该位置。
现在,&amp; x指向int'x'的4个字节的'first'字节。哪个字节是第一个字节可能是特定于实现的。在我的情况下,&amp; x重新解释为一个char实际上指向包含4的字节。我正在使用intel,Windows,VS2015。
至于printf,我有点不同意这是未定义的行为。 char将隐式转换为printf语句中要求的类型。
printf("%d %x %c \n", v0, v0, v0);
我们要求在'v0'打印字符3次。一次作为十进制值(%d),一次作为十六进制值(%x),一次作为字符(%c)。 在我的例子中,重新解释转换所指向的字节包含4.添加3到4给出7.这打印:
7 7
由于7十六进制是铃声字符,我得到最后一个值的声音,没有打印输出。
如果您使用摩托罗拉硬件,我怀疑您可能会指向int的另一端,这似乎是您在分析中做出的假设。
char v3 = *(reinterpret_cast<char*> (&x) + 1) + 11;
这个稍微不同,因为它将x的地址加1,后者移过一个字节。 (因为有parens强制+1将1添加到char指针,这使得它指向它指向的位置1个字符。)现在在我的实现中它指向其中带有'0x12'的字节。将十进制11添加到十六进制12会产生十进制值29或十六进制数。
我的输出是29 1d(一些无法正确打印的未知字符)
如前所述,你的帖子中没有显示y的值...
答案 1 :(得分:-1)
此练习的目的是使您拥有机器的心理模型。在C ++中,这个简单的心智模型可能对你有所帮助,但你也要学习它的局限性,后者(这里有实现定义的行为和严格的别名规则&#34;违规)
对不起!!!事实上,这肯定是:(字符必须是8位!)
0000 0000 0000 0000 0001 0010 0000 0100 (int)
0000 0000 (dereferenced char)
0000 0100 (char + 3)
0000 0100 0000 0000 0001 0010 0000 0100 (int after char + 3)
//the second:
char[1]
0000 0100 0000 0000 0001 0010 0000 0100 (int)
0000 0000 (dereferenced char[1])
0000 1011 (char + 11)
0000 0100 0000 1011 0001 0010 0000 0100 (int after char + 11)
//then I do not know what is y!!