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

5 ответов

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

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


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

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


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

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

fgets(str, 100, stdin);

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

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

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

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

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

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


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

licensed under cc by-sa 3.0 with attribution.