开发者

comma separated expression in while loop in C

I never saw such a while statement before.

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

I r开发者_StackOverflowead online, that the condition to come out of while loop is the rightmost one [ !feof(stdin) ]. Then, what is the use of the above while statement as opposed to

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

Also, while statement takes an expression, so is 1,1,1 a valid expression in C?


The two loops given don't have the same meaning. By using the comma operator in that way, the author was able to specify code that should be executed every iteration, even if the loop itself is never entered. It's more like a do ... while () loop, or something like the following:

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

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


The comma operator is best thought of as, well, an operator. Just like + is an operator, so that 2 + 3 is an expression (which happens to result in a value of 5), so too , is an operator, and thus 0, 1 is a valid expression (which happens to result in a value of 1, since that was the last operand).


Your proposed modification is not equivalent. This is:

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

I would suggest instead breaking off the work into a function:

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

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


Your second example has different behavior than the first, and has a bug.

If the line of code:

fgets(str, 100, stdin);

fails because it was a read at the end of the file, then the remainder of the block will be executed.

In the first set of code, the feof() test occurs after the fgets() that causes the EOF condition, so the while() block will not be executed.

Since fgets() returns NULL if it has hit EOF (and hasn't read any data into the buffer), I might code the loop as:

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

    // ...
}

which is still slightly different behavior (there will be one fewer "> " printed). If that were important, I'd put an extra instance of that printf() before the loop.

In general, since it tends to cause confusion, I'd avoid the comma operator except where it's really, really needed or where it won't cause confusion. For example, it's sometimes used in for loop clauses in a non-confusing manner to allow several variables to be updated on each loop iteration.


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

Commas inside a while behaves more like this:

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

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜