【问题标题】:Multiple conditions in a C 'for' loopC“for”循环中的多个条件
【发布时间】:2013-05-27 09:04:16
【问题描述】:

我遇到了这段代码。我一般使用 '&&' 或 '||'在for 循环中分隔多个条件,但此代码使用逗号来做到这一点。

令人惊讶的是,如果我更改条件的顺序,输出会发生变化。

#include<stdio.h>

int main() {
    int i, j=2;

    for(i=0; j>=0,i<=5; i++)
    {
         printf("%d ", i+j);
         j--;
    }
    return 0;
}

输出 = 2 2 2 2 2 2

#include<stdio.h>

int main(){
    int i, j=2;

    for(i=0; i<=5,j>=0; i++)
    {
         printf("%d ", i+j);
         j--;
    }
    return 0;
}

输出 = 2 2 2

有人可以解释原因吗?它似乎只检查最后一个逗号分隔的条件。

【问题讨论】:

  • 错误代码。你说得对;多个条件应使用 && 或 || 连接。
  • 五个答案,每个人都从字面上理解这个问题并解释逗号的作用,没有一个答案表明这是可怕的,可怕的破坏。

标签: c for-loop


【解决方案1】:

Wikipedia 告诉逗号运算符的作用:

"在 C 和 C++ 编程语言中,逗号运算符(由标记 , 表示)是一个二元运算符,它计算其第一个操作数并丢弃结果,然后计算第二个操作数并返回此值(和类型)。”

【讨论】:

  • -1 引用维基百科并不能回答问题,这不是逗号的作用,而是为什么在这里使用它。
  • @Caleb,老实说,我不相信这个问题会问为什么。因为它说:“令人惊讶的是,如果我改变条件的顺序,输出就会改变”。因此引用答案。
【解决方案2】:

完成克罗克先生的回答,小心 ++ 或 -- 运算符,或者我不知道其他运算符。 它们会影响循环。例如,我在一门课程中看到了与此类似的代码:

for(int i=0; i++*i<-1, i<3; printf(" %d", i));

结果将是 $1 2$。所以第一条语句影响了循环,而下面的结果是很多零。

for(int i=0; i<3; printf(" %d", i));

【讨论】:

    【解决方案3】:

    C 中有一个运算符叫做逗号运算符。它按顺序执行每个表达式并返回最后一条语句的值。它也是sequence point,这意味着每个表达式都保证在系列中的下一个表达式执行之前完全按顺序执行,类似于&amp;&amp;||

    【讨论】:

    • 这使得它在这种情况下毫无用处——他的第一个条件检查没有任何用处。
    • @EricPostpischil 对不起,表达。嘘。
    【解决方案4】:

    当然你一开始说的没错,而Clogical operator&amp;&amp;||是你通常用来“连接”条件(可以判断为真或假的表达式);正如其他用户所解释的那样,逗号运算符不是逻辑运算符,并且在该示例中使用它没有意义。您可以使用它,例如在 for 本身中“连接”语句:您可以使用 i 一起初始化和更新 j;或在other ways 中使用逗号运算符

    #include <stdio.h>
    
    int main(void)  // as std wants
    {
      int i, j;
    
      // init both i and j; condition, we suppose && is the "original"
      // intention; update i and j
      for(i=0, j=2; j>=0 && i<=5; i++, j--)
      {
           printf("%d ", i+j);
      }
      return 0;        
    }
    

    【讨论】:

      【解决方案5】:

      逗号运算符计算其所有操作数并产生最后一个的值。所以基本上无论你写第一个哪个条件,它都会被忽略,而第二个只有一个重要。

      for (i = 0; j >= 0, i <= 5; i++)
      

      因此等价于

      for (i = 0; i <= 5; i++)
      

      这可能是也可能不是代码作者的意图,这取决于他的意图 - 我希望这不是生产代码,因为如果编写此代码的程序员想要表达条件之间的 AND 关系,那么这是不正确,应该使用 &amp;&amp; 运算符。

      【讨论】:

      • 这里的重点是有问题的代码不正确。
      • @Caleb 在什么意义上?我想我明白了您的建议,我只是不确定它是否可以或应该按原样包含在答案中。
      • 不可能是作者想要的,因为它没有意义。我不会相信这个作者的任何代码。
      • 第一个条件 j&gt;=0 被求值,但从不使用结果。只要 i 不超过 5,循环就会继续,即使 j 小于 0。它看起来就像循环将在 j = -1 处停止,但它不会。除了破碎之外,很难称之为任何东西。
      • 是的,它不是生产代码。我只是在修改我的 C 基础知识,并遇到了一个网站,其中有一些我遇到的多项选择题。感谢您的回复。
      【解决方案6】:

      不要使用此代码;写它的人显然对语言有根本的误解,并且不值得信赖。表达式:

      j >= 0, i <= 5
      

      计算“j >= 0”,然后将其丢弃,不做任何处理。然后它评估“i 可以在循环条件中有意义地使用;你会经常看到类似的东西:

      for (i = 0, j = 0; i < 10; ++i, ++j) . . .
      

      其中逗号用于隐藏额外的初始化和增量语句。但是显示的代码并没有这样做,或者其他任何有意义的事情。

      【讨论】:

        【解决方案7】:

        逗号表达式采用last(例如最右边)表达式的值。

        所以在你的第一个循环中,唯一的控制表达式是i&lt;=5;并且j&gt;=0 被忽略。

        在第二个循环中,j&gt;=0 控制循环,i&lt;=5 被忽略。


        至于原因...没有理由。这段代码只是错误。逗号表达式的第一部分除了让程序员感到困惑之外,什么都不做。如果一个认真的程序员写了这个,他们应该为自己感到羞耻并撤销他们的键盘。

        【讨论】:

          猜你喜欢
          • 2016-08-03
          • 2013-09-19
          • 1970-01-01
          • 2013-01-27
          • 2012-08-04
          • 2011-09-02
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多