考虑代码:
int main() {
char orange[5];
for (int i = 0; i < 5; i++)
orange[i] = 1;
printf("orange: %d\n", *((char *)orange));
printf("orange: %d\n", *((int *)orange));
return 0;
}
第一个print语句的值为1
,但第二个print语句的值为16843009
。差异的原因是什么?
答案 0 :(得分:5)
在第二个中,您别名某些相邻的char
值为int
。根据C标准,这是不确定的;但是,通常的结果是,您将获得int
的值,该值与连接的char
值的位模式具有相同的位模式。
在这种情况下,您看到的值是0x01010101
的小数形式。
这是未定义的行为,因为C99 6.5#7列出了可能有别名的有效类型组合,char
作为int
不在列表中。 (您可以别名int
为char
,但不是相反)。 See here获取标准文字。
由于对齐要求,还存在潜在的未定义行为。例如,某些系统要求int
只能在4的倍数地址访问。
答案 1 :(得分:2)
在第二种情况下,您将其转换为int
指针。因此,假设系统int
为4
个字节,执行*((int *)orange)
将从4
到orange[0]
访问orange[3]
个字节。
由于您在这些地址中包含所有1
,因此orange[0]
到orange[3]
的十六进制表示法将为0x01010101
,其中16843009
为十进制。
答案 2 :(得分:0)
首先你必须知道int是4 bytes quantity
,char是1 byte
。
当机器读取整数时,它将连续读取4个字节。并为char读取1个字节。
在您的情况下,您首先声明一个数组橙色[5],这是机器上连续的5个字节。并为每个字节分配1。所以你会在你的机器上得到这样的东西
0000 0001 0000 0001 0000 0001 0000 0001 0000 0001
变量orange是指向第一个字节的指针。如果您将橙色转换为char *
并取消引用它,则机器将尝试读取此地址上的字符(橙色),这样您就可以获得
0000 0001
如果你将橙色转换为int指针,机器将尝试从橙色开始读取4个字节,这样你就可以得到它。
0000 0001 0000 0001 0000 0001 0000 0001
如果将此二进制数转换为十进制数,则会得到16843009
希望有所帮助:)