reinterpret_cast如何工作?

时间:2017-09-17 18:10:52

标签: c++

有人可以解释这段代码的工作原理以及原因吗?

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个演员阵容就好了。

2 个答案:

答案 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!!