2010-12-06 18 views
11

Nunca vi tal mientras que la declaración antes.expresión separada por comas en el ciclo while en C

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

He leído en línea, que la condición para salir del lazo while es la más a la derecha [! Feof (stdin)]. Entonces, ¿cuál es el uso de los anteriores mientras declaración en oposición a

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

Además, mientras afirmación adquiere una expresión, por lo que es 1,1,1 una expresión válida en C?

Respuesta

17

Los dos bucles dados no tienen el mismo significado. Al usar el operador de coma de esa manera, el autor pudo especificar el código que se debe ejecutar en cada iteración, incluso si el bucle nunca se ingresa. Es más como un bucle do ... while(), o algo como lo siguiente:

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

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

El comma operator es mejor pensado como, bueno, un operador. Al igual que + es un operador, por lo que 2 + 3 es una expresión (que resulta en un valor de 5), también , es un operador, y por lo tanto 0, 1 es una expresión válida (que resulta en un valor de 1, ya que ese fue el último operando).

2

Su modificación propuesta no es equivalente. Esto es:

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

Yo sugeriría lugar la ruptura de la obra en una función:

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

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

Su segundo ejemplo tiene un comportamiento diferente de la primera, y tiene un error.

Si la línea de código:

fgets(str, 100, stdin); 

falla porque se trataba de una lectura al final del archivo, a continuación, se ejecutará el resto del bloque.

En el primer conjunto de código, la prueba feof() ocurre después de la fgets() que causa la condición EOF, por lo que el bloque while() no se ejecutará.

Desde fgets() devuelve NULL si se ha golpeado EOF (y no ha leído los datos en el búfer), podría codificar el bucle como:

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

    // ... 
} 

que todavía es un comportamiento ligeramente diferente (no habrá uno menos ">" impreso). Si eso fuera importante, pondría una instancia adicional de ese printf() antes del ciclo.

En general, ya que tiende a causar confusión, evitaría al operador de coma excepto donde realmente, realmente se necesita o donde no causa confusión. Por ejemplo, a veces se usa en for cláusulas de bucle de una manera no confusa para permitir que se actualicen varias variables en cada iteración de bucle.

+1

En realidad, el bucle tal como está escrita se efectuará sin procesar la línea 'fgets' dejar de recibir EOF en lugar de recibir una nueva línea. Esto hace que el ciclo ignore una línea final que no termina en una línea nueva, que puede ser el comportamiento deseado, pero más probablemente un error. –

+0

@R .: Me acuerdo de la observación de http://www.drpaulcarter.com/cs/common-c-errors.php#4.2: "El autor aún no ha visto a ningún alumno usar la función feof() ¡correctamente!" –

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

comas dentro de un tiempo se comporta de la misma familia:

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

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