[英]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位内存,则会得到一堆未初始化的额外位。 即使*b
在i
的位置也取决于体系结构。
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.