x&&y||z 是如何计算的?

发布于 2024-12-02 08:06:01 字数 202 浏览 1 评论 0原文

鉴于

int x=1,y=2,z;

您能解释一下为什么结果:

x && y || z 

是 1 吗?

x && y = 1
x && y || z = 1

Given

int x=1,y=2,z;

Could you explain why the result for:

x && y || z 

is 1?

x && y = 1
x && y || z = 1

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

回梦 2024-12-09 08:06:01
x && y || z 

相当于

(x && y) || z

如果x=1y=2
那么x&&y就是1 && 2 这是true && truetrue

true || z 

始终为truez 甚至没有被评估

x && y || z 

is equivalent to

(x && y) || z

if x=1 and y=2
then x&&y is 1 && 2 which is true && true which is true.

true || z 

is always true. z isn't even evaluated

狼性发作 2024-12-09 08:06:01

x && y || z => <代码>(x && y) || z => <代码>1 || z => <代码>1

x && y || z => (x && y) || z => 1 || z => 1

月朦胧 2024-12-09 08:06:01
(bool)1 = true
(bool)2 = true

未初始化的 int 指的是保存在内存中的数据,它被放置在堆栈上......并且它很少是 0x00000000,即使是,true ||假=真

(bool)1 = true
(bool)2 = true

Uninitialized int refers to data that was saved in memory, where it is placed on stack... and it rarely is 0x00000000, and even if it was, true || false = true.

你怎么这么可爱啊 2024-12-09 08:06:01

&& 运算符的优先级高于 || 运算符。例如,请参阅此运算符优先级表,第 13 和 14 号。

您的示例的计算结果为 <代码>(x && y) || z 。由于短路规则,z 永远不会被计算,因为 x && 的结果是: y 已经是 true

The && operator has higher precedence than the || operator. See, e.g., this operators precedence table, numbers 13 and 14.

Your example evaluates as (x && y) || z. Thanks to the short circuiting rule, z is never evaluated because the result of x && y is already true.

携君以终年 2024-12-09 08:06:01

你可以想到x && y || z 相当于:

int func(int x, int y, int z) {
  if (x) {
    if (y) {
      return true;
    }
  }
  if (z) {
    return true;
  }
  return false;
}

由于 xy 都固定为非零值,因此始终会命中第一个 return 语句。

在 IA32 上,没有优化 x && y || z 变为:

        movl    $1, 28(%esp)        ; store 1 in x (on stack)
        movl    $2, 24(%esp)        ; store 2 in y (on stack)
        cmpl    $0, 28(%esp)        ; compare x to 0
        je      .L6                 ; if x is 0 jump to L6
        cmpl    $0, 24(%esp)        ; compare y to 0
        jne     .L7                 ; if y is 0 jump to L7
.L6:                                ; We only get to L6 if (x && y) was false
        cmpl    $0, 20(%esp)        ; compare z to 0
        je      .L8                 ; if z is 0 jump to L8
.L7:                                ; We get to this label if either (x && y) was true
                                    ; or z was true
        movl    $1, %eax            ; copy 1 into register eax, the result
        jmp     .L9                 ; jump unconditionally to L9
.L8:                                ; We only get here if both (x && y) and z are false
        movl    $0, %eax            ; copy 0 into register eax, the result
.L9:

并且 func 变为:

        cmpl    $0, 8(%ebp)        ; compare first argument (x) with 0
        je      .L2                ; jump to L2 if it is
        cmpl    $0, 12(%ebp)       ; compare second argument (y) with 0
        je      .L2                ; jump to L2 if it is
        movl    $1, %eax           ; store 1 for the return value (via register eax)
        jmp     .L3                ; jump to L3 (done, return to caller)
.L2:                               ; if we hit this label both x and y were false
        cmpl    $0, 16(%ebp)       ; compare third argument (z) with 0
        je      .L4                ; if it is 0 jump to L4
        movl    $1, %eax           ; store 1 in register eax, which is the return value
        jmp     .L3                ; jump to L3 (return to caller)
.L4:                               ; if we get here x, y and z were all 0
        movl    $0, %eax           ; store 0 in eax to return false
.L3:

启用优化后,func() 看起来更像表达式(返回值仅从一个位置加载,尽管它是被 x86-isms 掩盖了),但是表达式 x && y || z 基本上消失了,因为编译器能够在编译时推断出它的值。

You can think of x && y || z as equivalent to:

int func(int x, int y, int z) {
  if (x) {
    if (y) {
      return true;
    }
  }
  if (z) {
    return true;
  }
  return false;
}

Since both x and y are fixed to be non-zero values the first return statement is always hit.

On IA32, without optimisation x && y || z becomes:

        movl    $1, 28(%esp)        ; store 1 in x (on stack)
        movl    $2, 24(%esp)        ; store 2 in y (on stack)
        cmpl    $0, 28(%esp)        ; compare x to 0
        je      .L6                 ; if x is 0 jump to L6
        cmpl    $0, 24(%esp)        ; compare y to 0
        jne     .L7                 ; if y is 0 jump to L7
.L6:                                ; We only get to L6 if (x && y) was false
        cmpl    $0, 20(%esp)        ; compare z to 0
        je      .L8                 ; if z is 0 jump to L8
.L7:                                ; We get to this label if either (x && y) was true
                                    ; or z was true
        movl    $1, %eax            ; copy 1 into register eax, the result
        jmp     .L9                 ; jump unconditionally to L9
.L8:                                ; We only get here if both (x && y) and z are false
        movl    $0, %eax            ; copy 0 into register eax, the result
.L9:

And func becomes:

        cmpl    $0, 8(%ebp)        ; compare first argument (x) with 0
        je      .L2                ; jump to L2 if it is
        cmpl    $0, 12(%ebp)       ; compare second argument (y) with 0
        je      .L2                ; jump to L2 if it is
        movl    $1, %eax           ; store 1 for the return value (via register eax)
        jmp     .L3                ; jump to L3 (done, return to caller)
.L2:                               ; if we hit this label both x and y were false
        cmpl    $0, 16(%ebp)       ; compare third argument (z) with 0
        je      .L4                ; if it is 0 jump to L4
        movl    $1, %eax           ; store 1 in register eax, which is the return value
        jmp     .L3                ; jump to L3 (return to caller)
.L4:                               ; if we get here x, y and z were all 0
        movl    $0, %eax           ; store 0 in eax to return false
.L3:

With optimizations enabled func() looks even more like the expression (the return value only gets loaded from one place, although it's obscured by x86-isms), but the expression x && y || z basically disappears since the compiler is able to deduce its value at compile time.

水染的天色ゝ 2024-12-09 08:06:01

因为x && y 的计算结果为 (x != 0) && (y != 0),相当于 1 && 1 结果 1。并且 1 ||无论 y 值是什么,0 都是 1。

Because x && y is evaluated as (x != 0) && (y != 0), which is equivalent with 1 && 1 resulting 1. And 1 || 0 is 1, no matter what y value is.

望她远 2024-12-09 08:06:01

&& 运算符的优先级高于 || 运算符

The && operator has higher precedence than the || operator

逆光下的微笑 2024-12-09 08:06:01

这里有两个组成部分:

  1. 优先级
  2. 短路

如果它可以帮助您记住,就数学运算符而言,||可以用加号“+”替换,加号“+”由 2 个条组成,如 &&可以用“.”代替。并且乘法优先于“+”:-)

在 C++ 和 C 中,当计算布尔表达式并且可以从某个项逻辑上推断出结果时,不会计算以下项:
假&& (expr2) 为 false 并且 expr2 不会被求值。
真实 || (expr3) 为 true 并且 expr3 不会被求值。

我希望这有帮助 =)

There are 2 components here:

  1. Precedence
  2. Short-circuitry

If it helps you remember, in terms of mathematical operators, || can be replaced with the plus sign "+", which consists of 2 bars and as && can be replaced with a "." and has the multiplication's precedence over the "+" :-)

In C++ and C, when a boolean expression is being evaluated and the result can logically be inferred from a certain term, the following terms do not get evaluated:
false && (expr2) is false AND expr2 does not get evaluated.
true || (expr3) is true AND expr3 does not get evaluated.

I hope this helps =)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文