按位或与逻辑或

Bitwise OR vs Logical OR

在 C 中,是

if((d[i] != 1) && (d[i] != 2))

if(d[i] != (1 | 2))

为什么是

if(d[i] != (1 || 2))

被编译器拒绝?

如果我想检查很多常量,有没有办法简化第一个语句?即检查 d[i] 是否为 1,2,3,4,5。所以如果 d[i] 是例如,我会拒绝它。 6.

1) No. 1 | 23(你可以通过打印出来测试)所以 if(d[i] != (1 | 2))if(d[i] != 3)[=19= 做同样的事情]

2) 不应该。 1 || 2 应该是 1,所以 if(d[i] != (1 || 2)) 应该和 if(d[i] != 1) 做同样的事情。如果你为此得到一个错误,那么我怀疑那是因为你正在使用编译器的 "treat warnings as errors" 选项(-Werror 用于 gcc 或 clang)。

更新答案

is there a way to simplify the first statement, if I want to check for many constants? which to say check whether d[i] is 1,2,3,4,5. So I would reject it if d[i] is e.g. 6.

绝对:

if ((d[i] >= 1) && (d[i] <= 5))

看,其实并没有那么复杂。编译器可能会对此进行优化。

就其价值而言,检测 x in [1..5] 实际上是一个很难用位掩码逻辑优化的表达式。如果您为整数范围的低三位写出卡诺图,则不会显示任何有用信息。我可以将其简化为最好的是:

if (4 >= (unsigned)(d[i]-1))

我在 Visual Studio 中编译了一些代码,以查看它如何在零售版本中优化 (x >= 1) && (x <= 5)。它的优化与上面的表达式完全一样。即:((x-1) < 4)

在8位数字中,1表示为:

0000 0001

2表示为

0000 0010

这两个数字的按位或结果

0000 0011

3

因此,

d[i] != (1 | 2) 等同于 d[i] != 3。也就是说,显然,与 (d[i] != 1) && (d[i] != 2).

非常不同
if(d[i] != (1 || 2))

不应该被编译器拒绝。该语句等效于:

if(d[i] != 1)

条件一.

if((d[i] != 1) && (d[i] != 2))

这将检查条件 d[i] !=1d[i]!=2 即如果 d[i] 不等于 1 和 2 条件将 运行.
如果第一个条件失败,它将不会检查 d[i] != 2.

条件二.

if(d[i] != (1 | 2))

此处 (1 | 2) 将 return 3.

1==>        0001  
2==>        0010   
           ------
Bitwise OR= 0011 ==> result will be 3 

表示它将检查 d[i] !=3

条件三.

if(d[i] != (1 || 2))

1||2 会 return TRUE 所以它会给你错误。

因为 d[i] 具有整数值,而您正试图将其与导致错误的布尔值进行比较。

要根据多个值检查变量,必须每次都指定变量,如 a == 1 || a == 2 || ...a != 1 && a != 2 && ...

a != (1 || 2 ||..)那样只指定常量不会得到预期的结果,因为1 || 2被扩展为1(参考Short circuit evaluation)。编译器可能会发出警告,因为它看起来不太可能(意外)构造。

不,它们不一样。 if((d[i] != 1) && (d[i] != 2))无法进一步简化。

让我们来看看其他代码。 if(d[i] != (1 | 2)) 它首先执行 (1|2),结果是 3。然后进行比较if(d[i] != 3),你肯定不想这样吧?

现在在 if(d[i] != (1 || 2)) 中,完成的第一个操作是 (1 || 2) 它导致 true (类型为布尔值)并且由于类型不匹配,您的语句实际上变为 if(d[i] != true) //comparing int to boolean编译器 警告 反对它。

如果要检查多个数字,请使用 for 循环和数组作为

int constants[]=  {1,2,3,4,5}; //constants to check against
int ar_size = sizeof(constants) / sizeof(constants[0]); //ar_size will adjust to array size, you can use vector for simplification


bool inArray = false;  //default is false.
for (int it_i = 0; i < ar_size; it_i++)
{
    if (constants[it_i] == d[i]) //Checking is done here
        inArray = true;
}
//just use inArray to find if element was in constants[] or not
if (inArray)
{
    //code
}

d[i]为整数值,(1 || 2)的结果为boolean true if(d[i] != (1 || 2)) 中布尔值和整数值的比较对编译器没有意义。

在 C if((d[i] != 1) && (d[i] != 2)) 中,当且仅当 d[i] 既不等于 1 也不 d[i] 等于 2(两个条件必须同时满足)时,此条件为真。

if(d[i] != (1 | 2)) 不同,因为这意味着当且仅当 d[i] 不等于 1 和 2 的按位或,即 0001|0010=0011 (3 ).所以间接地检查 d[i] 是否不等于 3.

if(d[i] != (1 || 2)) 未被编译器拒绝尝试 gcc <filename.c> 并执行 a.out 文件。这将检查 d[i] 与 1 和 2 的异或,即 1.So 间接此条件评估是否 d[i] 不等于 1.

关于您的最后一个问题,可以通过以下检查轻松评估您的状况: if((d[i]>=1) && (d[i]<=5)) 其中 1 是初始值,5 是支票的最终值。