Выражение, разделенное запятыми, во время цикла в 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,1 действительное выражение в C?

Ответ 1

Две указанные циклы не имеют одинакового значения. Таким образом, используя оператор запятой, автор смог указать код, который должен выполняться на каждой итерации, даже если сам цикл никогда не вводится. Это больше похоже на цикл do ... while () или что-то вроде следующего:

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

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

Ответ 2

Оператор запятой лучше всего воспринимать как, ну, оператор. Точно так же, как + является оператором, так что 2 + 3 является выражением (которое приводит к значению 5), поэтому , является оператором и, следовательно, 0, 1 является допустимым выражением ( что приводит к значению 1, так как это был последний операнд).

Ответ 3

Ваша предлагаемая модификация не эквивалентна. Это:

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)) {
  ...
  ...
} 

Ответ 4

Второй пример отличается от первого, и имеет ошибку.

Если строка кода:

fgets(str, 100, stdin);

терпит неудачу, потому что он был прочитан в конце файла, затем будет выполнен остаток блока.

В первом наборе кода тест feof() происходит после fgets(), который вызывает условие EOF, поэтому блок while() не будет выполнен.

Так как fgets() возвращает NULL, если он попал в EOF (и не прочитал никаких данных в буфере), я мог бы закодировать цикл как:

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

    // ...
}

который все еще немного отличается от поведения (там будет меньше " > " ). Если бы это было важно, я бы поставил дополнительный экземпляр этого printf() перед циклом.

В общем, поскольку он имеет тенденцию приводить к путанице, я бы избегал оператора запятой, кроме случаев, когда это действительно действительно необходимо или где оно не вызывает путаницы. Например, он иногда используется в предложениях for в непустоте, чтобы разрешить обновление нескольких переменных на каждой итерации цикла.

Ответ 5

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

Запястье внутри какое-то время ведет себя вот так:

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

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