2009-08-05 11 views
102

Vi algunas respuestas a este problema, y ​​lo entiendo - no se puede declarar y asignar variables dentro de un switch. Pero me pregunto si el siguiente es correcta al tirar un error diciendoDeclarando variables dentro de una declaración de interruptor

error: expected expression before 'int'

Código:

switch (i) { 
    case 0: 
     int j = 1; 
     break; 
} 

¿Por qué poner una llamada a NSLog() antes de que da lugar a errores?

switch (i) { 
    case 0: 
     NSLog(@"wtf"); 
     int j = 1; 
     break; 
} 
+1

Esto se ha pedido (al menos) dos veces antes: http://stackoverflow.com/questions/92396/why-cant-variables-be-declared-in-a-switch-statement http: // stackoverflow.com/questions/1115304/can-i-declare-variables-inside-an-objective-c-switch-statement –

+2

Es cierto, pero ambas preguntas siguen abiertas. No veo ningún problema con dejar que este solo - no hay necesidad de votar para cerrarlo ... –

+1

Adam, mientras que la otra publicación responde el error, no aborda el hecho de que poner una expresión como la primera llamada sería en realidad evitar el error. Algo que Quinn ha respondido aquí. – dizy

Respuesta

132

En realidad puede declarar variables dentro de un interruptor si lo hace de acuerdo a la sintaxis de la lengua. Recibirá un error porque "case 0:" es una etiqueta, y en C es ilegal tener una declaración como primera afirmación después de una etiqueta: tenga en cuenta que el compilador espera una expresión , como una llamada a método, normal asignación, etc. (Por extraño que pueda ser, esa es la regla).

Cuando coloca el NSLog() primero, ha evitado esta limitación. Puede encerrar el contenido de un caso en {} llaves para introducir un bloque de alcance, o puede mover la declaración de variable fuera del interruptor. Lo que elija es una cuestión de preferencia personal. Solo tenga en cuenta que una variable declarada en {} llaves solo es válida dentro de ese alcance, por lo que cualquier otro código que la use también debe aparecer dentro de esas llaves.


Editar:

Por cierto, esta peculiaridad no es tan infrecuente como se podría pensar. En C y Java, también es ilegal el uso de una declaración de variable local, como la declaración solitario (que significa "no rodeado de aparatos ortopédicos) en un para, mientras o hacer bucle, o incluso en si y más cláusulas. (De hecho, esto está cubierto en el rompecabezas # 55 de "Java Puzzlers", que recomiendo encarecidamente). Creo que generalmente no escribimos esos errores para empezar porque tiene poco sentido declarar una variable como la única declaración en tales contextos. Con cambiar/caso construcciones, sin embargo, algunas personas omiten los apoyos ya que elroturaLa declaraciónes la declaración crítica para el flujo de control.

Para ver los ajustes del compilador de tiro, copiar este fragmento horrible y sin sentido en su (Objetivo-) código C:

if (1) 
    int i; 
else 
    int i; 
for (int answer = 1; answer <= 42; answer ++) 
    int i; 
while (1) 
    int i; 
do 
    int i; 
while (1); 

Sin embargo, otra razón para utilizar siempre {} Las llaves para delimitar el cuerpo de tales construcciones. :-)

+0

wow, eso es raro ... pero gracias! – dizy

+9

Generalmente, si la variable se usa solo dentro de un solo caso, adjuntar la sección de caso en {} será una mejor forma (evita que se vuelva a utilizar accidentalmente más adelante). Si la variable se usa más tarde, entonces tiene más sentido declararla antes del inicio de la instrucción switch, ya que es muy obtusa de lo contrario. –

+0

Estoy totalmente de acuerdo, el uso de un osciloscopio anidado con llaves hace que el intento sea claro como el cristal y puede prevenir errores incidentales. ¡Gracias por aclararlo! –

39

Me he encontrado con este problema anteriormente, y la conclusión fue que simplemente colocaste el código dentro de un bloque.

switch (i) { 
case 0: 
    { 
     int j = 1; 
     break; 
    } 
} 
4

Otra solución simple que uso es agregar una expresión vacía (punto y coma) antes de la declaración. Esto evita limitar el alcance de la variable a un bloque de código (o tener algunos enunciados de caso con bloques de código y algunos sin).

switch (i) { 
    case 0:; 
     int j = 1; 
     break; 
} 
+0

Esto me da un error en mi caso 'predeterminado':' La caja del interruptor está en el alcance protegido. – zakdances

+0

@joel Nice hack :) – FreelanceAr

Cuestiones relacionadas