Anda di halaman 1dari 7

4.10.

2 Sentencias de selección

§1 Sinopsis

Las sentencias de selección, también llamadas de control de flujo, permiten decidir


entre distintos cursos de acción en función de ciertos valores. En C++ existen tres tipos
de estas sentencias de selección:

• if...else .
• else if .
• switch .

Recuerde que de no ser por estas sentencias, el flujo de ejecución del programa estaría
siempre constreñido a la ejecución de sus sentencias en el orden en que están colocadas
en el fuente.

§2 if … else

En su forma abreviada, cuando no existe la cláusula else, esta sentencia permite escoger
entre ejecutar o no una sentencia, en función del resultado de una expresión lógica. En
su forma ampliada, cuando la cláusula else está presente, permite escoger entre dos
opciones alternativas.
§2.1 Sintaxis

if ( <condición> ) <sentencia1>;

[ else <sentencia2>; ]

§2.2 Descripción

<condición> debe ser una expresión relacional ( 4.9.12) que devuelve un valor
lógico, es decir, un bool ( 3.2.1b), y estar obligatoriamente entre paréntesis. Pueden
declararse variables dentro de la <condición>. Por ejemplo, la siguiente es una
sintaxis válida:

if (int val = func(arg))

val = z ;

else val = y;

El ámbito de la variable val incluye toda la sentencia if, incluyendo, en su caso, el


bloque <sentencia2> de else. La cláusula else es opcional, pero no puede haber
sentencias entre el if y else. Recuerde las precauciones indicadas respecto de las
expresiones relacionales ( 4.9.12), ya que son motivo frecuente de error en este tipo
de sentencias.

<sentencia1>. Es una sentencia o bloque de código que se ejecuta si <condicion>


se evalúa como cierto (true != 0).
<sentencia2> es una sentencia o bloque de código que se ejecuta si existe un else y
<condicion> resulta falso (false == 0)

Puesto que el if simplemente chequea el valor resultante de <condicion> (igual o


desigual a cero), las dos expresiones siguientes son equivalentes:

if ( expresion ) <sentencia> ;

if ( expresion !=0 ) <sentencia> ;

La forma más general es:

if (<condicion>) {

<sentencia1>;

else {

<sentencia2>;

§2.3 Ejemplos

Uno sencillo:

if (salida == 'S') break;

Otro ejemplo:

if (a > b)

z = a;

else

z = b;

Se podría haber escrito de forma más comprimida:

if (a > b) z = a;

else z = b;

También:

a>b?z=a:z=b;
o mejor aún:

z = (a > b ? a : b);

Otro ejemplo:

if (int val = func(count)) { /* sentencias */ }

else { // otra vía de acción

cout << "val es falso";

Puesto que la cláusula else es opcional, en los if... else anidados podría haber
ambigüedad sobre a qué if corresponde un else; esto se evita asociando el else al if más
interno sin else. Por ejemplo, en los dos trozos de código siguientes, el primero tiene
una indentación que no se corresponde con la realidad lógica del programa.

// mal indentado: ------------

if ( n > 0 )

if ( a > b )

z = a;

else

z = b;

// bien indentado: -----------

if ( n > 0 )

if ( a > b )

z = a;

else

z = b;

§3 else if

Estas sentencias no representan en realidad nada nuevo, solo una sucesión de if else
anidados, aunque de uso muy frecuente, por lo que haremos una consideración especial
de este caso.
if ( <expresion1> )

<sentencia1> ;

else if ( <expresion2> )

<sentencia2> ;

else if ( <expresion3> )

<sentencia3> ;

else

<sentencia4> ;

En realidad, a la luz de lo expuesto en el apartado anterior, su indentación correcta sería:

if ( <expresion1> )

<sentencia1> ;

else

if ( <expresion2> )

<sentencia2> ;

else

if ( <expresion3> )

<sentencia3> ;

else

<sentencia4> ;

Las expresiones <expresion> son evaluadas correlativamente hasta que se encuentra la


primera que devuelve un valor cierto ( != 0 ), en cuyo caso se ejecuta el bloque de
código <sentencia> correspondiente y acaba la evaluación. En caso de que ninguna de
las <expresion> sea cierta, se ejecuta la <sentencia> correspondiente al else (si
existe).

§4 switch

Se trata de una sentencia condicional multi-salida en la que las decisiones se toman en


función de un valor numérico entero de entre una serie de opciones posibles. Puede
existir una cláusula por defecto o bien no adoptarse ninguna acción.
§4.1 Sintaxis

switch ( <expresion> ) {

case <const1> : <sentencia1>; [break;]

case <const2> : <sentencia2>; [break;]

case <constN> : <sentenciaN>; [break;]

[default : <sentenciaD>; ]

§4.2 Descripción

La sentencia switch comprueba cuando una expresión <expresion> entre paréntesis


(que se traduce en un valor numérico) coincide con alguno de una serie de valores
enteros constantes y diferentes (<constX>). En cuyo caso, se ejecuta un bloque de
código específico <sentencia>. En caso de estar presente la cláusula opcional default
y no existir concordancia con ninguno de los valores anteriores, se ejecuta una sentencia
por defecto (<sentenciaD>).

Los valores case y default pueden aparecer en cualquier orden, aunque lo usual es
colocar default al final. Los dos puntos : después de <constX> son imprescindibles.

§4.3 Las expresiones <constX> son expresiones constantes ( 3.2.3a) que se


resuelven en un entero. Pueden ser simples o compuestas, como se muestra en el
ejemplo.

switch (c - 48) {
case 0: case 1: case 2: case 3: case 4:

case 5: case 6: case 7: case 8: case 9:


cout << "Dígito" << endl;
break;
case 17: case 21: case 25: case 31: case 37:

case 49: case 53: case 57: case 63: case 69:
cout << "Vocal" << endl;
break;
default:
cout << "Otro carácter" << endl;
}

§4.4 Después de ejecutado el bloque de código correspondiente a una concordancia,


siguen las comprobaciones, por lo que puede ser conveniente incluir un break para
abandonar el control del switch (no es necesario ningún break después de la última).
Ver ejemplo .

§4.5 Es ilegal que la transferencia de control originada en alguna cláusula case o


default se salte una declaración que incluya un inicializador implícito o explícito. A
menos que la declaración esté situada en el interior de un bloque que sea saltado
completamente durante la transferencia. Ejemplo:

switch (n) {
case 1: case 10:
int y; // L-3: Ok. no incluye inicialización
cout << "Caso-1" << endl;
break;
case 2:
{
int z = 0; // L-8: Ok. dentro de un bloque
cout << "Caso-2" << endl;
break;
}
case 3:
int x = 3; // L-13: Error-1
cout << "Caso-3" << endl;
break;
case 4: // L-16:
for (int i = 0; i<4; i++) // L-17: Error-2
cout << "Caso-4" << endl;
break;
default: // L-20:
cout << "Resto de casos" << endl;
}

Observación: es posible que en estos casos, el error señalado por el compilador se


produzca en las sentencias responsables de que la transferencia de control se salte la
declaración. En el código del ejemplo, el Error-1 podría ser señalado en las sentencias
L.16 y L.20, mientras que el Error-2 en la sentencia L.20. Como muestra se incluyen los
mensajes obtenidos en el caso anterior con los dos compiladores:

MS Visual C++ 6.0:

xxx.cpp(16) : error C2360: initialization of 'x' is skipped by 'case' label


xxx.cpp(13) : see declaration of 'x'
xxx.cpp(20) : error C2361: initialization of 'x' is skipped by 'default' label
xxx.cpp(13) : see declaration of 'x'
xxx.cpp(20) : error C2361: initialization of 'i' is skipped by 'default' label
xxx.cpp(17) : see declaration of 'i'

Anda mungkin juga menyukai