2010-11-08 27 views
24

¿Podemos poner punto y coma como while(condition); en una programación en C? Si while(condition); es válido, ¿qué significa?Es el código "while (condition);" válido y ¿qué significa?

+3

¿Cuál es la condición? –

+4

Sí, desafortunadamente, cuando me enteré después de algunas horas desperdiciadas en mi primera clase de programación. – Chance

+0

La condición es irrelevante, todas ellas son verdaderas o falsas. De acuerdo, las cosas se pueden hacer dentro de la condición como se explica a continuación, pero esta pregunta parece ser principalmente sobre la sintaxis y/o el comportamiento en relación con el ciclo. – Chance

Respuesta

2

Es solo un bucle vacío. Ayudaría si explicaras cuál es la condición.

3

while() es un bucle. Probablemente estés buscando hacer un ciclo "do-while". Do-while se ejecutan en este formato:

do 
{ 
    // Your process 
    // When something goes wrong or you wish to terminate the loop, set condition to 0 or false 
} while(condition); 

El que usted ha enumerado anteriormente, sin embargo, es un bucle vacío.

while() los bucles funcionan casi igual; simplemente no hay una porción de "hacer".

¡Buena suerte!

4

Sí, es correcto. Hará un bucle en la condición hasta que sea falso.

while (condition()); 
50
while (condition); 

es la misma que

while (condition) 
{ 
} 

Se puede utilizar para bucles de espera, por ejemplo:

while (!isLightGreen()); // waits until isLightGreen() returns true 
go(); 
+42

Se debe tener en cuenta que esto dará como resultado la ejecución continuamente de bucles y comprobación de la condición, por lo que el proceso/hilo no espera, sino que utiliza el tiempo de CPU todo el tiempo. – TeaDrivenDev

+5

@GCATNM: correcto, pero a veces (por ejemplo, aplicaciones de controlador que esperan una señal) no hay nada más que hacer que esperar. Si este no es el comportamiento deseado, el cuerpo del bucle debería permitir el cambio de hilo/tarea (por ejemplo, utilizando el modo reposo) o usar otro mecanismo para esperar (por ejemplo, funciones de devolución de llamada, interrupciones); pero esta no era la pregunta ... – Curd

+20

Esto se llama [Spinlock] (http: //en.wikipedia.org/wiki/Spinlock) – Brian

1

Si la evaluación de la condición no modifica un valor que influye en la condición en sí, while(condition); es un bucle infinito vacío, lo que significa que nunca terminará (y nunca hará nada excepto consumiendo tiempo de CPU).

+4

A menos que esté esperando algo de otro hilo o un registro para cambiar (o algo similar). Creo que lo has generalizado demasiado. –

+2

Esto es cierto en un solo programa de subprocesos, pero el valor de la condición podría cambiarse por otros subprocesos. – Francesco

+2

Si la condición es falsa, no se repetirá. – GreenMatt

10

Como la condición en realidad puede tener efectos secundarios, dicha construcción está permitida. Considere lo siguiente:

while (*p && *p++ != ' '); 

Esto haría avanzar el puntero p al primer personaje que es un espacio.

Usted puede incluso utilizar el operador coma tener declaraciones ordinarias dentro de la condición:

while (do_something(), do_something_else(), i < n); 

Debido a las instrucciones conectadas con el operador coma evalúan a la declaración más a la derecha, en ese caso i < n, lo anterior es idéntica a:

do { 
    do_something(); 
    do_something_else(); 
} while (i < n); 
5

Se mantendrá evaluando la condición hasta que sea falsa. Es un bucle sin cuerpo.

Los programadores suelen añadir un espacio antes del punto y coma, es decir

while(condition) ; 

o vacíos llaves:

while(condition) {} 

para mostrar el cuerpo vacío es intencional y no sólo un error tipográfico. Si está leyendo un código fuente existente y se pregunta por qué hay un bucle vacío allí, también debe leer las siguientes líneas para ver si el punto y coma realmente debería estar allí o no (es decir, las siguientes líneas parecen el cuerpo de un lazo o no?).

27

Significa que el cuerpo del lazo está vacío. Por lo general, este patrón se usa cuando la condición misma hace algún trabajo.

Por ejemplo, este bucle puede copiar bytes dentro de la condición:

while ('\0' != (*pt++ = *ps++)) 
      ; 

Si utiliza un punto y coma, que es una buena idea para ponerla en una línea separada para que se vea menos como un error . Personalmente tiendo a utilizar llaves vacías - {}, y a veces un comentario de que el bloque vacío es intencional.

Editar:

En el segundo comentario, Tom Anderson observa una mejora con respecto a un punto y coma en solitario. Google's C++ style guide recomienda esto o {}.

while ('\0' != (*pt++ = *ps++)) 
      continue; 
+8

+1 para la explicación de que es útil cuando la condición de ciclo tiene un efecto secundario. -100000 para poner el punto y coma en una línea separada! ¡Horrible! FWIW, hay una buena guerra de llama cruzada pasando en comp.lang.java.programmer/comp.lang.c sobre cómo dar estilo a esta construcción que puede ser de interés. –

+8

'while (condition) continue;' (con un salto de línea antes de continuar y/o llaves, como prefiera) se ha sugerido como una forma legible y razonablemente no producida. –

+2

Como mencioné, utilizo llaves en lugar de un punto y coma. K & R usó el punto y coma en una línea separada. El patrón "continuar" parece una mejora. No considero que los flamewars en las cosas pequeñas sean valiosos. –

10

Sí, puede hacerlo. Simplemente significa que el ciclo while seguirá en bucle hasta que condition sea falso. Por ejemplo:

#include<stdio.h> 

int x = 10; 
int func() 
{ 
    printf("%d\n", x); 
    return --x; 
} 

int main() 
{ 
    while(func()); 
    return 0; 
} 

Pero en general, la gente no hace esto, ya que tendría más sentido de poner la lógica en el cuerpo del bucle.

Editar:

Hay algunos ejemplos de esto en el uso, por ejemplo, la copia de una cadena terminada en cero:

char dest[256]; 
char *src = "abcdefghijklmnopqrstuvwxyz"; 
while(*(dest++) = *(src++)); 
+2

+1 para el ejemplo –

+1

Si bien esto puede ser un ejemplo de un bucle de cuerpo vacío, también es un ejemplo de código mal diseñado (por lo tanto, un poco menos útil en mi humilde opinión). –

+0

@ Lee-Man - exactamente, incluso señalo que no es una buena idea, la lógica pertenece al cuerpo del ciclo. Mi segundo ejemplo es un poco mejor, aunque sea porque es un patrón algo común y la mayoría de los programadores C lo reconocerían instantáneamente. –

3

Significa que guardar condiciones de comprobar hasta que se evalúe a falsa

3

La clave para entender esto es que la sintaxis del while loop en "C" es la siguiente:

while (condition) statement 

Dónde declaración puede ser cualquier sentencia "C" válido. Los siguientes son todas válidas "C" declaraciones:

{ statements } // a block statement that can group other statements 

statement; // a single statement terminated by a ; 

; // a null statement terminated by a ; 

Por lo tanto, por las reglas de la bucle while, la comunicado parte (instrucción nula en su ejemplo) se ejecutará (no hacer nada), siempre como condición es true. Esto es útil porque equivale a una espera ocupada hasta que la condición convierte en falso. No es una buena manera de esperar, pero útil sin embargo. Podría usar esta construcción, por ejemplo, si desea esperar a que haya otra secuencia (o un manejador de señal) para establecer una variable a algún valor antes de seguir adelante.

1

es absolutamente correcto. significa no hacer nada en el ciclo, simplemente sondear la condición. Y es común en los códigos del sistema integrado.

-1

Sólo otro uso no se describe aquí:

do 
{ 
    if(out_of_memory) 
    break; 

    if(file_does_not_exist) 
    break; 

    return ok; 

} while(0); 

return error; 

Esto le permite evitar varias llamadas de retorno o sentencias goto.

+1

Considero esto un antipatrón. Por el amor de Dios, solo usa return, o incluso goto donde sea la mejor construcción. No escriba código con el enmascaramiento de goto como estructurado. –

1

Es sólo un bucle while con ningún organismo de ejecución

while(condition); 

es igual que

while(condition) 
{ 
    } 
+0

Tenemos un estándar de codificación en el trabajo que siempre requiere el uso de llaves incluso para declaraciones simples if/while/for. Esta puede ser una buena razón por qué; la segunda declaración es mucho más clara. – Chance

3

Siempre escribo esto como:

while (condition()) 
    continue; 

Así que es obvio que no estaba es un error Como otros han dicho, solo tiene sentido cuando la condición() tiene efectos secundarios.

+0

condición sin efectos secundarios también tiene sentido si se comprueba la variable volátil, cuando simplemente espera evento asincrónico. – Vovanium

2

El código while(condition); es un código perfectamente válido, aunque sus usos son pocos. Supongo condition es una variable, no una función — otros aquí discuten funcional condition.

Se puede bloquear un uso de while(condition); mientras espera un signal p. Ej. SIGHUP, donde el manejador de señal cambia la variable condition. Sin embargo, esta no suele ser la mejor manera de esperar una señal. Uno normalmente usaría un sleep en el bucle, es decir, while(condition) { sleep(1); }.

La ausencia de cualquier sleep significa que el lazo se procesará continuamente mientras tanto, y probablemente desperdicie ciclos de procesamiento. A menos que el proceso tenga sus recursos gestionados (e incluso allí ...), creo que esto solo es adecuado cuando el ciclo se debe interrumpir en un intervalo menor que la granularidad del comando sleep disponible (es decir, el segundo gran pero necesita el código después de la apariencia ejecutada con un tiempo de respuesta inferior al segundo). Dicho esto, un tubo o zócalo de bloqueo puede ser preferible a las señales, en cuanto al rendimiento – aunque no tengo ningún dato empírico que respalde esto de forma inmediata, y sospecho que el rendimiento puede variar significativamente según la plataforma.

Una podría tener condition modificada de un hilo paralelo de un mismo proceso, pero me gustaría pensar que se debe preferir a hacer eso por medio de un mutex o semáforo (es decir condition puede ser necesario hacer más de una variable simple)

Espero que sea útil, ¡o al menos algo que me haga pensar!

Cuestiones relacionadas