【问题标题】:Is the code "while(condition);" valid and what does it mean?是代码“while(condition);”有效,这是什么意思?
【发布时间】:2011-05-06 17:22:20
【问题描述】:

我们可以在 C 编程中使用像 while(condition); 这样的分号吗? 如果while(condition); 有效,那是什么意思?

【问题讨论】:

  • 是的,很遗憾,我在第一次编程课上浪费了几个小时后才发现。
  • 条件无关紧要,它们都评估为真或假。诚然,事情可以在下面讨论的条件内完成,但这个问题似乎主要是关于与循环相关的语法和/或行为。
  • 是的,它是有效的。否则你会怎么写一个 do-while 循环?

标签: c while-loop


【解决方案1】:

代码while(condition); 是完全有效的代码,尽管它的用途很少。我认为condition 是一个变量,而不是一个函数——其他人在这里讨论函数condition

while(condition); 的一个用途可能是在等待 signal 时阻止,例如SIGHUP,其中信号处理程序更改变量condition。但是,这通常不是等待信号的最佳方式。通常会在循环中使用sleep,即while(condition) { sleep(1); }

没有任何sleep 意味着循环将在此期间持续处理,并且可能会浪费处理周期。除非进程管理其资源(甚至在那里......),否则我认为这仅适用于需要在小于可用sleep 命令粒度的间隔内中断循环的情况(即睡眠由第二,但您需要在以亚秒级响应时间执行外观之后的代码)。话虽如此,在性能方面,阻塞管道或套接字可能比信号更可取——尽管我没有任何经验数据来支持它,我怀疑性能可能会因平台而有很大差异。

可以condition 被同一进程的并行线程修改,但我认为应该更喜欢通过互斥锁或信号量来做到这一点(即condition 可能不仅仅是一个简单的变量)。

我希望这会有所帮助,或者至少值得深思!

【讨论】:

    【解决方案2】:

    我总是这样写:

    while (condition())
        continue;
    

    所以很明显这不是一个错误。正如其他人所说,只有在 condition() 有副作用时才有意义。

    【讨论】:

    • 没有副作用的条件如果检查 volatile 变量也有意义,此时它只是等待异步事件。
    【解决方案3】:

    这意味着循环的主体是空的。通常,当条件本身执行某些工作时会使用此模式。

    例如,这个循环可以复制条件内的字节:

    while ( '\0' != (*pt++ = *ps++))
                ;
    

    如果您使用分号,最好将其放在单独的行上,这样看起来就不会出错。我个人倾向于使用空大括号——{},有时还会使用空块的注释。

    编辑:

    在第二条评论中,汤姆安德森指出了对单独分号的改进。 Google's C++ style guide 推荐这个或 {}。

    while ( '\0' != (*pt++ = *ps++))
                continue;
    

    【讨论】:

    • +1 用于解释当循环条件有副作用时它很有用。 -100000 将分号放在单独的行上!可怕! FWIW,comp.lang.java.programmer/comp.lang.c 上正在进行一场关于如何设计这个可能感兴趣的结构的样式的好消息。
    • while (condition) continue;(在 continue 和/或大括号之前有一个换行符,根据您的喜好)已被建议为一种可读且合理的非人为形式。
    • 正如我所提到的,我使用大括号而不是分号。 K&R 确实在单独的一行上使用了分号。 “继续”模式似乎是一种改进。我不认为小东西上的激烈争吵是有价值的。
    • 我们能否针对逆转的情况再进行一场激烈的战争?我非常喜欢'while ((*pt++ = *ps++) != '\0'),但这就是火焰战争的美妙之处。 (FWIW:我更喜欢下一行的分号。)
    • 我正在考虑添加一个类似的示例,但可能具有不同的风格。抛开风格不谈,这是空的“while”主体的常见用法的一个很好的例子。
    【解决方案4】:

    它只是一个没有执行主体的while循环

    while(condition);
    

    相同
    while(condition)
    {
        }
    

    【讨论】:

    • 我们有一个编码标准在工作,它总是要求我们使用大括号,即使是简单的 if/while/for 语句。这可能是一个很好的理由;第二个陈述要清楚得多。
    【解决方案5】:

    这里没有描述的另一种用法:

    do
    {
       if(out_of_memory)
         break;
    
       if(file_does_not_exist)
         break;
    
       return ok;
    
    } while(0);
    
    return error;
    

    这使您可以避免多次返回调用或 goto 语句。

    【讨论】:

    • 我认为这是一种反模式。看在上帝的份上,只需使用 return,甚至转到更好的构造。不要将 goto 伪装成结构化的代码。
    【解决方案6】:

    绝对正确。这意味着在循环中什么都不做,只是轮询条件。在嵌入式系统代码中很常见。

    【讨论】:

      【解决方案7】:

      理解这一点的关键是“C”中while循环的语法如下:

      while (condition) statement
      

      statement 可以是任何有效的“C”语句。以下是所有有效的“C”语句

      { statements } // a block statement that can group other statements
      
      statement; // a single statement terminated by a ;
      
      ; // a null statement terminated by a ;
      

      所以,根据 while 循环 的规则,只要 condition true。这很有用,因为它相当于一个忙碌的等待,直到 条件 变为 false。等待不是一个好方法,但仍然有用。例如,如果您想等待另一个线程(或信号处理程序)在继续前进之前将变量设置为某个值,则可以使用此构造。

      【讨论】:

        【解决方案8】:

        因为条件实际上可能有副作用,所以允许这样的构造。考虑以下几点:

        while (*p && *p++ != ' ');
        

        这会将p 指针前进到第一个空格字符。

        您甚至可以使用逗号运算符在条件中包含普通语句:

        while (do_something(), do_something_else(), i < n);
        

        因为与逗号运算符连接的语句计算为最右边的语句,在这种情况下为i &lt; n,以上等同于:

        do {
          do_something();
          do_something_else();
        } while (i < n);
        

        【讨论】:

          【解决方案9】:

          这意味着继续检查条件直到它评估为false

          【讨论】:

            【解决方案10】:

            是的,你可以。这只是意味着 while 循环将继续循环,直到 condition 为假。例如:

            #include<stdio.h>
            
            int x = 10;
            int func()
            {
              printf("%d\n", x);
              return --x;
            }
            
            int main()
            {
              while(func());
              return 0;
            }
            

            但通常人们不会这样做,因为将逻辑放在循环体中会更有意义。

            编辑:

            有一些这样的例子在使用,例如,复制一个以 null 结尾的字符串:

            char dest[256];
            char *src = "abcdefghijklmnopqrstuvwxyz";
            while(*(dest++) = *(src++));
            

            【讨论】:

            • 虽然这可能是一个空体循环的例子,但它也是一个设计不良的代码的例子(因此不太有用恕我直言)。
            • @Lee-Man - 确切地说,我什至指出这不是一个好主意,逻辑属于循环体。我的第二个例子要好一些,只是因为它是一种比较常见的模式,大多数 C 程序员会立即识别它。
            【解决方案11】:

            它将继续评估条件,直到它为假。这是一个没有主体的循环。

            程序员经常在分号前加一个空格,即

            while(condition) ;
            

            或空括号:

            while(condition) {}
            

            显示空的身体是故意的,而不仅仅是一个错字。如果您正在阅读一些现有的源代码并想知道为什么那里有一个空循环,您还应该阅读接下来的几行以查看分号是否真的应该存在(即,接下来的几行看起来像循环与否?)。

            【讨论】:

              【解决方案12】:
              while (condition);
              

              相同
              while (condition) 
              {
              }
              

              可用于等待循环,例如:

              while (!isLightGreen()); // waits until isLightGreen() returns true
              go();
              

              【讨论】:

              • 需要注意的是,这会导致执行不断循环并检查条件,所以进程/线程实际上并没有等待而是一直使用CPU时间。
              • @GCATNM:是的,但有时(例如,控制器应用程序等待信号)除了等待之外真的没有什么可做的。如果这不是所需的行为,则循环体应允许线程/任务切换(例如使用睡眠)或使用另一种等待机制(例如回调函数、中断);但这不是问题...
              • @Brian 还有忙等待 :)
              • Condition 也可能包含 action,毕竟这是一个任意的表达式求值。所以这个整个讨论是荒谬的恕我直言。所有 bla-bla bout 处理器负载、自旋锁定、阻塞、shmocking 等。
              • 无论条件阻塞与否,注释都为真。如果它阻塞,则名称选择不当,并且循环是不必要的。如果它没有阻塞,则该示例选择不当——初学者最常使用它作为反模式。
              【解决方案13】:

              如果条件的评估没有修改影响条件本身的值,while(condition); 是一个空的无限循环,这意味着它永远不会终止(除了消耗 CPU 时间之外永远不会做任何事情)。

              【讨论】:

              • 除非您正在等待来自另一个线程或寄存器的内容进行更改(或类似的内容)。我认为你过度概括了它。
              • 在单线程程序中是这样,但是条件的值可以被其他线程改变。
              • 如果条件为假,则根本不会循环。
              【解决方案14】:

              是的,没错。它会循环条件直到它为假。

              while ( condition() );
              

              【讨论】:

                【解决方案15】:

                while() 是一个循环。您可能正在寻找一个“do-while”循环。 Do-while 循环以这种格式运行:

                do
                {
                    // Your process
                    // When something goes wrong or you wish to terminate the loop, set condition to 0 or false
                } while(condition);
                

                然而,您上面列出的那个是一个空循环。

                while() 循环的工作方式几乎相同;根本没有“做”部分。

                祝你好运!

                【讨论】:

                  【解决方案16】:

                  这只是一个空循环。如果您解释一下条件是什么,将会有所帮助。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 2016-03-28
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多