按位或与逻辑或
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 | 2
是 3
(你可以通过打印出来测试)所以 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] !=1
和 d[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 是支票的最终值。
在 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 | 2
是 3
(你可以通过打印出来测试)所以 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] !=1
和 d[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 是支票的最终值。