我不明白0xff的补码是怎么不是0x00。 这是代码:
uint8_t u8a;
u8a = 0xff;
printf( "%d\n", ~u8a );
if( ~u8a == 0x00 )
printf( "Equal\n" );
else
printf( "Not Equal\n" );
printf
语句显示“-256”和“不等于”。
我的理解中缺少什么?
如果它被提升为int
类型,为什么会将其提升为int
类型?
答案 0 :(得分:12)
在应用~
运算符之前,u8a
的值会提升为int
。
来自C standard的第6.3.1.1节:
2 以下内容可用于任何可能使用
int
或unsigned int
的表达式:
带有的对象或表达式 整数的整数类型(
int
或unsigned int
除外) 转化排名小于或等于int
的排名 和unsigned int
。类型为
_Bool
,int
,signed int
或unsigned int
的位字段。如果
int
可以代表所有的值 原始类型(受宽度限制,适用于 位字段),该值转换为int
;否则,它 转换为unsigned int
。这些被称为 整数促销。所有其他类型均未被整数促销更改。
由于uint8_t
的排名低于int
,并且因为所有可能的值都适合int
,所以涉及此类型的任何表达式都将始终提升为int
按照标准。
因此,假设int
为4个字节,则值0xff
将提升为0x000000ff
。将~
运算符应用于0xffffff00
。
因此,当您使用%d
运算符打印此值时,它(正确地)被解释为-256。同样,此值与0x00
不同,因此"不等于"打印出来。
要获得您期望的结果,您需要将~
运算符的结果转换回uint8_t
。此外,您应该使用PRIu8
格式说明符宏printf
来准确反映您传入的值。
printf( "%" PRIu8 "\n", (uint8_t)~u8a );
if( (uint8_t)~u8a == 0x00 )
printf( "Equal\n" );
else
printf( "Not Equal\n" );
结果:
0
Equal
答案 1 :(得分:-1)
在C中,所有算术都使用不小于int
的值(参见here)。这意味着当您执行~
操作时,8位值将扩展为32位。
如果要将结果分配给变量,它会使用正确的变量大小保存它,但是由于您在if
语句中使用printf
函数对其进行评估,因此它使用32-比特价值。