为什么打印char有时会在C中打印4个字节的数字

Has*_*eem 3 c

为什么使用printf在屏幕上打印十六进制char表示有时会打印一个4字节的数字?

这是我写的代码

#include <stdio.h>
#include <stdint.h>
#include<stdio.h>

int main(void) {
    char testStream[8] = {'a', 'b', 'c', 'd', 0x3f, 0x9d, 0xf3, 0xb6};

   int i;
    for(i=0;i<8;i++){
      printf("%c = 0x%X, ", testStream[i], testStream[i]);
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

以下是输出:

a = 0x61, b = 0x62, c = 0x63, d = 0x64, ? = 0x3F, ? = 0xFFFFFF9D, ? = 0xFFFFFFF3, ? = 0xFFFFFFB6
Run Code Online (Sandbox Code Playgroud)

And*_*mbe 5

char似乎已在您的系统上签名.使用标准的"二进制补码"整数表示,具有最高有效位设置意味着它是负数.

为了传递一个charvararg函数,就像printf它必须扩展到一个int.为了保持其值,符号位被复制到所有新位(0x9D0xFFFFFF9D).现在%X转换期望并打印一个unsigned int,你可以看到负数中的所有设置位而不是减号.

如果你不想这样,你必须在传递它时使用unsigned char或转换unsigned charprintf.一个unsigned char有与无额外的比特signed char,因此相同的位模式.当无符号值被扩展时,新位将为零,并且您首先得到预期的值.