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
编译器开关将诊断问题