繁体   English   中英

取消引用和类型转换

[英]Dereferencing and typecasting

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

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

对于以上内容,我了解到,在第三行,我已取消引用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。

您的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 *指向的char *

您关心的最后一行是一件非常糟糕的事情。 首先,它将b视为int*而b是char* 即,由b指向的内存指针被假定为4个字节(通常)而不是1个字节。 因此,当您取消引用它时,它会到达实际b所指向的1个字节,也占用以下3个字节,将这4个字节视为单个int,然后为您提供结果。 这就是为什么它是垃圾。

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

您正在将char指针转换为int指针。 字符(通常)存储为8位。 另一方面, int是32位(在64位系统上为64位)。 因此,如果您查看8位b旁边的其他24位内存,则会得到一堆未初始化的额外位。 即使*bi的位置也取决于体系结构。

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

当您转换存储在上面的字符时,所有星号都将变为相关。

由于char长度为1个字节,而int 4,所以当您从单个字符的地址读取int时,您将读取该字符和另外3个字节。 这些字节的内容就是发生在内存中的所有内容(指针, b的值),甚至可能未被分配(导致分段错误 )。

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

在第二种情况下,您将相同的地址当作指向int的地址。 正式地,结果就是简单的不确定行为。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM