如何补充0xff不是0x00?

时间:2017-04-23 00:50:39

标签: c

我不明白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类型?

2 个答案:

答案 0 :(得分:12)

在应用~运算符之前,u8a的值会提升为int

来自C standard的第6.3.1.1节:

  

2 以下内容可用于任何可能使用intunsigned int的表达式:

     
      
  • 带有的对象或表达式   整数的整数类型(intunsigned int除外)   转化排名小于或等于int的排名   和unsigned int

  •   
  • 类型为_Boolintsigned intunsigned 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-比特价值。