我正在实现一个简单的状态机,如下所示:
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
和~
之间的区别是什么?
答案 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。