逗号在C中的while循环中分隔表达式

时间:2010-12-06 07:10:34

标签: c

我之前从未见过这样的 while 声明。

while(printf("> "), fgets(str, 100, stdin), !feof(stdin)) {
..
..
}

我在网上看到,来自while循环的条件是最右边的[!feof(stdin)]。 然后,使用上面的 while 语句而不是

while(!feof(stdin))
{
       printf("> ");
       fgets(str, 100, stdin);
       ...
       ...
}

另外, while 语句是一个表达式,1,1是一个有效的表达式吗?

5 个答案:

答案 0 :(得分:17)

给出的两个循环不具有相同的含义。通过以这种方式使用逗号运算符,作者能够指定每次迭代应执行的代码,即使从未输入循环本身。它更像是do ... while ()循环,或类似以下内容:

 printf("> ");
 fgets(str, 100, stdin);
 while(!feof(stdin)) {
    ..
    ..

    printf("> ");
    fgets(str, 100, stdin);
 }

答案 1 :(得分:4)

comma operator最好被认为是运营商。就像+是一个运算符一样,2 + 3是一个表达式(恰好产生5的值),因此,也是运算符,因此0, 1是一个有效的表达式(恰好导致值为1,因为那是最后一个操作数)。

答案 2 :(得分:2)

您提议的修改不等同。这是:

while (1) {
  printf("> ");
  fgets(str, 100, stdin);
  if (feof(stdin)) { break; }
  ...
  ...
}

我建议将工作分解为函数:

int get_input(char* buffer, int size) {
  printf("> ");
  fgets(buffer, size, stdin);
  return !feof(stdin);
}

while (get_input(str, 100)) {
  ...
  ...
} 

答案 3 :(得分:2)

您的第二个示例与第一个示例的行为不同,并且有一个错误。

如果代码行:

fgets(str, 100, stdin);

失败,因为它是在文件末尾的读取,然后将执行块的其余部分。

在第一组代码中,feof()测试发生在导致EOF条件的fgets()之后,因此while()块将不会被执行。

由于fgets()如果已经命中了EOF(并且没有将任何数据读入缓冲区),则返回NULL,我可能将循环编码为:

while (fgets(str, 100, stdin)) {
    printf("> ");

    // ...
}

这仍然是略有不同的行为(将会少一个“>”打印)。如果这很重要,我会在循环之前添加printf()的额外实例。

一般情况下,由于它往往会导致混淆,我会避免使用逗号运算符,除非它真的,真正需要或不会引起混淆。例如,它有时在for循环子句中以非混淆的方式使用,以允许在每次循环迭代时更新多个变量。

答案 4 :(得分:1)

while(printf("> "), fgets(str, 100, stdin), !feof(stdin)) {
..
..
}

Commas在一段时间内表现得更像这样:

int feof_wrapper(FILE * stream)
{
   printf("> ");
   fgets(str, 100, stream);
   return feof(stream);
}

while(!feof_wrapper(stdin)) {
..
..
}