在while循环条件中分配值

Jos*_*sip 13 c initialization while-loop

我在维基百科上找到了这段代码.

#include <stdio.h>

int main(void)
{
  int c;

  while (c = getchar(), c != EOF && c != 'x')
  {
    switch (c)
      {
      case '\n':
      case '\r':
        printf ("Newline\n");
        break;
      default:
        printf ("%c",c);
      }
  }
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我很好奇表达用作while循环的条件:

while (c = getchar(), c != EOF && c != 'x')
Run Code Online (Sandbox Code Playgroud)

它的作用非常明显,但我以前从未见过这种结构.这是特定于while循环吗?如果没有,解析器/编译器如何确定逗号分隔表达式的哪一侧为while循环返回布尔值?

Pau*_*xon 17

逗号运算符是评价其第一操作数和丢弃结果的二进制运算符,它然后评估第二个操作数,并返回该值.

它也是一个"序列点",这意味着所有副作用将在下一部分代码执行之前计算出来.

  • 只是添加,因为它可能不是很明显 - "="运算符更新变量c的值的效果在此上下文中被视为"副作用". (3认同)

pax*_*blo 11

逗号运算符是一个奇怪的野兽,直到你理解它,并不是特定的while.

表达方式:

exp1, exp2
Run Code Online (Sandbox Code Playgroud)

评估exp1然后评估exp2并返回exp2.

你经常看到它,虽然你可能没有意识到:

for (i = j = 0; i < 100; i++, j += 2)
Run Code Online (Sandbox Code Playgroud)

你实际上没有使用返回值,"i++, j += 2"但它仍然存在.逗号运算符计算两个位以修改ij.

你可以在任何可以使用普通表达式的地方使用它(例如,函数调用中的逗号不是逗号运算符),并且它在编写紧凑的源代码时非常有用,如果这是你喜欢的.通过这种方式,它是家庭的一部分,允许这样的事情:

while ((c= getchar()) != EOF) {...}
i = j = k = 0;
Run Code Online (Sandbox Code Playgroud)

等等.

对于您的具体示例:

while (c = getchar(), c != EOF && c != 'x')
Run Code Online (Sandbox Code Playgroud)

发生以下情况:

  • c = getchar() 完全执行(逗号运算符是序列点).
  • c != EOF && c != 'x' 被执行.
  • 逗号运算符抛弃第一个值(c)并"返回"第二个值.
  • while用于返回值来控制循环的用途.