区别!和〜

时间:2016-05-12 06:44:19

标签: c logical-operators

我正在实现一个简单的状态机,如下所示:

typedef void V_V_StateFunc(void);
static V_V_StateFunc *const fpCurrentStateFunc[STATE_ELEM_SIZE]={

    &fn1,/*0*/

};

void Execute_StateMachine(const U8 bCurrent_StateIndex)
{
    if(bStateIndex == (~bInvert_StateIndex))
    {
        if(bCurrent_StateIndex <= STATE_ELEM_SIZE)
        {
            fpCurrentStateFunc[bCurrent_StateIndex]();
        }
        else
        {
            /*this should never enter*/
        }   
    }
    else
    {
            /*this should never enter*/
    }
}

void Update_State(U8 bNewIndex)
{
    bStateIndex=bNewIndex; //bStateIndex & bInvert_StateIndex are globals
    bInvert_StateIndex=(~bNewIndex);
}

在函数Execute_StateMachine()中,如果我检查bStateIndex == (~bInvert_StateIndex),则值始终为0并且不会输入if语句,但bStateIndex=0~bInvert_StateIndex=0(即{{1}这是真的)。 为什么会这样?

如果我更改0 == 0,则会输入bStateIndex == (!bInvert_StateIndex)声明。

if~之间的区别是什么?

6 个答案:

答案 0 :(得分:8)

!运算符是逻辑非运算符;例如表达式

if (!variable)

等于:

if (variable == 0)

~运算符是按位NOT 运算符;从而改变每个位的值。

 char variable = 1;           // value: 00000001
 char variable2 = ~variable;  // value: 11111110 = 254  (as noted by @Lundin; value = 11111111 11111111 11111111 11111110 and then truncated to 11111110 upon assignment to char)

答案 1 :(得分:4)

我猜它会因为整数提升而发生。 ~运算符是一个危险的运算符,因为它的操作数是整数提升的。因此,提升的操作数在此处为int类型,而不是您可能认为的U8

这意味着如果将值0xFF传递给~,结果将不是您所期望的0x00,而是0xFFFFFF00。暂时存储在已签名的int

通过始终~运算符的结果转换为预期类型来避免这种情况:

bStateIndex == (U8)(~bInvert_StateIndex)

答案 2 :(得分:2)

!会将任何非零值更改为零,并将零更改为1.

~将执行按位补码,将值中的每个位切换为0到1之间的值,但在此操作之后,许多非零的可能值仍然不为零。这意味着x~x都可以测试为真(但他们都不能测试为假)。

此外,由于整数提升发生在补码之前,因此任何无符号8位整数的比较都不可能等于另一个无符号8位整数的按位补码,因为补码的结果大于将适合8位类型。

答案 3 :(得分:1)

!是合乎逻辑的。

〜是按位。

克里斯

答案 4 :(得分:0)

!将值视为布尔值

如果它为0则为1

如果它(任何但不是0)它将是0

〜处理每个位的值(做一个2&#39; s补充)

如果它的7(111b)它将是-8(对于2&#39的补充,额外的-1)

答案 5 :(得分:0)

<强>! (逻辑NOT运算符):它返回true为false的操作。操作返回类型总是一个布尔类型。如果操作返回true,!运算符将其转换为false,反之亦然 (例如):!(1 == 2)返回TRUE,而通常(1 == 2)返回false。

〜(按位一元补码运算符):这个一元运算符处理给定操作数的二进制值(0&#39; s和1&#39; s)。它处理二进制值并返回操作数原始类型的输出。 (例如):〜(2)处理二进制值2(0010)的补码,并对(0010)执行2的补码运算,并以操作数的原始返回类型返回输出,( ie)最终输出为-3。