我很难理解逻辑运算符在 C 中的工作原理。我已经了解位级运算符的工作原理,而且我还知道逻辑运算符将非零参数视为表示 TRUE,将零参数视为表示 FALSE
但是假设我们有 0x65 && 0x55。我不明白这个操作为什么以及如何给出 0x01。
我试图将其转换为二进制,但我无法弄清楚它是如何工作的
我很难理解逻辑运算符在 C 中的工作原理。我已经了解位级运算符的工作原理,而且我还知道逻辑运算符将非零参数视为表示 TRUE,将零参数视为表示 FALSE
但是假设我们有 0x65 && 0x55。我不明白这个操作为什么以及如何给出 0x01。
我试图将其转换为二进制,但我无法弄清楚它是如何工作的
&&操作员:
如果左操作数和右操作数都不同于0它的求值结果,1否则它的求值结果为0。
如果左操作数为0,则不计算右操作数,结果为0。
0x65 && 0x55被评估为1。
The&&是一个逻辑AND(而不是&,它是按位 AND的)。它只关心它的操作数是零/非零值。零被认为是false,而非零被视为true。
在您的情况下,两个操作数都是非零的,因此它们被视为true,导致结果也是true如此。C 表示true为1,说明您的操作的总体结果。
如果将操作更改为&,您将获得按位操作。0x65 & 0x55会给你一个结果0x45。
C 和 C++ 具有三个逻辑运算符:逻辑非(!)、逻辑与(&&)和逻辑或(||)。对于逻辑运算符,0是 false 并且任何不为零的都是 true。此真值表说明了每个逻辑运算符的工作原理(将1用于 for true):
p q p && q p || q
= = ====== ======
1 1 1 1
1 0 0 1
0 1 0 1
0 0 0 0
真值表!如下:
p !p
= ===
1 0
0 1
对于您的具体情况:
0x65 && 0x55
由于整个表达式的操作数0x65和0x55求值都求值为并因此扩展为,这适用于但链接线程中的其他答案也解释了它之前的应用方式。truetrue1c99c99
&&是逻辑运算符,而不是位运算符。0x65 和 0x55 都为真,因此结果为真数。0x01 是一个真实的数字。
二进制表示仅对按位运算起作用。表达式0x65 & 0x55等于0x45。
任何计算结果为 0 的表达式都是假的。任何非零的表达式都是真的。所以 0x65 和 0x55 都是真的。
0x65 && 0x55
=> 真 && 真 => 真
我试图将其转换为二进制
这可能妨碍了理解。和 的确切位模式0x65与0x55所需结果完全无关,重要的是它们都是非零的。您可以考虑a = (0x65 && 0x55)等效于以下内容:
if (0x65 != 0) goto condition_false;
if (0x55 != 0) goto condition_false;
a = 1;
goto condition_end;
condition_false:
a = 0;
condition_end:
给定的实现可能能够发出比这更有效的代码(尽管我已经看到了很多发出的代码,每个代码if ... goto都是程序集中的测试和分支)。更高效的代码可能涉及一些位操作以避免分支。就此而言,在这个涉及常量的示例中,编译器可能只会发出a = 1;.
不过,运算符的含义&&是在条件执行方面。例如,如果您编写f() && g(),则保证当f返回 false 值时,g不会调用。如果可以通过位旋转获得相同的结果,那么这可能是性能的奖励。
C 将大于零的值定义为“真”。由于 0x65 和 0x55 都符合此条件,因此结果也是 True - 在输出中为 1 - 或者在十六进制表示法中为 0x01。
您的代码的另一种编写方式是:
返回(0x65 为真)和(0x55 为真);
正如您所说,逻辑运算符将非零参数视为表示
(0x65 && 0x55) is equal as (0x65 > 0) && (0x55 > 0)
0x65 > 0 get true and 0x55 > 0 get true as well
So (0x65 && 0x55) is equal true && true = 1