两者之间的区别 |和 ||,或 & 和 &&

Difference between | and || , or & and &&

本文关键字:区别 两者之间      更新时间:2023-10-16

这是在 Dev-cpp C++ 5.4.2 上编写的两个简单示例C++:

float a, b, c;
if (a | b  & a | c)
   printf("x = %.2ftF = %.0fn", x, F);
else
   printf("x = %.2ftF = %.2fn", x, F);

和这个代码:

float a, b, c;
if (a || b  && a || c)
   printf("x = %.2ftF = %.0fn", x, F);
else
   printf("x = %.2ftF = %.2fn", x, F);

有人能说出我||> |&> &&之间的区别吗?第二个代码有效,但第一个代码无效。编译器给出一条错误消息:

[错误] 二进制"运算符&"类型"float"和"float"的操作数无效。

运算符|&~并行作用于单个位。 它们只能用于整数类型。 a | b对每个a位执行独立的 OR 运算,并具有相应的b位,以生成该位的结果。

运算符||&&!作用于每个完整的操作数作为单个true/false值。 可以使用隐式转换为 bool 的任何数据类型。 许多数据类型(包括float(通过隐含的!=0运算隐式转换为布尔值。

||&&也"短路"。 这意味着只要结果的值只能由第一个操作数确定,就不会计算第二个操作数。 例:

ptr && (*ptr==7) 如果ptr为零,则结果为假,没有任何通过取消引用零而导致 seg 错误的风险。

您可以将其与(int)ptr & (*ptr) . 忽略这将是一个奇怪的操作的事实,如果(int)ptr为零,整个结果将为零,因此在这种情况下,人类可能会认为您不需要第二个操作数。 但无论如何,该程序可能会同时计算两者。

您似乎对运算符的符号感到困惑。这些符号实际上分为两个不同的类别,分别是按位运算符和逻辑运算符。尽管它们使用相同的符号,但您应该将它们视为不同的运算符。这两个类别的真值表相似,但含义不同。也许这就是为什么人们使用类似的符号来表示运算符的原因。

按位运算符

~  // NOT
&  // AND
|  // OR
^  // XOR

按位运算符将其所有操作数视为二进制数字,并根据每个操作数的按位真值表进行操作。

Bit-wise Truth Table
x   y   x&y x|y x^y
0   0   0   0   0
1   0   0   1   1
0   1   0   1   1
1   1   1   1   0
x   ~x
0   1
1   0

逻辑运算符

!   // Logical NOT (negation)
&&  // Logical AND (conjunction)
||  // Logical OR  (disjunction)

逻辑运算符将其所有操作数视为布尔值,并根据运算符真值表进行操作。任何不等于0的数字都将true,否则将被false

Logical Truth Table
x   y    x&&y   x||y
F   F    F      F
T   F    F      T
F   T    F      T
T   T    T      T
x   !x
F   T
T   F

例如:

int a = 10;  // a = 0000 .... 0000 1010  <-- a 32 bits integer
             // a is not zero -> true
int b = 7;   // b = 0000 .... 0000 0111  <-- a 32 bits integer
             // b is not zero -> true

然后对于按位运算符:

assert(a & b == 2);   // 2 = 0000 .... 0000 0010  <-- every bit will & separately

对于逻辑运算符:

assert(a && b == true);  // true && true -> true

按位运算符(| (OR(、& (AND(、^ (XOR( 和 ~(补码((执行您希望它们执行的操作:它们对位执行上述操作。
关于您的编译问题,浮点数没有按位运算。

逻辑运算符(|| (OR(、&& (AND( 和 ! (NOT( 只知道值 truefalse
如果表达式的值未0,则true表达式。如果其值等于 0 false
逻辑运算符首先执行此操作。然后他们执行相应的操作:

  • ||true如果至少有一个操作数是true
  • &&true如果两个操作数都true
  • !true操作数是否false

请注意,所有逻辑运算符都是短路运算符。

浮点不支持按位运算

或者,如果您确实需要检查,则可以在使用它们之前进行投射(强烈建议(,

在此处查看如何将浮点数转换为积分,https://www.cs.tut.fi/~jkorpela/round.html