Está en la página 1de 7

ESTRUCTURAS DE CONTROL - SENTENCIA SWITCH

 Sentencia switch.
 Importancia de break.

 Importancia de default.

Sentencia switch.
En las secciones anteriores se ha estudiado un tipo de flujo de control limitado a las
posibilidades ofrecidas por las sentencias alternativas (if-else) y repetititivas (for,
while). Las sentencias alternativas permiten especificar la reacción del programa en
distintas circunstancias; si la lógica del algoritmo empleado se ajusta a un comportamiento
más o menos dicotómico, es posible construir un árbol de sentencias if() anidadas que
generen el comportamiento necesario. Sin embargo, es frecuente hallar grupos de
situaciones (y por tanto de respuestas de programa) que se reducen a una lista de
posibilidades mutuamente excluyentes. Ciertamente, se puede implementar un algoritmo de
este tipo mediante múltiples sentencias
if()-else anidadas, pero esta solución
resulta farragosa y poco eficiente, porque
el código tiene que ir comprobando una
por una todas las posibilidades (todas las
condiciones if()) hasta encontrar la
correcta.
  El lenguaje C ofrece otra posibilidad:
construir una expresión ordinal
(posiblemente basada en un tipo
enumerado) que tipifique las posibles
situaciones y ejecutar el código
correspondiente a cada valor de esta
expresión sin necesidad de examinar los
demás. La sentencia switch es un
selector multivía, que admite como
argumento el valor de una expresión
ordinal, y desencadena la ejecución del
código correspondiente, identificado
mediante uno o más valores constantes
del mismo tipo ordinal que la expresión.
La sintaxis de esta sentencia es como
sigue:
switch( expresión_ordinal )
{
case constante_1 : Bloque_1;
break;
case constante_2 : Bloque_2;
break;
case constante_3 :
case constante_4 :
case constante_5 : Bloque_3;
break;
...
default : Bloque_4;
break;
}

Al evaluar la expresión_ordinal se obtiene un entero (quizá el valor de una variable de


tipo enum) o un carácter. Si este valor es igual a la constante que acompaña a alguna de las
cláusulas case presentes en el cuerpo de la sentencia switch, entonces se ejecuta el bloque
de código situado a la derecha de los dos puntos que acompañan a la cláusula case en
cuestión. El bloque puede estar formado por una o más sentencias. Puede haber varias
cláusulas case asociadas a un mismo bloque de código; en tal caso, el bloque ejecutado
será el mismo para todos aquellos casos en que el valor de la expresión de control sea el de
cualquiera de las cláusulas case asociadas a ese bloque. El programa siguiente es un
ejemplo sencillo de uso de la sentencia switch:
#include<stdio.h>

int main(int contador, char * argumento[])


{
int i;
switch(contador)
{
case 1: printf("\nNo me ha dado argumentos.\n");
break;
case 2: printf("\nMe ha dado un argumento.\n");
break;
case 3:
case 4:
case 5: printf("\nMe ha dado 2, 3 o 4 argumentos.\n");
break;
default: printf("\nMe ha dado más de 4 argumentos.\n");
break;
}
printf("\n");
/*
Ahora se muestran los argumentos dados, si los hay
*/
for(i=0;i<contador;i++)
printf("Argumento[%d] = %s\n", i, argumento[i]);

printf("\nTerminación normal del programa\n\n");


return 0;
}
El resultado de ejecutar este programa es como sigue:
[cauldron:~/coti>]> ./a.out

No me ha dado argumentos.

Argumento[0] = ./a.out

Terminación normal del programa

[cauldron:~/coti>]> ./a.out 1

Me ha dado un argumento.

Argumento[0] = ./a.out
Argumento[1] = 1

Terminación normal del programa

[cauldron:~/coti>]> ./a.out 1 2 3

Me ha dado 2, 3 o 4 argumentos.

Argumento[0] = ./a.out
Argumento[1] = 1
Argumento[2] = 2
Argumento[3] = 3

Terminación normal del programa

[cauldron:~/coti>]> ./a.out 1 2 3 4 5 6 7

Me ha dado más de 4 argumentos.

Argumento[0] = ./a.out
Argumento[1] = 1
Argumento[2] = 2
Argumento[3] = 3
Argumento[4] = 4
Argumento[5] = 5
Argumento[6] = 6
Argumento[7] = 7

Terminación normal del programa

[cauldron:~/coti>]>

Comentarios.- La variable contador recibe automáticamente como valor el número de


argumentos que acompañan al nombre del programa en la línea de órdenes. Si no se dan
argumentos, esto es, si lo único que se escribe es el nombre del programa, entonces el valor
de contador es 1. Si se dan argumentos, se incrementa contador en tantas unidades como
palabras distintas aparezcan en la línea de órdenes. Hemos utilizado contador como
expresión (trivial, al ser una variable) de control en este ejemplo de sentencia switch.
El programa imprime en pantalla distintos comentarios en función del número de
argumentos; se han considerado los casos en que:

 No hay argumentos (contador es 1)


 Hay 1 argumento (contador es 2),
 Hay 2, 3 o 4 argumentos (contador es 3, 4 o 5),
 O hay más de 4 argumentos (contador tiene cualquier otro valor, cláusula default)

Importancia de break
Cuando el control del programa llega a una sentencia switch y se evalúa la expresión de
control de la misma, el programa comienza a ejecutar las sentencias presentes en el bloque
correspondiente a alguna cláusula case, o quizá a la claúsula default. ¿Qué sucede después
de ejecutar la última sentencia del bloque? Si el bloque es el último, el programa ejecuta la
sentencia inmediatamente siguiente al switch. Pero si no es el último, el programa ejecuta la
primera sentencia inmediatamente siguiente al bloque. Y luego la siguiente, y la siguente,
etc. La sentencia break, sirve para hacer que el programa abandone la sentencia switch. Si
no se encuentra un break, se ejecuta el siguiente bloque de código, y así hasta hallar un
break o salir de la sentencia switch.
Dicho de otro modo, las cláusulas case son puntos de entrada al conjunto de líneas de
código que hay en el interior del switch. Las sentencias break son puntos de salida, y
debemos organizar cuidadosamente ambas cosas para evitar errores que no podrá detectar
el compilador.
La estructura switch se utiliza con mucha frecuencia; véase el Ejercicio 1.

Importancia de default.
La sentencia switchestá especialmente indicada para construir menús: en efecto, se ofrece
al usuario una colección de opciones, y este indica su preferencia pulsando una tecla o
haciendo clic con el ratón en algún lugar. Esta elección del usuario es fácilmente
transformable en números enteros, y una sentencia switch permite fácilmente asignar
acciones a esos números. De hecho, la sentencia switch se va a utilizar para construir
algunas esqueletos de programa, aun cuando prescindiremos de ella en cuanto dispongamos
del interesante concepto de puntero de función.

Ejercicio 1.- Construir un programa que resuelva ecuaciones de segundo grado empleando
sentencias switch.
/*
Este programa sirve para resolver ecuaciones cuadráticas.
Es un ejemplo de utilización de la sentencia switch.
*/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

enum tipos_de_raices {reales_y_distintas, complejas_conjugadas,


raiz_real_doble};
enum tipos_de_raices tipo;
float a, b, c, d;
float r1, r2, preal, pimaginaria, rrd;

int main(void)
{
printf ("Ecuaciones cuadráticas");
printf("\n\nEscriba los coeficientes a, b y c : ");
scanf("%f %f %f", &a, &b, &c);

d = b*b - 4.0*a*c;

d > 0.0 ? tipo=reales_y_distintas :


(d < 0.0 ? tipo=complejas_conjugadas : (tipo= raiz_real_doble));
switch(tipo) {
case reales_y_distintas :
{
r1=(-b+sqrt(d))/(2.0*a);
r2=(-b-sqrt(d))/(2.0*a);
printf("\nRaíces reales y distintas; r1= %f y r2= %f",
r1, r2);
}
break;
case complejas_conjugadas :
{
preal=(-b)/(2.0*a);
pimaginaria=sqrt(-d)/(2.0*a);
printf( "\nRaíces complejas conjugadas, r1= %f+j%f y r2= %f-j%f",
preal, pimaginaria, preal, pimaginaria);
}
break;
case raiz_real_doble:
{
rrd=(-b)/(2.0*a);
printf("\nRaíz real doble, rrd= %f", rrd);
}
break;
default:
{
printf("\nError catastrófico - tipo de ecuación cuadrática
desconocido!");
}
break;
}
printf("\n\nTerminación normal del programa.\n");
return 0;
}
Comentarios.- El algoritmo empleado es el sobradamente conocido para la resolución de
ecuaciones de segundo grado. Para hace más comprensible el programa se ha creado un
tipo de datos enumerado, enum tipos_de_raices, para luego declarar una variable (tipo)
de este tipo de datos. De este modo se puede hablar de manera comprensible de los
distintos tipos de soluciones; tipo se utiliza como expresión de control en la sentencia
switch del programa.
Para calcular el valor de tipo se ha recurrido a dos operadores ?: anidados; lo mismo podría
hacerse con sentencias if()-else, quizá algo más voluminosas aunque el resultado sería
exactamente el mismo. A fin de cuentas, se trata de dar el valor correcto a tipo, en función
del signo del discriminante.
Para abreviar el programa se ha utilizado una sola sentencia switch. Nada impide, desde
luego, utilizar dos sentencias switch distintas, una para el cálculo y otra para la impresión;
de hecho, el programa resultante resulta más claro.

Ejercicio 2.- Construir un programa que realice diferentes acciones en función de la


selección efectuada por el Usuario. El programa deberá mostrar un menú en pantalla;
recibirá instrucciones del usuario y ejecutará las acciones correspondientes. Para salir de
programa, el usuario seleccionará la opción oportuna.
/*
Esta es una versión muy primitiva del programa núcleo, sin utilizar
subprogramas.
Este ejercicio muestra la aplicación de la sentencia switch,
con especial antención a break y default.

Esta versión del programa núcleo es apenas utilizable,


es tan solo un ejemplo de aplicación de la sentencia switch.
*/

/*
Basado en nucleosp.pas
*/

#include<stdio.h>

void main(void)
{
int fin; /* control de iteración del programa */
char instruccion; /* dada por el usuario */
char menu[80]; /* que muestra el programa */
char opcionesvalidas[80]; /* que admite el programa */

/* Iniciaciones generales */

fin = 0; /* Acabamos de arrancar, no hay que


salir */
strcpy(menu,"O)perar S)alir"); /* Esto es lo que mostrará el menú
*/
strcpy(opcionesvalidas,"OSQ"); /* Estas son las opciones admisibles
*/

do {

do {
printf("%s ", menu);
scanf("%c%*c",&instruccion);/* Se descarta el \n del usuario */
instruccion=toupper(instruccion);
} while (!strchr(opcionesvalidas,instruccion));

/* "dispatcher" */
switch(instruccion)
{
case 'S': {
fin = 1;
puts("Nos vamos!\n");
}
break;
case 'O': {
puts("Estamos operando.\n");
}
break;
default : {
puts("Instrucción incorrecta.\n");
}
break;
}

}
while (!fin);

puts("\n\nThat's all folks!\n");


}
/*
COMENTARIOS

Este programa admite "macros". En efecto, escriba varias veces la letra


"o" y observará que se producen varias llamadas al bloque correspondiente
a operar. Si hubiera más de una letra correspondiente a una operación,
se desencadenarían sucesivamente todas las operaciones.
Este programa es posiblemente el intérprete más pequeño posible.

¿Qué ocurre si las instrucciones se leen de un fichero (y no del


teclado)?
¿Qué ocurre si en lugar de caracteres se leen cadenas completas (gets)?
¿Qué ocurre si se analizan esas cadenas, en busca de palabras reservadas
(input, print,load, save, list, run...?

¿Cómo funciona command.com, o cualquier otro intérprete de líneas?


¿Se entiende el tratamiento de un fichero .BAT?
*/

También podría gustarte