Declarar variables dentro de una instrucción switch [duplicate]


Esta pregunta ya tiene una respuesta aquí:

Vi algunas respuestas a este problema, y lo entiendo - no se puede declarar y asignar variables dentro de un switch. Pero me pregunto si lo siguiente es correcto al lanzar un error diciendo

Error: expresión esperada antes de " int "

Código:

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

¿Por qué hacer una llamada a NSLog() antes de que resulte en ningún error?

switch (i) {
    case 0:
        NSLog(@"wtf");
        int j = 1;
        break;
}
Author: Sourav Ghosh, 2009-08-05

3 answers

En realidad puede declarar variables dentro de un switch si lo hace de acuerdo con la sintaxis del lenguaje. Está obteniendo un error porque " case 0:" es una etiqueta, y en C es ilegal tener una declaración como la primera declaración después de una etiqueta - tenga en cuenta que el compilador espera una expresión , como una llamada a un método, asignación normal, etc. (Aunque sea extraño, esa es la regla.)

Al poner primero NSLog (), evitó esta limitación. Puedes encierre el contenido de un caso entre llaves { } para introducir un bloque de alcance, o puede mover la declaración de variable fuera del conmutador. Que usted 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 ámbito, 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 poco común como se podría pensar. En C y Java, también es ilegal utilizar un local declaración variable como la única declaración (que significa " no rodeado de llaves) en un para, while , or do loop, or even in if and else clauses. (De hecho, esto está cubierto en puzzler #55 de "Java Puzzlers", que recomiendo encarecidamente.) Creo que generalmente no escribimos tales errores para empezar porque tiene poco sentido declarar una variable como la única declaración en tales contextos. Con el interruptor / case construye, sin embargo, algunas personas omiten las llaves ya que la instrucción break es la instrucción crítica para el flujo de control.

Para ver los ajustes del compilador, copie este fragmento horrible e inútil en su código (Objetivo-)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);

Otra razón más para usar siempre { } llaves para delimitar el cuerpo de tales construcciones. :-)

 134
Author: Quinn Taylor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-25 16:42:49

Me he encontrado con este problema antes, y la conclusión fue que solo pones el código dentro de un bloque.

switch (i) {
case 0:
    {
        int j = 1;
        break;
    }
}
 42
Author: newacct,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-08-05 04:38:05

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 ámbito de la variable a un bloque de código(o tener algunas sentencias case con bloques de código y algunas sin).

switch (i) {
    case 0:;
        int j = 1;
        break;
}
 3
Author: Joel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-12 20:01:55