2010-01-27 12 views
56

quiero saltar desde la mitad de una declaración switch, a la sentencia de bucle en el código siguiente:Uso de continuar en una sentencia switch

while (something = get_something()) 
{ 
    switch (something) 
    { 
    case A: 
    case B: 
     break; 
    default: 
     // get another something and try again 
     continue; 
    } 
    // do something for a handled something 
    do_something(); 
} 

¿Es esta una forma válida para utilizar continue? ¿Son continue declaraciones ignoradas por las declaraciones switch? ¿C y C++ difieren en su comportamiento aquí?

+0

Tu idea está bien, pero el ciclo anterior nunca ejecutará 'do_something()'. – antik

+4

Incluso si el control alcanza el caso A o el caso B? –

+13

Iba a decir, antik está equivocado al respecto. En el caso de A o B, se ejecutará do_something(). Con el valor predeterminado, se rescatará. – acron

Respuesta

42

Está bien, la declaración continue se relaciona con el bucle de cerramiento, y el código debe ser equivalente a (evitando tales declaraciones salto):

while (something = get_something()) { 
    if (something == A || something == B) 
     do_something(); 
} 

Pero si espera break para salir del bucle, como su comentario sugerir (siempre intenta de nuevo con otro algo, hasta que se evalúe como falso), necesitarás una estructura diferente.

Por ejemplo:

do { 
    something = get_something(); 
} while (!(something == A || something == B)); 
do_something(); 
+1

'equivalente' solo en el sentido semántico. el código que genera el compilador es muy diferente. con una declaración de cambio, el compilador puede generar una tabla de salto que evita comparaciones múltiples y, por lo tanto, es mucho más rápido que comparar contra cada elemento 1 por 1. – chacham15

+0

+1 para "la instrucción continuar se relaciona con el bucle adjunto" – onmyway133

+0

@ chacham15, why couldn ' t el compilador genera el mismo código para ambos? – avakar

18

Sí, está bien, es como usarlo en una declaración if. Por supuesto, no puede usar un break para salir de un bucle desde el interior de un interruptor.

+0

Pero 'if' no tiene ningún efecto en el comportamiento de' continue' o 'break'. ¿Cómo quieres decir que es igual? –

+0

@Matt Quiero decir que continuará el ciclo en ambos casos. –

+1

@Neil, está bien, confusión evitada. –

4

Aunque técnicamente válidos, todos estos saltos de control de flujo oscuro - en especial la declaración continue.

Usaría un truco como último recurso, no el primero.

¿Qué tal

while (something = get_something()) 
{ 
    switch (something) 
    { 
    case A: 
    case B: 
     do_something(); 
    }   
} 

Es más corto y llevar a cabo sus cosas de una manera más clara.

+1

disculpe la confusión Alexander, el código es sólo para demostración, tengo una buena razón (creo) para la estructura real de mi código. –

+2

@Matt: Eso probablemente significaría una estructura aún más ofuscada ... :) – visitor

+0

@visitor, sí lo hace –

5

Es sintácticamente correcto y estilísticamente correcto.

buen estilo requiere que cada case: declaración debe terminar con uno de los siguientes:

break; 
continue; 
return (x); 
exit (x); 
throw (x); 
//fallthrough 

Además, siguiendo case (x): inmediatamente con

case (y): 
default: 

es admisible - agrupen varios casos que tienen exactamente el mismo efecto .

Cualquier otra cosa se sospecha que es un error, al igual que if(a=4){...} Por supuesto que es necesario encerrar bucle (while, for, do...while) para continue a trabajar. No volverá al solo case(). Pero una construcción como:

while(record = getNewRecord()) 
{ 
    switch(record.type) 
    { 
     case RECORD_TYPE_...; 
      ... 
     break; 
     default: //unknown type 
      continue; //skip processing this record altogether. 
    } 
    //...more processing... 
} 

... está bien.

+2

lo siento por necroposting, pero yo agregaría que una llamada a 'exit' también sería una buena cosa para terminar una caja de conmutación con. – Vality

2

Sí, continuar será ignorado por la declaración del interruptor y pasará a la condición del bucle que se probará. Me gustaría compartir este extracto de la referencia del lenguaje de programación de C por Ritchie "La instrucción continuar está relacionada con el corte, pero se usa con menos frecuencia, hace que comience la siguiente iteración del bucle adjunto para, while o do.En el tiempo y do, esto significa que la parte de prueba se ejecuta inmediatamente; en el para, el control pasa al paso de incremento. La instrucción continue se aplica solo a los bucles, no a los cambios. Un continuar dentro de un interruptor dentro de un bucle causa la siguiente iteración del bucle. "

No estoy seguro de eso para C++.

-1

interruptor no se considera como bucle de modo que no se puede utilizar Continuar dentro de una declaración de caso en el interruptor ...

+0

La instrucción 'switch' está dentro de un bucle' while', por lo que 'continue' es perfectamente válida. – Rick

Cuestiones relacionadas