我无法弄清楚下面的代码如何产生输出为ffffffaa请帮助我理解?

时间:2015-02-23 19:12:26

标签: c pointers

您好我无法弄清楚以下代码是如何产生的 输出为ffffffaa   请帮我理解

#include<stdio.h>
 int main()
{
  int a=0xaaaaaaaa;
  char *p=(char*)&a;
  printf("%x\n",*p);
}  

2 个答案:

答案 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的十六进制表示形式。 intunsigned 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位),可能会在同一台机器上产生不同的输出。