Char自动转换为int(我猜)

Char自动转换为int(我猜),c,C,我有以下代码 char temp[] = { 0xAE, 0xFF }; printf("%X\n", temp[0]); 为什么输出是FFFFFF AE,而不仅仅是AE 我试过了 printf("%X\n", 0b10101110); 并且输出正确:AE 建议?您得到的答案,FFFFFF AE,是签名的char数据类型的结果。如果您检查该值,您会注意到它等于-82,其中-82+256=174,或者是十六进制的0xAE 打印0b10101110甚至174时获得正确输出的原因是,您直接使用文字

我有以下代码

char temp[] = { 0xAE, 0xFF };
printf("%X\n", temp[0]);
为什么输出是
FFFFFF AE
,而不仅仅是
AE

我试过了

printf("%X\n", 0b10101110);
并且输出正确:
AE


建议?

您得到的答案,
FFFFFF AE
,是签名的
char
数据类型的结果。如果您检查该值,您会注意到它等于-82,其中-82+256=174,或者是十六进制的
0xAE

打印
0b10101110
甚至174时获得正确输出的原因是,您直接使用文字值,而在您的示例中,您首先将0xAE值放在
有符号字符中,如果您想这样想的话,该值随后被排序为“重新解释的模128”

换句话说:

    0   =    0 = 0x00 
    127 =  127 = 0x7F
    128 = -128 = 0xFFFFFF80
    129 = -127 = 0xFFFFFF81
    174 =  -82 = 0xFFFFFFAE
    255 =   -1 = 0xFFFFFFFF
    256 =    0 = 0x00
要解决这个“问题”,您可以声明最初使用的相同数组,只需确保使用
无符号字符
类型数组,并且您的值应按预期打印

#include <stdio.h>
#include <stdlib.h>


int main()
{
    unsigned char temp[] = { 0xAE, 0xFF };

    printf("%X\n", temp[0]);
    printf("%d\n\n", temp[0]);

    printf("%X\n", temp[1]);
    printf("%d\n\n", temp[1]);

    return EXIT_SUCCESS;
}

根据手册页,
%x
%x
接受一个
无符号整数
。因此,它将从堆栈中读取4个字节

在任何情况下,在大多数架构下,您都不能传递小于
(即
int
long
)大小的参数,在您的情况下,它将转换为
int.

在第一种情况下,您传递的是
字符
,因此它将被强制转换为
int
。两者都是有符号的,因此执行有符号的强制转换,因此您可以看到前面的
FF
s

在第二个示例中,实际上一直传递一个
int
,因此不执行强制转换

如果您愿意尝试:

printf("%X\n", (char) 0b10101110);

您将看到
FFFFFF AE
将被打印。

当您将小于
int
的数据类型(如
char
is)传递给变量函数(如
printf(3)
is)时如果参数是
有符号的
,则将该参数转换为
int
;如果参数是无符号的,则将该参数转换为
无符号的int
。所做的和您观察到的是一个符号扩展名,由于
char
变量的最有意义位处于活动状态,它被复制到完成
int
所需的三个字节

unsigned char my_char;
...
printf("%X\n", my_char);
要解决此问题并将数据转换为8位,有两种可能:

  • 允许您的
    signed char
    转换为int(带符号扩展名),然后屏蔽位8及以上

    printf("%X\n", (int) my_char & 0xff);
    
  • 将变量声明为
    unsigned
    ,因此它将升级为
    unsigned int

    unsigned char my_char;
    ...
    printf("%X\n", my_char);
    
此代码导致。
%X
的参数必须具有类型
unsigned int
,但必须提供
char


未定义的行为意味着任何事情都可能发生;包括但不限于输出中出现的额外F。

使用
-pedantic
编译器开关将诊断问题