# Estructuras de control

Hay dos maneras de cambiar el rumbo de ejecución de un programa, estos pueden ser saltos incondicionales y saltos condicionales. En este capítulo se describen algunas de estas sentencias. Algunas son muy similares a las existentes en otros lenguajes, como las sentencias if, for, while, etc. y otras, como foreach, throw o continue, son algo más específicas.

## Saltos incondicionales

Las instrucciones de un programa se ejecutan sentencia por sentencia empezando desde el método o función principal llamado Main hasta terminar con el programa. El programa sin embargo, tomará otros rumbos incondicionalmente en dos oportunidades: 1. Cuando encuentre la llamada a otros métodos (Ejemplo 4.1) y 2. Con el uso de las palabras claves como goto, break, continue, return y throw las cuales se discutirán más adelante.
Ejemplo 4.1 - Salto incondicional a otra función
En el ejemplo anterior el programa ejecuta sentencia por sentencia el método principal Main hasta que encuentra la llamada a otro método. Después de que el método llamado haya terminado el método Main continuará con la ejecución de las sentencias restantes.

### La sentencia goto

En los inicios de los lenguajes de programación la sentencia goto fue la más popular para ir de un lugar a otro dentro del programa. Sin embargo esto creaba una tremenda confusión al momento de diseñar la aplicación. Si el programador quería hacer un esquema de como funcionaba dicha aplicación, se veía con un laberinto tipo espagueti de líneas y símbolos conectados entre sí. Es por esto que esta sentencia es un poco "problemática" y fuera de "moda" entre los lenguajes de programación modernos. C# sin embargo soporta esta sentencia. Os recomendamos no utilizarla a menos que sea necesario o si os sentís cómodos haciéndolo, pero cuando os cree un laberinto difícil de depurar, no digáis que no os advertimos de no utilizarla. Hay muchas otras mejores maneras de cumplir con el mismo propósito (la sentencia while por ejemplo es una de ellas), las cuales son más elegantes y más sencillas de depurar.
La sentencia goto funciona de la siguiente manera:
Primero se crea una etiqueta al inicio de cierto bloque de código y después en otro lugar podemos saltar hacia esa etiqueta usando la palabra clave goto. El siguiente ejemplo ilustra la sentencia goto:
Esta sentencia es un ejemplo de salto incondicional ya que por si solo saltará a la etiqueta seleccionada incondicionalmente.

## Saltos condicionales

Los saltos condicionales sirven para ejecutar cierto código solamente si se cumple con alguna condición. Entre otros tenemos:

### Instrucción if

Esta sentencia sirve para ejecutar unas instrucciones en caso de que se cumpla determinada condición. La forma completa de la instrucción if es
donde la cláusula else es opcional. Si la condición es verdadera, se ejecutarán las instrucciones dentro del bloque if, mientras que si es falsa, se ejecutará el bloque else. El valor que controla la sentencia if debe ser de tipo bool. El siguiente ejemplo
te pide que introduzcas un número y dependiendo de si se cumple que dicho número es mayor que cero (condición), se ejecuta un bloque u otro.
La sentencia d = Double.Parse( Console.ReadLine ); tal vez requiera algo de explicación adicional. En realidad, con Console.ReadLine estamos leyendo lo que el usuario introduce por pantalla, que es una cadena de caracteres, y con Double.Parse lo que hacemos es interpretar esa cadena de caracteres y convertirla en un tipo numérico double, de forma que tendrá el valor del número que introduzcamos por la consola.
Las intrucciones if se pueden anidar, y existe también una extensión de la sentencia if, la sentencia if-else-if. Su formato es el siguiente:
Las instrucciones condicionales se evalúan de arriba a abajo. Tan pronto como se encuentra una condición true, se ejecuta la instrucción asociada con ella, y el resto de la escalera se omite. Si ninguna de las condiciones es true, se ejecutará la última instrucción else. La última instrucción else actúa como condición predeterminada, es decir, si no funciona ninguna de las otras pruebas condicionales, se realiza esta última instrucción. Si no existe esta instrucción else final y el resto de de las condiciones son falsas, entonces no se realizará ninguna acción. El siguiente ejemplo
le pide al usuario que elija una opción si/no y la procesa usando una estructura if-else-if. Si la opción no es ni "si" ni "no", entonces se ejecuta la sentencia else por defecto, que imprime por pantalla el mensaje "No entiendo lo que ha escrito"

### Instrucción switch

La instrucción switch es muy parecida a la estructura if-else-if, sólo que permite seleccionar entre varias alternativas de una manera más cómoda. Funciona de la siguiente manera: el valor de una expresión se prueba sucesivamente con una lista de constantes. Cuando se encuentra una coincidencia, se ejecuta la secuencia de instrucciones asociada con esa coincidencia. La forma general de la instrucción switch es la siguiente:
La sentencia default se ejecutará sólo si ninguna constante de las que siguen a case coincide con expresión. Es algo similar al else final de la instrucción if-else-if.
Sin más, vamos a por un ejemplo
El cual solicita al usuario que inserte uno de los símbolos +-*/ , y con un switch compara los resultados para hacer diferentes acciones dependiendo del valor de s, que es la cadena de caracteres que almacena la elección del usuario. El resultado debería ser algo parecido a esto:
Como habrá notado, al final de todo case siempre hay una sentencia break. Esto no es obligatorio, puede haber en su lugar otra sentencia de salto como un goto inclusive en el caso default.
Siempre se deberá tener un break o un goto en cada caso a menos que la sentencia esté vacía. En esta situación se ejecutará el siguiente caso que viene en la lista. Si no se toma en cuenta ésto se obtiene un error en tiempo de compilación. Otros lenguajes, como C/C++ o Java no tienen esta restricción. La razón de adoptarla en C# es doble: por un lado, elimina muchos errores comunes y en segundo lugar permite al compilador reorganizar las sentencias de los case, y así permitir su optimización.
Ejemplo:
Como bien se puede notar en el ejemplo, en el case 4, se utiliza la instrucción goto, indicando que se vaya al case 1, ya que según la lógica del ejemplo, es igual elegir 1 o 4. Nótese que no es necesario usar break; en el case 4 ya que se utilizó goto.

### Bucle for

El bucle for de C# es idéntico al encontrado en los lenguajes C/C++ y Java. El formato general es
Las sentencias de inicialización se ejecutan una vez al principio y sirven principalmente para asignar valores a las variables que servirán de contador. Las sentencias de condición, por su parte, se ejecutan cada vez que el bucle vuelve al principio y sirven para controlar el bucle: éste seguirá realizándose siempre y cuando estas condiciones sean true. Las sentencias de iteración se ejecutan también cada vez que se realiza una nuevo ciclo en el bucle, y sirven para cambiar el estado de las variables que gobiernan las sentencias de condición. Pero todo esto se entiende mejor con un ejemplo
Este ejemplo imprime por pantalla los 10 primero enteros positivos. Es un caso muy simple del bucle for. Por cierto, el operador ++ lo que hace es que añade una unidad a la variable a la que acompaña, de forma que, por ejemplo, 9++ es 10. De esta forma, la variable i se incrementa a cada vuelta.
En el ejemplo anterior, las sentencias de inicialización y de iteración eran únicas, pero esto no tiene por qué ser así, de hecho se pueden utilizar varias sentencias separadas por comas. Por ejemplo, se pueden usar dos variables para controlar el bucle
Por su parte, la expresión condicional del bucle for puede ser cualquier expresión que genere un valor booleano. En este caso se ha usado "i<j", pero también hubiera sido válida "i==5", "true" (el bucle se realizará indefinidamente) o "false" (el bucle no se realizará).

### Bucle while

El bucle while es un bucle que se realiza mientras se cumpla determinada condición. Tiene la forma
Donde la condición tiene que ser un valor booleano. Tiene una estructura muy sencilla, así que vamos a ver directamente un ejemplo.
En el que se realiza lo mismo que en el ejemplo anterior, sólo que ahora con un bucle while.

### Bucle do-while

Se trata de una ligera variante del bucle anterior, con la diferencia de que ahora primero se ejecutan las instrucciones y luego se evalúa la condición, de forma que tiene tiene una estructura:
El siguiente ejemplo
muestra un programa que ejecuta un bucle hasta que el usuario introduce "si". Por cierto, != es lo contrario de ==, es decir, != devuelve true cuando los valores comparados son distintos.

### Bucle foreach

El bucle foreach se utiliza para hacer iteraciones sobre elementos de una colección, como pueden ser los enteros dentro de un arreglo de enteros. La sintaxis sigue la siguiente estructura:
Como hemos comentado, el uso más inmediato es iterar sobre un arreglo de números:
Este ejemplo sólo imprime los valores de una matriz, pero como se puede comprobar mejora mucho la claridad del código comparándolo con una implementación con bucles for como esta
Además, es posible utilizar el bucle foreach con cualquier tipo que sea una colección, no solo con arreglos, como veremos más adelante.

### Usando continue y break

continue y break son dos palabras clave que nos permiten saltar incondicionalmente al inicio de un bucle (continue) o fuera de un bucle (break) cuando se necesite. Por ejemplo:
Este pequeño programa entrará en un bucle for que hará que la variable i tome los valores del 1 al 10, pero al llegar al número 5 el bucle saltará incondicionalmente al inicio del bucle sin ejecutar las líneas que siguen más adelante por lo que no ejecutará la línea que imprime en la pantalla el número 5. Cosa similar sucede cuando llega al número 9: el bucle será detenido por el salto incondicional break que romperá el bucle cuando encuentre esta palabra. El resultado será el siguiente:
El bucle saltó la línea que imprime 5 y terminó cuando llegó a 9 gracias a las palabras clave continue y break.