我不明白当我将char变量和int变量相乘并将结果放入char中时发生了什么。例如:
char p= (98*'b') ; printf("%d",p);
为什么是-124?我以为会满溢的。
ktecyv1j1#
“字里行间”发生了什么:
(98*'b')
98
'b'
int
char
printf("%d",...
%d
%hhd
最佳做法:
uint8_t
printf
ar5n3qh52#
这是因为char是有符号的。有符号的char的值为-128至127。因此,当你得到值0x 2584时,MSB被忽略,你实际上得到值0x 84。现在,0x 84在二进制中是:
1000 | 0100 = 0x84
设置最高有效位,因此将其视为负数。因此,如果设置了最高有效位,则我们有:
1000 | 0000 = 0x80 = -128 1000 | 0001 = 0x81 = -127 1000 | 0010 = 0x82 = -126 1000 | 0011 = 0x83 = -125 1000 | 0100 = 0x84 = -124
这就是你得到的。如果你正在寻找一个值0x 2584,那么你需要使用一个16位的数据类型作为最小值,在你的平台上可能是一个普通的int。如果你正在寻找0x 84的实际值,那么你需要使用unsigned char数据类型。类似于:
unsigned char p= (98*'b') ; printf("%d",p);
2条答案
按热度按时间ktecyv1j1#
“字里行间”发生了什么:
(98*'b')
括号没有添加任何内容。98
和'b'
都是int
类型。int
上执行的,结果的类型是int
.9604十进制或0x 2584十六进制。char
中。进一步的问题是char
类型具有实现定义的有符号性,并且可以是有符号的或无符号的,当涉及到存储值时,它是不可移植的类型。Is char signed or unsigned by default?char
是无符号的,则转换是定义良好的,您将获得值0x 84 hex / 132 dec。char
是有符号的,则转换是实现定义的。然而,大多数具有2的补码的主流系统将仅将0x 84转换为1字节的2的补码数。即-124。char
传递给printf("%d",...
并没有很好的定义,因为%d
意味着它需要一个整数。(“default argument promotions”),如果是char
,它将被提升为int
。要可靠地打印有符号的char
整数值,请使用%hhd
。最佳做法:
char
除了用于存储字符外,永远不要用于其他用途。避免将其用于算术,尤其是位操作。uint8_t
。printf
使用正确的格式说明符。ar5n3qh52#
这是因为char是有符号的。有符号的char的值为-128至127。
因此,当你得到值0x 2584时,MSB被忽略,你实际上得到值0x 84。
现在,0x 84在二进制中是:
设置最高有效位,因此将其视为负数。
因此,如果设置了最高有效位,则我们有:
这就是你得到的。
如果你正在寻找一个值0x 2584,那么你需要使用一个16位的数据类型作为最小值,在你的平台上可能是一个普通的int。
如果你正在寻找0x 84的实际值,那么你需要使用unsigned char数据类型。类似于: