Tutorial de C++ : Control de Estructuras

14.12.09

Control de Estructuras


Un programa usualmente no esta limitado a seguir una secuencia lineal de instrucciones. Durante el proceso se puede bifurcar, repetir el codigo o tomar una decision. Por ese propocito, C++ provee un control de estructura que sirve para especificar que debe hacer nuestro programa, cuando y bajo que circunstancias.

Con la introduccion del control de estructuras vamos ahora introducir un nuevo concepto: las declaraciones compuestas o bloques. Un bloque es un grupo de declaraciones que estan separadas por puntos y comas (;) como todo lo que se declara en C++, pero agrupadas entre llaves { }:

{ declaracion1; declaracion2; declaracion3; }

La mayoria de los controles de estructuras que hemos visto requieren una declaracion generica como parte de la sintaxis. Una declaracion puede ser tan simple (Una instruccion simple termina con punto y coma) o una declaracion compuesta, como la que se acaba de describir. En el caso que queramos la declaracion simple, no necesitamos encerrarlo entre llaves ({ }). Pero en el caso que queramos que la declaracion sea compuesta debe estar entre llaves ({ }), formando un bloque.

Condicional: if y else

La palabra if es usada para ejecutar una declaracion o un bloque solo si la condicion se cumple. Su forma es:

if (condicion) declaracion

Donde la condicion es la expresion que sera evaluada. Si la condicion es verdadera, la declaracion es ejecutada. Si es falsa, la declaracion es ignorada (no ejecutada) y el programa continua despues del condicional. Por ejemplo, el siguiente fragmento de codigo imprime "x es 100" solo si el valor guardado en la variable x es realmente 100:

if (x == 100)
  cout << "x es 100"; 
Si queremos que mas de una declaracion sea ejecutada en caso de que la condicion sea verdadera tenemos que especificarlo en un bloque usando llaves { }:

if (x == 100)
{
   cout << "x es ";
   cout << x;
}

Podemos adicionalmente especificar que queremos que pase si la condicion no se cumple usando la palabra else. Se usa en conjunto con if, su forma de uso es:

if (condicion) declaracion1 else declaracion2

Por ejemplo:

if (x == 100)
  cout << "x es 100";
else
  cout << "x no es 100";

Imprime por pantalla "x es 100" solo si x vale 100, pero si no y solo si no, imprime "x no es 100".

La estructura if + else se puede concatenar con la intencion de verificar un rangos de valores. EL siguiente ejemplo muestra el uso diciendo si el valor guardado en x es positivo, negativo o ninguno de de los (Ej: cero):

if (x > 0)
  cout << "x es positivo";
else if (x < 0)
  cout << "x es negativo";
else
  cout << "x is 0";

Recuerda que si queremos mas de una declaracion sea ejecutada, hay que agruparlos entre llaves { }.

Estructuras de iteracion (bucles o en ingles loops)

Los loops o bucles tienen el propocito de repetir una declaracion una cierta cantidad de veces o mientras una condicion se cumpla.

El loop while


Su formato es:

while (expresion) declaracion

Y su funcion es simplemente de repetir una declaracion mientras la condicion establecida es la expresion sea verdadera. Por ejemplo, vamos hacer un programa que haga una cuenta regresiva usando un while-loop:

// Cuenta regresiva (countdown) usando while

#include
using namespace std;

int main ()
{
  int n;
  cout << "Introduzca el numero para empezar > ";
  cin >> n;

  while (n>0) {
    cout << n << ", ";
    --n;
  }

  cout << "FIRE!\n";
  return 0;
}

Cuando el programa empieza se le pide al usuario que coloque un numero para comenzar el conteo. Despues while-loop empieza, si el valor introducido por el usuario cumple la condicion n>0 (n es mayor que cero) el bloque sera ejecutado y se repetira mientras la condicion (n>0) siga siendo verdadera.

Todo el proceso el programa anterior se puede interpretar de la siguiente manera (empezando en main):

1. El usuario le asigna un valor a n
2. La condicion while se verifica (n>0). En este punto hay dos posibilidates:
    * si la condicion es verdadera: la declaracion es ejecutada (ir al paso 3)
    * si la condicion es falsa: se ignora la declaracion y continua despues de eso (ir al paso 5)
3. Ejecuta la declaracion:
    cout << n << ", ";
    --n;

    (imprime el valor de n en la pantalla y disminuye n por 1)
4. Termina el bloque. Regresa automaticamente al paso 2.
5. Continua el programa despues del bloque: imprime FIRE! y finaliza el programa.

Cuando creamos el loop con while, tenemos que considerar que tiene que finalizar en un punto, por eso tenemos que declarar dentro del bloque algun metodo que force a la condicion a ser falsa en algun momento, de otra manera el loop continuara por siempre. En este caso se ha incluido --n; que disminuye el valor de la variable que se esta evaluando en la condicion (n) por uno, esto eventualmente hara que la condicion (n>0) sea falsa despues de ciertos ciclos: para ser mas especificos, cuando n sea 0, donde nuestro bucle y contador terminan.

Por supuesto esto es una simple accion para nuestra computadora, donde todo el proceso del contador se lleva a cabo sin ningun retardo entre los numeros.

El bucle do-while


EL formato es:

do declaracion while (condicion);

Esta funcion es exactamente la misma al del bucle while, execto la condicion en el bucle do-while donde es evaluada despues de la ejecucion de la declaracion en vez de al principio, permitiendo una ejecucion de la declaracion incluso si la condicion no se cumple. Por ejemplo, el siguiente programa muestra por pantalla cualquier numero introducido hasta que se introduzca 0.

// number echoer

#include 
using namespace std;

int main ()
{
  unsigned long n;
  do {
    cout << "Escriba un numero (0 para finalizar): ";
    cin >> n;
    cout << "Usted Escribio: " << n << "\n";
  } while (n != 0);
  return 0;
}

Salida del programa:
Escriba un numero (0 para finalizar): 12345
Usted Escribio: 12345
Escriba un numero (0 para finalizar): 160277
Usted Escribio: 160277
Escriba un numero (0 para finalizar): 0
Usted Escribio: 0

El bucle do-while se usa normalmente cuando la condicion que determina el final del bucle es determinado dentro de la misma declaracion del bucle, como en el caso anterior, donde lo que el usuario ingresa dentro del bloque es usado para determinar el final del bucle. De hecho si nunca se introduce el valor de 0 en el ejemplo anterior, se le pedira numeros por siempre.

Bucle for


Su formato es:

for (iniciacion; condicion; incremento) declaracion;

Su funcion principal es repetir la declaracion mientras la condicion se mantenga verdadera, como el bucle while. Pero adicional, el for necesita el iniciador y el incremento para la declaracion. Este loop esta especificamente diseñado para repetir la accion con un contador el cual inicia y se va incrementando en cara iteracion o ciclo.

Funciona de la siguiente manera:

1. El iniciador es ejecutado. Generalmente es un valor asignado a una variable que funcionara como contador.
2. La condicion es revisada. Si es verdadera el bucle continuara, de otra menra el bucle terminara y la declaracion no se ejecutara.
3. La declaracion es ejecutada. Puede ser una declaracion simple o un bloque encerrado entre llaves { }.
4. Lo que este especificado en el campo de incremento es ejecutado y el bucle regresara al paso 2.

Este es un ejemplo de un contador usando el bucle for:

// Contador usando un loop con for
#include 
using namespace std;
int main ()
{
  for (int n=10; n>0; n--) {
    cout << n << ", ";
  }
  cout << "FIRE!\n";
  return 0;
} 
 
Salida del programa:
10, 9, 8, 7, 6, 5, 4, 3, 2, 1, FIRE! 

Los campos inicializacion y el de incremento son opcionales. Pueden estar vacios, pero en cualquiera de los casos los puntos y comas debe estar escrito. Por ejemplo: for (;n<10;) si no queremos especificar ninguna iniciacion o incremento, o for (;n<10;n++) si queremos incluir el campo de incremento pero sin iniciacion (Puede ser que la variable  ya este iniciada desde antes).

Opcionalmente, usando el operador de coma (,) podemos especificar mas de una exprecion en cualquiera de los campos para el bucle for, como en el de iniciacion por ejemplo. El operador coma (,) es un separador de expresiones, sirve para separar mas de una expresion donde una es generalmente esperada. Por ejemplo: suponga que queremos iniciar mas de una variable en el loop:

for ( n=0, i=100 ; n!=i ; n++, i-- )
{
    // Cuaquier cosa...
}

Este bucle sera ejecutado 50 veces si n o i son modificados dentro del bucle:




n empieza con un valor de 0, y i con un valor de 100, el condicional es n!=i (si n no es igual a i). Porque n es incrementado por uno y i va disminuyendo con uno, la condicion del bucle sera falsa en el ciclo 50, cuando los dos tanto n como i sean igual a 50.

Saltar declaraciones


La declaracion break

Usando el break podemos salir de un loop incluso si la condicion no ha finalizado. Es usado para terminar con un loop infinito, o para forzarlo a terminar antes de su final natural. Por ejemplo, vamos a terminar la cuenta de regresiva antes del final normal (puede ser que hubo un error):

// ejemplo de break loop

#include 
using namespace std;

int main ()
{
  int n;
  for (n=10; n>0; n--)
  {
    cout << n << ", ";
    if (n==3)
    {
      cout << "contador abortado!";
      break;
    }
  }
  return 0;
}
 
Salida del programa:
10, 9, 8, 7, 6, 5, 4, 3, contador abortado!

La declaracion continue

Hace que el programa omita la actual iteracion en el bucle, haciendo un salto al principio. Por ejemplo, omiteremos el numero 5 en la cuenta regresiva:

/ continue loop example
#include 
using namespace std;

int main ()
{
  for (int n=10; n>0; n--) {
    if (n==5) continue;
    cout << n << ", ";
  }
  cout << "FIRE!\n";
  return 0;
}
 
Salida del programa:
10, 9, 8, 7, 6, 4, 3, 2, 1, FIRE! 

La declaracion goto

goto permite hacer un salto a otro punto en el programa. Debes usar esta opcion con precaucion ya que su ejecucion hace un salto incondicional ignorando cualquier tipo de limitacion de anidacion.

El punto de destino esta identificado por una etiqueta, que es usado como argumento para la declaracion de goto. Una etiqueta se hace con los dos puntos (:) como ientificador valido.

Generalmente esta instruccion no es usada en programacion estructurada u orientada a objetos. Un ejemplo, de su uso con un contador:


// Ejemplo de un loop con goto

#include 
using namespace std;

int main ()
{
  int n=10;
  loop:
  cout << n << ", ";
  n--;
  if (n>0) goto loop;
  cout << "FIRE!\n";
  return 0;
} 
 
Salida del programa:
10, 9, 8, 7, 6, 5, 4, 3, 2, 1, FIRE!

Estructura de seleccion: switch

La sintaxis de la declaracion del switch es un poco peculiar. El objetivo es verificar varios posibles valores de constantes de una expresion. Algo parecido a lo que se hizo al principio de esta seccion con la instruccion if y else if. Su forma se escribe:

switch (expresion)
{
  case constante1:
     grupo de declaracion 1;
     break;
  case constante2:
     grupo de declaracion 2;
     break;
  .
  .
  .
  default:
     grupo de declaracion por defecto
}

Trabaja de la siguiente manera: switch evalua la "expresion" y verifica si es equivalente a la "constante1", si lo es, ejecuta el "grupo de declaracion 1" hasta que consigue la declaracion break. Cuando consigue la declaracion break el programa hace un salto hasta el final de la estructura del switch.

Si la expresion no es igual a la "constante1" lo verifica con la "constante2". Si lo es, ejecutara el "grupo de declaracion 2" hasta que consigue la declaracion break y hace un salto hasta el final de la estructura selectiva del switch.

Finalmente, si el valor de la expresion no concuerda con ninguna constante especificada (puedes incluir tantas etiquetas "case" como necesites), el programa ejecutara la declaracion incluida desdes de la etiqueta "default:", si existe (ya que es opcional).

Estos dos fragmentos de codigos tienen el mismo comportamiento:

ejemplo switch
equivalente con if-else
switch (x) {
  case 1:
    cout << "x es 1";
    break;
  case 2:
    cout << "x es 2";
    break;
  default:
    cout << "valor de x desconocido";
  }
if (x == 1) {
  cout << "x es 1";
  }
else if (x == 2) {
  cout << "x es 2";
  }
else {
  cout << "valor de x desconocido";
  }

La declaracion switch es un poco peculiar en el lenguaje C++ porque usa etiquetas en vez de bloques. Esto nos obliga a usar la declaracion break despues del grupo de instrucciones que queremos que sean ejecutadas con cierta condifcion. De lo contrario las declaraciones restantes (incluyendo las otras etiquetas) seran ejecutadas hasta el final del switch o hasta que consiga la declaracion break.

Por ejemplo, si no incluimos la instruccion break en el primer case, el programa no saltara hasta el final del switch y ejecutara el resto de las declaracion hasta que consiga la instruccion break o llegue al final del switch. Esto hace innecesario incluir llaves () alrededor de las declaracion de cada case, y puede ser util ejecutar el mismo bloque de instruccion para diferentes valores posibles para la expresion que se esta evaluando. Por ejemplo:

switch (x) {
  case 1:
  case 2:
  case 3:
    cout << "x es 1, 2 es 3";
    break;
  default:
    cout << "x no es 1, 2 o 3";
  }

Note que el switch solo puede ser usado para comparar expresiones en contra de constantes. Por lo tanto no podemos colocar una variable en las etiquetas (por ejemplo case n: donde n es una variable) o rangos (case (1..3):) porque no son constantes validas en C++.

Si necesita verificar rangos o valores que no son constantes, use una concatenacion de if y else if.


Traduccion de la pagina: http://cplusplus.com/doc/tutorial/control/


Jhyx

0 comentarios:

Creative Commons License
Esta obra está bajo una licencia de Creative Commons.