espressione separata da virgola nel ciclo while in C

Non ho mai visto una frase del genere prima d’ora.

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

Ho letto online che la condizione per uscire dal ciclo è quella più a destra [! Feof (stdin)]. Quindi, a che serve l’affermazione di cui sopra mentre in contrapposizione a

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

Inoltre, mentre l’ istruzione prende un’espressione, quindi 1,1,1 è un’espressione valida in C?

I due anelli dati non hanno lo stesso significato. Utilizzando l’operatore virgola in questo modo, l’autore è stato in grado di specificare il codice che deve essere eseguito ogni iterazione, anche se il ciclo stesso non viene mai inserito. È più come un ciclo do ... while () , o qualcosa del genere:

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

L’ operatore virgola è meglio pensato come, beh, un operatore. Proprio come + è un operatore, in modo che 2 + 3 sia un’espressione (che si traduce in un valore di 5 ), così pure , è un operatore, e quindi 0, 1 è un’espressione valida (il che accade in un risultato valore di 1 , poiché quello era l’ultimo operando).

La tua modifica proposta non è equivalente. Questo è:

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

Suggerirei invece di interrompere il lavoro in una funzione:

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

Il tuo secondo esempio ha un comportamento diverso rispetto al primo e ha un bug.

Se la riga di codice:

 fgets(str, 100, stdin); 

fallisce perché era una lettura alla fine del file, quindi il resto del blocco verrà eseguito.

Nel primo set di codice, il test feof() verifica dopo il fgets() che causa la condizione EOF, quindi il blocco while() non verrà eseguito.

Poiché fgets() restituisce NULL se ha colpito EOF (e non ha letto alcun dato nel buffer), potrei codificare il ciclo come:

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

che è ancora un comportamento leggermente diverso (ne verrà stampato uno meno “>”). Se fosse importante, avrei messo un’istanza extra di quel printf() prima del ciclo.

In generale, poiché tende a creare confusione, eviterei l’operatore virgola eccetto dove è realmente, davvero necessario o dove non causerà confusione. Ad esempio, a volte viene utilizzato in clausole loop in modo non confusionario per consentire l’aggiornamento di più variabili su ogni iterazione del ciclo.

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

Le virgole all’interno di un tempo si comportano più come questo:

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