解除引用和类型转换

时间:2011-03-08 14:13:07

标签: c pointers casting

我构建了以下代码部分,以帮助自己理解C中的指针解引用和类型转换。

char a = 'a';
char * b = &a;
int i = (int) *b;

对于上述内容,我理解在第3行,我已取消引用b并得到'a'和(int)将'a'的值转换为其对应的值97,该值存储在i中。但对于这部分代码:

char a = 'a';
char * b = &a;
int i = *(int *)b;

这导致我是一些像792351这样的任意大数字。我假设这是一个内存地址,但我的问题是为什么?当我将b转换为整数指针时,这是否会导致b指向内存中的其他区域?发生了什么事?

编辑:如果上述方法不起作用,那么为什么会这样呢:

char a = 'a';
void * b = &a;
char c = *(char *)b;

这正确地将'a'分配给c。

6 个答案:

答案 0 :(得分:3)

您的int大于char - 您在内存中获得了'a'值+一些随机数据。

例如,在内存中假设这种布局:

'a'
0xFF
0xFF
0xFF

您的char *int *都指向'a'。当您取消引用char *时,只会获得第一个字节'a'。当你取消引用int *(假设你的int是32位)时,你会得到'a'未初始化数据的3个字节。

编辑:回应更新的问题:

char c = *(char *)b;中,b仍然指向'a'值。您将其转换为char *,然后取消引用它,获取char * 指向的字符

答案 1 :(得分:2)

你关注的最后一行是非常糟糕的事情。首先,它将b视为int*,而b是char*。也就是说,将b的存储器指针假定为4个字节(通常)而不是1个字节。因此,当您取消引用它时,它会转到实际b指向的1个字节,也会接受以下3个字节,将这4个字节视为单个int,并为您提供结果。这就是为什么它是垃圾。

通常,必须非常谨慎地将一个指针类型转换为另一个指针类型。

答案 2 :(得分:1)

您正在向int指针强制转换char指针。字符(通常)存储为8位。另一方面,int是32位(或64位系统上的64位)。因此,如果你查看值为b的8位旁边的其他24位内存,你将获得一堆未初始化的额外位。即使*bi的位置依赖于架构。

big-endian:    **** ****|**** ****|**** ****|0110 0001
little-endian: 0110 0001|**** ****|**** ****|**** ****

当您投射上面存储的角色时,所有星号都变得相关。

答案 3 :(得分:1)

由于char长1字节,int 4,当您从单个字符的地址读取int时,您正在阅读该字符,还有3个字符字节。这些字节的内容就是发生在内存中的任何内容(指针,b的值),甚至可以是未分配的(导致分段错误)。

答案 4 :(得分:0)

当你将它转换为(int *)类型时,它将在内存中引用总共4个字节(大小,如果 int )。

答案 5 :(得分:0)

在第二种情况下,您将处理相同的地址,就像它指向int一样。正式来说,结果只是未定义的行为。

实际上,发生的事情是,从该地址开始的四个 1 字节中发生的任何事情都被解释为int。

1 假定32位int的4个字节 - 如果您的实现具有例如64位int,则它将是8个字节。