#include <stdio.h>

int main() {
    int i,n;
    int a = 123456789;

    void *v = &a;

    unsigned char *c = (unsigned char*)v;

    for(i=0;i< sizeof a;i++) {
        printf("%u  ",*(c+i));
    }

    char *cc = (char*)v;
    printf("\n %d", *(cc+1));

    char *ccc = (char*)v;
    printf("\n %u \n", *(ccc+1));

}

该程序在我的32位Ubuntu计算机上生成以下输出。
21  205  91  7
-51
4294967245

我能理解的输出的前两行=>
  • 第一行:字节在内存中的存储顺序。
  • 第二行:第二个字节值的有符号值(2的补码)。
  • 第三行:为什么这么大的值(value)?

  • 请解释输出的最后一行。为什么要添加三个字节的1
    因为(11111111111111111111111111001101) = 4294967245

    最佳答案

    显然,您的编译器使用带符号的字符,这是一个小端的二进制补码系统。

    123456789d = 075BCD15h
    Little endian: 15 CD 5B 07
    

    因此v + 1的值为0xCD。当将其存储在带符号的char中时,您将获得带符号的十进制格式的-51

    传递给printf时,首先将包含值*(ccc+1)的字符-51隐式地提升为int,因为诸如printf之类的可变函数具有一条规则,规定所有小的整数参数都将提升为int(默认参数提升)。在此促销期间,会保留标志。您仍然具有-51值,但是对于32位带符号整数,这将得到0xFFFFFFCD值。

    最后,%u说明符告诉printf将其视为无符号整数,因此最终得到42.9亿。

    这里要理解的重要部分是%u与实际的类型提升无关,它只是告诉printf提升之后如何解释数据。

    关于c++ - 使用%u读取签名的字符,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36350405/

    10-11 04:25