Introducción
Por defecto, un programa se ejecuta de arriba a abajo; pero gracias a diferentes estructuras de control, es posible modificar y manipular este orden para realizar tareas más complicadas.
- Control secuencial: control por defecto, de arriba a abajo.
- Control selectivo: se ejecutan solamente determinadas partes.
- Control repetitivo: se ejectutan las mismas instrucciones varias veces.
Selectivo
if
La estructura selectiva o condicional más básica es el if
. Este toma una
condición entre paréntesis: si se evalua a un número distinto de 0, se ejecutará
la siguiente sentencia; de lo contrario, la saltará.
Nótese que es posible ejecutar varias sentencias usando un bloque:
if else
A continuación del if
, se puede añadir una parte de else
, que se ejecutará
en caso de que la condición sea falsa (en este caso, que se evalue a 0).
1if (condición)
2 // Se ejecuta si la condición != 0
3 sentencia_if;
4else
5 // Se ejecuta si la condición == 0
6 sentencia_else;
Y de la misma forma, se pueden usar bloques si es necesario:
1if (condición) {
2 sentencia_if1;
3 sentencia_if2;
4} else {
5 sentencia_else1;
6 sentencia_else2;
7}
8
9// Y otras variantes
else if
También es posible anidar estas estructuras, es decir, añadir unas dentro de otras:
En concreto, si se anida un if
en un bloque de else
:
Aunque normalmente se formatea de la siguiente manera:
Y nótese también, que estos bloques se pueden repetir las veces que se desee
(incluso en combinación con un bloque else
normal).
1if (condición) {
2 sentencia_if;
3} else if (condición1) {
4 sentencia_elseif1;
5} else if (condición2) {
6 sentencia_elseif2;
7} else if (condición3) {
8 sentencia_elseif3;
9} else {
10 sentencia_else;
11}
switch
En algunos casos es necesario hacer comprobaciones como esta:
1if (variable == valor1) {
2 sentencia_valor1;
3} else if (variable == valor2) {
4 sentencia_valor2;
5} else if (variable == valor3) {
6 sentencia_valor3;
7} else if (variable == valor4) {
8 sentencia_valor4;
9} else if (variable == valor5) {
10 sentencia_valor5;
11} else {
12 sentencia_else;
13}
Esto resulta un poco complicado de leer, por tanto C permite crear bloques
switch
con este propósito:
1switch (variable) {
2 case valor1:
3 sentencia_valor1;
4 case valor2:
5 sentencia_valor2;
6 case valor3:
7 sentencia_valor3;
8 case valor4:
9 sentencia_valor4;
10 default:
11 sentencia_else;
12}
==
) con números enteros (int
)
y caracteres (char
).Sin embargo, funciona un poco diferente de lo que se esperaría. Cuando se
comprueba el primer case
, continua con el siguiente; lo cual es ineficiente,
dado que una variable solo puede tener un único valor. Para evitar ese problema,
se escribe:
1switch (variable) {
2 case valor1:
3 sentencia_valor1;
4 break;
5 case valor2:
6 sentencia_valor2;
7 break;
8 case valor3:
9 sentencia_valor3;
10 break;
11 case valor4:
12 sentencia_valor4;
13 break;
14 default:
15 sentencia_else;
16}
La instrucción break
fuerza la salida de la estructura, evitando que se siga
comprobando tontamente el resto de valores.
Pero tiene un sentido de ser:
1char x = 'a';
2switch (x) {
3 case 'a':
4 case 'b':
5 case 'c':
6 sentencia1; // En caso de que x sea 'a', 'b' o 'c'
7 break;
8 case 'd':
9 sentencia2; // En caso de que x sea 'd'
10 break;
11 default:
12 sentencia3;
13}
Repetitivo / bucles
while
Se repetirá sentencia
mientras la condición
sea verdadera, es decir,
mientras se evalue a un número no nulo.
Recuerda que también puedes usar un bloque para repetir varias sentencias:
do while
Esta estructura es exactamente igual que el while
, pero evalua la condición
después de ejecutar las sentencias del bucle. Es decir, que dichas sentencias
se ejecutarán al menos una vez si la condición es falsa.
Bucles infinitos
Teniendo en cuenta que un bucle while
se ejecuta siempre que la condición es
verdadera, es posible crear algo así:
Esto ejecutará sentencia
infinitamente, lo que por definición no es un
algoritmo válido.
Nótese que esto produce el mismo efecto:
Para detectar estos bucles infinitos hay que analizar si la condición es constante y si alguno de las variables que se utilizan en ella cambian dentro del bucle.
for
Para muchos problemas será necesario algo similar a esto:
De esta forma, sentencia
ejecutará exactamente 10 veces, con la variable
contador almacenando en cuál se encuentra.
Por este motivo, C proporciona el bucle for
, para acortar el código:
Y en general:
1for (<creación del contador>; <condición>; <actualización del contador>) {
2 sentencia;
3}
4
5// Equivalente a
6<creación del contador>;
7while (<condición>) {
8 sentencia;
9 <actualización del contador>;
10}
i
, j
y k
para los bucles. En el futuro veremos estructuras más
complejas que también se utilizan para controlar los bucles.break
La instrucción break
ayuda a controlar mejor los bucles, dado que cuando se
ejecuta, sale directamente del bucle.
Por ejemplo, es posible hacer lo siguiente:
Aparentemente, la condición del while
es constante, pero este bucle termina
tras 10 iteraciones.
continue
De forma similar a break
, continue
ayuda a controlar los bucles, pero
cuando se ejecuta, en lugar de salir, salta a la siguiente iteración.
Por ejemplo, este es un bucle infinito porque siempre se salta la instrucción que cambia la condición, por tanto esta es constante:
Pero sin embargo eso no pasa en un bucle for
, que simplemente lo repite 10
veces:
Bucles anidados
Al igual que los if
s dentro de otros if
s, es posible meter bucles dentro de
otros.
Por ejemplo:
Nótese que sentencia1
está dentro del primer bucle, que solo da 5 vueltas. El
segundo bucle está también dentro del primero, por tanto también se repite
5 veces. Por otro lado, sentencia2
se repite 3 veces de cada vez, y en total
3x5=15 veces.