【问题标题】:What is the difference between && and ||? [duplicate]&& 和 || 有什么区别? [复制]
【发布时间】:2014-04-04 12:29:45
【问题描述】:

我很难理解以下程序的工作原理,请帮助我理解。

int x=2,y=0;

(一)

if(x++ && y++)
cout<<x<<y;

输出:

(ii)

if(y++ || x++)
cout<<x<<" "<<y;

输出:3 1

(iii)

if(x++||y++)
cout<<x<<" "<<y;

输出:3 0

请解释一下程序是如何工作的,以及 (ii) 和 (iii) 之间的区别。

【问题讨论】:

  • &amp;&amp; 是“和”,|| 是“或”,你有什么问题?
  • 你需要阅读一本关于逻辑运算符的书,以及它们如何快捷方式

标签: c++ operators


【解决方案1】:

您正在查看一个使用两种语言技巧的“C++ 谜题”。

首先是postincrement先使用变量的值,然后再递增变量。

所以 x++ 在表达式中的值为 2,然后 x 变为 3 y++ 在表达式中的值为 0,然后 y 变为 1

&& 是和 ||是或

两个运算符都短路了。

先看&&。

为了为真,两边都必须为真(非零)

因为它是 x++ && y++,首先 x++ 发生,并且因为它是非零(真) y++ 必须发生以确定结果是否为真。 因此 x 为 3,y 为 1。

第二种情况也是一样的。 y 为零,但为了确定 OR 是否为真, if 语句执行表达式的后半部分。

第三种情况,因为顺序相反,所以永远不会执行y++,因为

x++ ||是的++

前半部分是x++,已经是真的了,编译器也懒得去执行后半部分的测试了。

【讨论】:

    【解决方案2】:
    int x=2,y=0;
    

    if() 中的条件根据规则进行评估:

    • operator &amp;&amp; 首先计算左操作数,如果该值在逻辑上为 false,则它避免计算右操作数。例如if (x &gt; 0 &amp;&amp; k/x &lt; limit) ... 的典型用法是避免除零问题。

    • operator || 首先计算左操作数,如果该值在逻辑上为 true,则它避免计算右操作数。例如,if (overwrite_files || confirm("File existing, overwrite?")) ... 将不会在设置标志 overwrite_files 时要求确认。

    要理解以下内容,同样重要的是要注意 x++后增量 这意味着在 if( x++) x 具有旧值,但只是在下一行(甚至是同一行,但在 if() 测试之后)x 递增。


    (i)
    
    if(x++ && y++) // x=2,y=0;
     // 2 so y++ is evaluated
    cout<<x<<y;    // skipped, but now x=3,y=1; 
    Output:
    
    (ii)
    
    if(y++ || x++)    // x=2,y=0;
     //0 so x++ is evaluated
    cout<<x<<" "<<y;  // x=3,y=1;
    Output: 3 1
    
    (iii)
    
    if(x++||y++)      // x=2,y=0;
     //2 so y++ is not evaluated
    cout<<x<<" "<<y;  // x= 3,y=0;
    

    "IF" argument evaluation order?

    【讨论】:

      【解决方案3】:

      在 C++(和其他一些语言)中,&amp;&amp;|| 是条件中的逻辑运算符。 &amp;&amp; 是逻辑 AND 运算符,|| 是逻辑 OR 运算符。

      当在条件中使用这些时,条件的结果取决于这些运算符两边的内容,并且就像您只是在说单词一样被阅读。

      示例:
      if(thisNum &gt; 0 &amp;&amp; thisNum &lt; 10) 读作“如果 thisNum 大于零且小于 10,则条件为真”。因此,0 到 10 之间的任何数字都将使条件成立。

      if(thisNum &gt; 0 || thisNum &lt; 10) 读作“如果 thisNum 大于零或小于 10,则条件为真。”因此,任何数字都可以使该陈述成立,因为该陈述只有一部分必须为真才能评估为 TRUE。

      有关这些工作原理的更详细说明如下:
      OR (||) - 如果运算符的任何一方或双方都为真,则结果将为真。

      AND (&amp;&amp;) - 如果运算符的 BOTH 和 ONLY 双方都为真,则结果为真。否则为假。

      如果您通过 Google 搜索来帮助理解这些解释,包括互联网上的真值表,还有很多解释。

      至于你的例子。

      if(x++ && y++)
          cout<<x<<y;
      

      您正在执行一个if 语句,它比较xy 的值。要记住的重要一点是,您没有将这些值一起比较。在 C++ 中,非零值将评估为 TRUE,而零值将导致 FALSE。因此,您在这里检查xy 是否为TRUE,然后在比较后将它们的值增加一。由于 x = 2y = 0,我们有一个 TRUE 值和一个 FALSE 值,并且由于我们在它们之间有一个 &amp;&amp; (AND) 运算符,我们知道条件的结果是 FALSE(因为两者都不是 TRUE)并且输出被跳过。


      if(y++ || x++)
          cout<<x<<" "<<y;
      

      在这个例子中,我们正在做同样的事情,除了我们正在做一个逻辑 OR 操作而不是 AND(因为我们有 || 而不是 &amp;&amp;)。这意味着,正如我上面所说,条件的一部分必须为 TRUE 才能导致 TRUE。因为我们的值仍然是x = 2y = 0,所以我们有一个 TRUE 值和一个 FALSE 值。由于 part 为 TRUE,所以整个条件为 TRUE 并且输出发生。

      结果是3 1 而不是2 0 的原因是变量后面的++ 运算符。当++ 运算符位于变量之后时,它将在该行的其余部分发生并完成所需的操作后添加一个。所以它确实评估条件 THEN 将值增加一。


      if(x++||y++)
          cout<<x<<" "<<y;
      

      这个例子完全一样,唯一的区别是值被交换了。由于它是一个 OR (||) 运算,因此只有一部分必须为 TRUE。和以前一样,我们有一个 TRUE 值(因为 x 不为零)和一个 FALSE 值(因为 y 为零)。因此,我们得到了一个 TRUE 结果,这意味着输出没有被跳过,我们再次得到答案 3 1(因为 ++ 运算符出现在变量之后)。

      现在,说到++ 运算符。如果在第一个示例中它是:

      if(++x && ++y)
          cout<<x<<y;
      

      在这种情况下,我们会得到不同的结果。由于++ 运算符出现在变量之前,发生的第一件事是值增加了一个,然后评估条件。由于我们的新值是 x = 3 (TRUE) 和 y = 1 (也是 TRUE),我们可以得出结论,我们将得到与其他两个示例相同的结果,因为这两个值都是 TRUE(因为我们有一个 AND ( &amp;&amp;) 运算符,两个变量都必须为 TRUE 才能得到 TRUE)。

      希望这会有所帮助。

      编辑:
      其他答案之一对第二个和第三个示例提出了很好的观点。结果明智,没有区别。但是,就如何评估而言,存在差异。

      C++ 自动执行称为“短路评估”的操作。这意味着,如果它知道结果已经是 TRUE 或 FALSE,它将跳过任何评估。这意味着对于 OR 操作,如果第一部分为 TRUE,它将跳过第二部分,因为它已经知道结果必须为 TRUE。 (请记住,使用 OR 时,只有比较的一部分必须为 TRUE。)因此这意味着如果第一部分为 FALSE,那么程序也必须评估第二部分,因为它确定结果是 TRUE 还是 FALSE。
      使用 AND 操作,它会做相反的事情。如果第一部分为 FALSE,则程序知道结果必须为 FALSE,并将跳过其余部分。但是,如果第一部分为 TRUE,则程序必须评估其余部分以确定结果是 TRUE 还是 FALSE。

      就您的示例而言,这意味着第二个必须评估双方,因为第一部分的结果为 FALSE。
      在第三个示例中,第二部分被跳过,因为第一部分为 TRUE,这意味着整个条件为 TRUE。

      【讨论】:

        【解决方案4】:

        对于or(||)运算符,如果左边的表达式为true,则忽略右边的表达式。

        对于and(&&)运算符,如果左边的表达式为false,则忽略右边的表达式。

        这是您的问题的答案,是什么使 (ii) 和 (iii) 之间有区别。

        【讨论】:

          【解决方案5】:

          在输出(ii)中,它是:

          当编译器评估y时,y等于0,所以语句是false,它正在评估另一个成员x,它等于2,所以语句是true。然后它操作增量运算符。

          在输出(iii)中,它是:

          当编译器计算 x 时,x 等于 2 所以语句是 true 因为条件的运算符是 || 它不会计算另一个表达式,所以y++ 被忽略。只有x 会增加。

          【讨论】:

            猜你喜欢
            • 2015-11-23
            • 2013-02-13
            • 2011-04-26
            • 2016-09-24
            • 1970-01-01
            • 1970-01-01
            • 2010-12-11
            • 2023-03-10
            相关资源
            最近更新 更多