您好我无法弄清楚以下代码是如何产生的 输出为ffffffaa 请帮我理解
#include<stdio.h>
int main()
{
int a=0xaaaaaaaa;
char *p=(char*)&a;
printf("%x\n",*p);
}
答案 0 :(得分:5)
像printf
这样的变量函数在其尾随参数上执行默认参数提升。 char
被提升为int
,并且在平台上签署char
时会执行符号扩展。
要避免代码扩展名使用unsigned char
类型,或在*p
程序的unsigned char
中将printf
投射到{{1}}。
答案 1 :(得分:1)
我无法弄清楚上面的代码如何生成ffffffaa
,因为它无法使用"%d"
说明符执行此操作; - )。
你可能错误地输入了代码示例,它应该是:
int main() {
int a=0xaaaaaaaa;
char *p=(char*)&a;
printf("%x\n",*p);
}
对于生成ffffffaa
的代码,char必须是8位有符号的,并且int必须以小端顺序存储或者大小最多为32位。
&a
是内存中a
的第一个字节的地址。取消引用此地址作为char *
加载一个字节并将符号扩展为int
,然后将其传递给printf
,因为此函数是可变参数。类型小于int
的变量函数的额外参数将提升为int
并按原样传递,小于double
的浮点类型将提升为double
并作为此类传递。 printf
收到int
,但会为格式说明符unsigned int
打印%x
的十六进制表示形式。 int
和unsigned int
以同样的方式传递是一件好事; - )
由于值0xaaaaaaaa
在小端和大端顺序中具有相同的表示形式,因此只要int
为32位或更少,您的代码就不会依赖于字节序。但是在大端序列为64位int
的计算机上(例如一些后期PowerPC),a
的实际内存布局为00 00 00 00 aa aa aa aa
。然后,您的代码将生成0
输出。
您可以使用此代码示例了解字节顺序:
#include <stdio.h>
int main(void) {
int i, a = 0x12345678;
unsigned char *p = (unsigned char *)&a;
printf("Memory layout for %x is:", a);
for (i = 0; i < (int)sizeof(a); i++)
printf(" %02x", p[i]);
printf("\n");
}
如果不同的编译器针对不同的体系结构(32比64位),可能会在同一台机器上产生不同的输出。