Bienvenido sean a este post, hoy veremos como  se maneja y manipula el flujo y la interaccion de los programas, aca explicaremos algunas instrucciones que se complementan con el comando IF y que nos permiten desarrollar un poco mejor las determinaciones que debe evaluar el programa en si. En primera instancia voy a hablar un poco del comando goto, que me sorprende que este en C++, como dato anecdotico y por un si acaso pero como aprendi con el tiempo (ya que en Basic de la Commodore se usaba a full) no es el mejor metodo para trabajar con un lenguaje ya que dificulta su seguimiento en caso de falla y a veces hace confuso la comprension de la logica del programa en si, pero vamos a ver el caso. El comando goto se compone de 2 partes la etiqueta, la misma se identifica con un nombre seguido de 2 puntos (:) en el lado izquierdo del codigo, que vamos a asignar a la parte del programa que tiene que saltar y el comando en si que es goto etiqueta, veanlo en este ejemplo:

goto.cpp

# include <iostream>

using namespace std;

int main()
{
        int contador = 0;
        ciclo:
        contador++;
        cout << "contador: " << contador << endl;
        if (contador < 5)
                goto ciclo;
        cout << "Completo. Contador: " << contador << endl;
        return 0;
}

Este programa es un simple contador, donde primero establecera una variable llamada contador, luego pondremos la etiqueta, ciclo, incrementaremos en uno, luego lo mostraremos en pantalla, el condicional chequeara si contador es menor a 5, en caso afirmativo usara el goto para ir a la etiqueta y volvera a ejecutar el incrementador, una vez cumplida la condicion mostrara un mensaje y saldra del programa. Si lo compilamos y ejecutamos:

tinchicus@dbn001vrt:~/programacion/c++$ ./program/goto
contador: 1
contador: 2
contador: 3
contador: 4
contador: 5
Completo. Contador: 5
tinchicus@dbn001vrt:~/programacion/c++$

Como dije anteriormente el comando goto no es recomendado como una buena practica pero si se utiliza sabiamente puede ser una herramienta util, sigamos con el resto.
El comando while se utiliza para ejecutar un ciclo (o bucle) de funciones mientras la condiciion sea verdadera, La estructura basica es la siguiente:

while(condicion)
{
... instrucciones ...
}

Veamos como reemplazamos el comando goto con el while para una mayor practicidad con el siguiente ejemplo:

while.cpp

# include <iostream>

using namespace std;

int main()
{
        int contador=0;
        while(contador < 5)
        {
                contador++;
                cout << "Contador: " << contador << endl;
        }
        cout << "Completo. Contador: " << contador << endl;
        return 0;
}

Como se ve en el caso resulta mucho mas practico hacer un bucle con el comando while que no solamente nos simplifica y nos permite tener un mejor control del programa dado que las instrucciones que solamente competen al bucle quedan contenidas en el mismo y no tenemos que hacer una busqueda exhaustiva desde donde comienza el mismo a traves de la etiqueta, si lo compilan y prueban deberan obtener el mismo resultado que el ejercicio anterior. Ahora veamos como seria un bucle mas complejo a traves de los condicionales AND, OR y NOT que ayudan a la evaluacion de la condicion. Veamoslo con el siguiente ejemplo:

while01.cpp

# include <iostream>

using namespace std;

int main()
{
        unsigned short chico;
        unsigned long grande;
        const unsigned short MAXCHICO=65535;
        cout << "Escriba un numero chico: ";
        cin >> chico;
        cout << "Escriba un numero grande: ";
        cin >> grande;
        cout << "chico: " << chico << "..." << endl;
        while (chico < grande && grande > 0 && chico < MAXCHICO)
        {
        if (chico % 5000 == 0)
                cout << ".";
        chico++;
        grande -=2;
        }
        cout<< "\nChico: " << chico << " Grande: "<< grande << endl;
        return 0;
}

En este ejemplo utilizaremos dos variables una llamado chico y otra grande, luego tendremos una constante llamado MAXCHICO, luego por medio de dos metodos cin le asignamos un valor a chico y otro a grande, mostraremos el valor de chico y luego pasaremos al while, en este caso el condicional se lee asi: mientras (while) chico sea menor que grande Y grande sea mayor a cero Y chico sea menor a MAXCHICO, mientras estas tres condiciones sean verdaderas se repetira el ciclo hasta que cualquiera de las tres no se cumpla mas y salga del bucle, esto es debido al AND utilizado porque para esta logica si debe devolver un verdadero todas las condiciones deben ser verdaderas, analicemos el bucle. El condicional mostrara un punto si el calculo del residual de chico dividido por 5000 es igual a cero, luego en el siguiente paso incrementara en uno el valor de chico, y por otro lado restara en dos al valor de grande. Una vez finalizado el bucle nos mostrara el valor de chico y el valor de grande despues del bucle. Si lo compilamos y ejecutamos tendremos esta salida:

tinchicus@dbn001vrt:~/programacion/c++$ ./program/while01
Escriba un numero chico: 1
Escriba un numero grande: 100000
chico: 1…
……
Chico: 33334 Grande: 33334
tinchicus@dbn001vrt:~/programacion/c++$

Pasemos a ver otros recursos interesantes en while, estos son los metodos continue y break, el primer metodo nos devolvera al principio de nuestro bucle creado por while, el segundo metodo nos quitara del bucle, esto es ideal para saltar u omitir un proceso del bucle o salir cuando se cumple una condicion, veamos su funcionamiento por medio del siguiente ejemplo:

while02.cpp

# include <iostream>

using namespace std;

int main()
{
        unsigned short chico;
        unsigned long grande;
        unsigned long salto;
        unsigned long destino;
        const unsigned short MAXCHICO=65535;
        cout << "Escriba un numero chico: ";
        cin >> chico;
        cout << "Escriba un numero grande: ";
        cin >> grande;
        cout << "Escriba un valor de salto: ";
        cin >> salto;
        cout << "Escriba un valor de destino: ";
        cin >> destino;
        cout << endl;

        while (chico < grande && grande > 0 && chico < MAXCHICO)
        {
        chico++;
        if (chico % salto == 0)
        {
                cout << "Salto en " << chico << endl;
                continue;
        }
        if (grande == destino)
        {
                cout << "Destino alcanzado!";
                break;
        }
        grande -=2;
        }
        cout << "\nChico: " << chico << " Grande: ";
        cout << grande << endl;
        return 0;
}

En este ejemplo vamos a tener cuatro valores para ingresar, chico y grande como antes, pero ahora agregaremos un valor llamado salto y otro destino, seguiremos con la constante MAXCHICO, el condicional while es exactamente igual al anterior, tambien incrementaremos chico en uno y reduciremos a grande en dos, desaparecio el condicional que mostraba el punto pero agregamos dos, veamos el primer condicional:

if (chico % salto == 0)     
{
cout << "Salto en " << chico << endl;
continue;
}

Este condicional chequea si el residual de chico con la division de salto es igual a cero muestra el mensaje del bloque y despues ejecuta continue, esto evitara el resto del bucle y volvera al principio, pasemos al segundo condcional:

if (grande == destino)     
{
cout << "Destino alcanzado!";
break;
}

Este condiciona chequea si grande es igual a destino, en caso afirmativo mostrara el mensaje y saldra del bucle while por medio del break, interrumpiendo el mismo, luego por fuera del bucle mostraremos en que estado estan los valores de chico y grande. Si los compilamos y ejecutamos podremos tener dos tipos de salida:

Salida de ejemplo por medio de continue:

tinchicus@dbn001vrt:~/programacion/c++$ ./program/while02
Escriba un numero chico: 2
Escriba un numero grande: 20
Escriba un valor de salto: 4
Escriba un valor de destino: 5

Salto en 4
Salto en 8

Chico: 10 Grande: 8
tinchicus@dbn001vrt:~/programacion/c++$

Salida de ejemplo por medio de break:

tinchicus@dbn001vrt:~/programacion/c++$ ./program/while02
Escriba un numero chico: 2
Escriba un numero grande: 20
Escriba un valor de salto: 4
Escriba un valor de destino: 10

Salto en 4
Salto en 8

Destino alcanzado!
Chico: 10 Grande: 10
tinchicus@dbn001vrt:~/programacion/c++$

Estas opciones son como el goto usadas correctamente pueden ser herramientas muy utiles pero en caso contrario dificultan mucho la evaluacion e incrementan la ilegibilidad del mismo. Otra opcion valida dentro de while es que se puede usar el valor true para generar un bucle infinito (dado que while solo evalua lo que es verdadero) y este deberia ser cortado por alguna condicion dentro del  mismo. Veamoslo por medio del siguiente ejemplo:

while03.cpp

# include <iostream>

using namespace std;

int main()
{
        int contador=0;
        while(true)
        {
                contador++;
                if (contador > 10)
                        break;
        }
        cout << "Completo. Contador: " << contador << endl;
        return 0;
}

En este ejemplo podemos ver que de la unica forma que se tiene para salir del bucle es cuando contador llega a 10 y ejecuta un break. Mientras esta en el bucle incrementa el valor de contador, esto tambien es ideal para hacer un bucle mientras espera un condicion externa para detenerlo, probemos de compilarlo y ejecutarlo:

tinchicus@dbn001vrt:~/programacion/c++$ ./program/while03
Completo. Contador: 11
tinchicus@dbn001vrt:~/programacion/c++$

Hasta aca seguramente estas pensando que bonito que es hacerlo con while pero como dijimos anteriormente el ciclo se ejecuta siempre y cuando la condicion sea verdadera y en caso de ser falsa omite completamente las instrucciones contenidas en el mismo, ahora para evitar esto ya que algunas veces vamos a necesitar que se ejecute a pesar de que la condicion no sea verdadera para esto se implementa el while desde otro modo, do…while. Veamos un ejemplo de lo que sucede en ambos casos:

while04.cpp

# include <iostream>

using namespace std;

int main()
{
        int contador,contadorw,contadord;
        cout << "Cuantos holas???:";
        cin >> contador;
        contadorw=contador;
        contadord=contador;
        while (contadorw > 0)
        {
                cout << "Hola\n";
                contadorw--;
        }
        cout << "Contador del while: " << contadorw << endl;
        cout << "Hasta aca fue el ciclo de while.\n";
        cout << "Ahora veamos el de do..while" << endl;
        do
        {
                cout << "Hola\n";
                contadord--;
        }
        while (contadord > 0);
        cout << "Contador del do...while: " << contadord << endl;
        return 0;
}

En este ejemplo tendremos los dos casos, el primero con while, y el segundo con do…while, antes de analizarlo veamos la salida del programa, para ello lo compilamos y ejecutamos:

tinchicus@dbn001vrt:~/programacion/c++$ ./program/while04
Cuantos holas???:5
Hola
Hola
Hola
Hola
Hola
Contador del while: 0
Hasta aca fue el ciclo de while.
Ahora veamos el de do..while
Hola
Hola
Hola
Hola
Hola
Contador del do…while: 0
tinchicus@dbn001vrt:~/programacion/c++$

En este caso no se ve bien el ejemplo de como trabaja porque para este caso muestra la misma cantidad de hola que solicitamos pero la diferencia radicaria para el primer caso en caso de cumplirse una condicion falsa omitiria el bloque de instrucciones, en cambio para el segundo caso haria la accion pero luego saldria del bucle si la condicion es falsa, pasemos a ver el caso de for, el comando for consta de 3 partes, un valor de inicio, la condicion y el operador, en general se utiliza como contadores para repetir una instruccion una X cantidad de veces, la estructura basica es esta:

for(valor inicial;condicion;operador)
instruccion;

A traves del siguiente ejemplo, de como se utilizaria en el caso de un programa:

for.cpp

# include <iostream>

using namespace std;

int main()
{
int contador;
        for(contador = 0; contador <5; contador++)
        cout << "Loopeando a lo loco!!!\n";
        cout << "Completo. Contador: " << contador << endl;
        return 0;
}

En este programa nos centraremos en el metodo for, observen como primero establecemos el valor inicial de contador, luego usamos una condicion como limite, en este caso se leeria mientras sea menor a cinco, y por ultimo incrementaremos el valor de contador por cada vuelta, en este caso no establecimos el bloque por lo que el for cosidera que la siguiente linea es la unica para hacer el bucle, en caso de necesitar mas de una instruccion es necesario utilizar el bloque, una vez finalizado nuestro bucle mostramos el mensaje de completo y salimos del programa, compilemos y probemos:

tinchicus@dbn001vrt:~/programacion/c++$ ./program/for
Loopeando a lo loco!!!
Loopeando a lo loco!!!
Loopeando a lo loco!!!
Loopeando a lo loco!!!
Loopeando a lo loco!!!
Completo. Contador: 5
tinchicus@dbn001vrt:~/programacion/c++$

Pasemos a ver como se puede utilizar el for de un modo mas avanzado, como dijimos anteriormente el comando for consta de 3 partes, entre ellas la llamada operador. Esta puede ser multiple, si bien la condicion deberia ser una sola, se pueden utilizar varias operaciones en ese campo, veamos un breve ejemplo:

for (i=0, j=0; i<3; i++, j++)

En este caso incrementaremos a i y j mientras i sea menor que 3, en el for tambien se pueden dejar valores nulos, o sea que no es obligatorio que esten los 3 campos completos, por ejemplo se puede usar solamente la condicion y despues en la estructura del bucle se efectua la operacion que hara terminar el mismo cuando la condicion se cumpla, de caso contrario quedara en un eterno bucle, tambien se puede no declarar nada y que en la estructura haya un if que lleve a un break para salir del bucle. Para lograr hacer esto y que el programa no de error, se debe utilizar los punto y coma (;) para que el programa entienda que los campos tienen un valor nulo, en el caso de que solamente queremos declara una condicion seria asi:

for (;i<3;)

Ahora en el caso de que todos sean nulos seria asi:

for(;;)

Los ciclos for tambien pueden ser vacios ya que para una operacion sencilla esta puede estar contenida dentro del campo de operador del for, lo unico que despues de la linea debemos poner un punto y coma (;), la sintaxis seria algo asi:

for(i=0;i<3;cout << "i: " << i++ << endl);

y por ultimo lo que se puede hacer es anidar internamente ciclos for, vamos a ver un ejemplo que contiene las distintas formas de expresar el for, como se puede representar y que funcion pueden cumplir:

for00.cpp

# include <iostream>

using namespace std;

int main()
{
        int j,i=0;
        int filas, columnas;
        char letra;
        cout << "Cuantas filas?: ";
        cin >> filas;
        cout << "Cuantas columnas?:";
        cin >> columnas;
        cout << "Ingresa un caracter: ";
        cin >> letra;
        for (;;)
        {
                if (i<filas)
                {
                        for(j=0;j<columnas; j++, cout << letra);
                }
                else
                        break;
                cout << endl;
                i++;
        }
        return 0;
}

En este ejemplo manejaremos tres datos, uno para las columnas, otro para las filas y una letra como caracter, tambien tendremos dos variables, i y j, las cuales se encargaran de controlar primero el condicional de las filas y otro para el bucle de las columnas, nuestro primer bucle for es infinito porque carece de cualquiera de las condiciones para terminar, luego tendremos un condicional donde chequeara que i sea menor que el valor de filas, en caso de ser verdadero ejecutara un bucle for donde imprimira el caracter informado una vez finalizado saldra del condicional e incrementara en uno a i, cuando no se cumpla mas la condicion del condicional saldra del primer bucle for por medio del break y finalizara el programa, compilemos y ejecutemos para ver su salida:

tinchicus@dbn001vrt:~/programacion/c++$ ./program/for00
Cuantas filas?: 4
Cuantas columnas?:10
Ingresa un caracter: x
xxxxxxxxxx
xxxxxxxxxx
xxxxxxxxxx
xxxxxxxxxx
tinchicus@dbn001vrt:~/programacion/c++$

Observen como hizo las cuatro filas solicitadas y las diez columnas solicitadas con el caracter informado, x, prueben con otros valores y vean los resultados. el bucle for es muy bueno para enumerar, enlistar o crear una opcion para que nos repita una solicitud hasta que demos la salida por medio de una intencion a traves del break, pasemos al siguiente ciclo el cual es el switch.

El comando switch toma una variable (la que se le indica que debe verificar), extrae el dato contenido en el mismo y lo compara con las condiciones que tiene declarada, en el caso de no coincidir con ninguna tiene un valor default (declarado por nosotros) que es el que va a devolver pero en caso contrario ejecuta las instrucciones que estan contenidas dentro de cada caso (case), todos los casos al final deben tener declarado un break porque de caso contrario cuando termine de ejecutar esas instrucciones pasara a la siguiente y asi sucesivamente hasta que encuentre un break o termine la funcion switch. La sintaxis es asi:

switch(variable)
{
	case valor1:
		instrucciones
		break;

	case valor2:
		instrucciones
		break;

	case valorN:
		instrucciones
		break;

	default:
		instrucciones
		break;
}

Veamos la funcionalidad de este metodo por medio del siguiente ejemplo:

switch.cpp

# include <iostream>

using namespace std;

//prototipos

int menu();
void HacerTareaUno();
void HacerTareaMuchos(int);

int main()
{
        bool salir=false;
        for(;;)
        {
                int opcion = menu();
                switch(opcion)
                {
                        case (1):
                                HacerTareaUno();
                                break;
                        case (2):
                                HacerTareaMuchos(2);
                                break;
                        case (3):
                                HacerTareaMuchos(3);
                                break;
                        case (4):
                                continue;
                                break;
                        case (5):
                                salir=true;
                                break;
                        default:
                                cout << "Selecciona otra vez!\n";
                                break;
                }
                if (salir)
                        break;
        }
        return 0;
}

int menu()
{
        int opcion;
        cout << " **** Menu **** \n\n";
        cout << "(1) Opcion Uno \n";
        cout << "(2) Opcion Dos \n";
        cout << "(3) Opcion Tres \n";
        cout << "(4) Volver a desplegar menú \n";
        cout << "(5) Salir \n";
        cout << ": ";
        cin >> opcion;
        return opcion;
}

void HacerTareaUno()
{
        cout << "Tarea Uno!\n";
}

void HacerTareaMuchos(int cual)
{
        if (cual == 2)
        cout << "Tarea Dos!\n";
        else
        cout << "Tarea tres!\n";
}

En este ejemplo pusimos varios temas en practica primero creamos los prototipos de nuestros tres metodos, luego en el cuerpo de main() hicimos un bucle for indefinido para que se repita hasta que lo hagamos salir, vean como lo primero que creamos es una variable llamada opcion a la cual le asignamos el metodo menu(), el cual nos mostrara el menu con las opciones y eligiendo una volveremos al cuerpo del main(), el siguiente paso es un switch() que evaluara el valor asignado a opcion por medio del metodo menu(), en este caso lo evaluara de la siguiente manera:

  • case (1), elegimos la opcion uno por ende ejecutara el metodo llamado TareaUno()
  • case (2), elegimos la opcion dos y esta llamara a la tarea HacerTareaMuchos() pero le enviara el valor 2
  • case (3), elegimos la opcion tres y esta llamara a la tarea HacerTareaMuchos() pero le enviara el valor 3
  • case (4), vuelve a mostrar el menu por medio del continue que vuelve al principio del bucle y despliega el menu
  • case (5), llama al break, sale del bucle y por ende termina el programa.
  • default, muestra un mensaje cuando no se selecciona ninguna opcion correctamente

Despues tendremos las tres definiciones de nuestros metodos, menu() se encarga de mostrarnos las opciones disponibles, despues tenemos el metodo TareaUno() para mostrar un mensaje y por ultimo el metodo HacerTareaMuchos() que dependiendo del valor que le enviamos mostrara un mensaje u otro, compilemos y probemos nuestro programa:

 tinchicus@dbn001vrt:~/programacion/c++$ ./program/switch
**** Menu ****
(1) Opcion Uno
(2) Opcion Dos
(3) Opcion Tres
(4) Volver a desplegar menú
(5) Salir
: 1
Tarea Uno!
**** Menu ****
(1) Opcion Uno
(2) Opcion Dos
(3) Opcion Tres
(4) Volver a desplegar menú
(5) Salir
: 3
Tarea tres!
**** Menu ****
(1) Opcion Uno
(2) Opcion Dos
(3) Opcion Tres
(4) Volver a desplegar menú
(5) Salir
: 4
**** Menu ****
(1) Opcion Uno
(2) Opcion Dos
(3) Opcion Tres
(4) Volver a desplegar menú
(5) Salir
: 5
tinchicus@dbn001vrt:~/programacion/c++$

Observen como nos repitio el menu siempre y cuando no seleccionaramos la opcion 5, para estos casos switch es una mejor opcion que estar concatenando if o if…else para cubrir todas las posibles opciones, igualmente mas adelante cuales son los pros y contras de este y los otros metodos.
En resumen hoy hemos visto como se puede controlar el flujo de un programa, sea por medio de if, un while, un do…while, de un for o de un switch, como los mismos pueden integrarse entre si, formas mas avanzadas de crear un contador o una forma muy basica de poder crear un menu, espero les haya sido util sigueme en Twitter, Facebook o Google+ para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Anuncios