Hoy vamos a tratar el problema de las bifurcaciones (dependiendo de un dato haces esto o aquello), de los bucles y algo llamado recursividad. Hasta ahora todo lo que habiamos hecho eran programan que se ejecutaba en el orden en que lo habiamos escrito. Esto no nos da libertad para hacer lo que se necesite en cada momento pues en la ejecucion de un programa siempre estamos sujetos a lo que haga la persona encargada de manejar el programa. Tambien habia en momentos en que se necesitaba repetir n veces un trozo de codigo alterando, o no, una pequeña parte de ese codigo. Hoy todo esto cambia con estas instruccione que nos van a permitir una flexibilidad increible para escribir nuestro programa y solventar algunas situaciones que se nos hayan hecho dificiles o casi imposibles, de una manera rapida, flexible y no muy dificil.
Sentencias de control
Son instrucciones de programacion que nos permiten mantener el control de lo que se hace en cada momento en base a condiciones.
if ... elseif...else
La traduccion dice: si..sino si....sino. Esto es un condicional, nos va a permitir ejecutar bloques de codigo en base a una condicion. Su sintaxis es:
if (condicion) {
....
}
if (condicion && (condicion || condicion)) {
....
}
if (condicion){
....
} else {
....
}
En el tiempo que llevo enseñando me he dado cuenta que la gente tiene problemas con los condicionales.Esto suele venir por una comprension del problema equivocada pensando que la situacion es mas complicada de lo que realmente es.Vamos a ver un detector de colisiones en plan chorras.
Vamos a imaginar un cuadrado de tamaño 10 x 10. En las coordenadas {(3,3),(3,4),(3,5),(4,3),(4,4),(4,5),(5,3),(5,4),(5,5)} Tenemos una columna.
Nosotros cuando nos movemos por un mundo 3d o 2d (da =) movemos nuestro muñeco en base a coordenadas, asi podemos evaluar en que punto nos encontramos en cada instante de tiempo. La sentencia para comprobar si nos damos de morros con la columna es:
if (miscoordenadas >= 3 && miscoordenadas <= 5) { //En la sobrecarga y structs veremos como hacer que esta condicion funcione
meDejoLosDientesEnLaPared(cantidadDientesRestantes); //
} else { //No hay columna
muevoElPersonaje();
}
Esto es muy facil de entender, pero el problema radica en cuanto tenemos que empezar a anidar. Esto es: incluir condiciones dentro de condiciones o basar la ejecucion en n condiciones pudiendo ser distintas.
if (a>b){
printf ("a mayor");
} else if (c printf ("c menor");
} else {
printf ("Ni a es mayor, ni c menor");
}
Veamos la ejecucion paso por paso. Primero comprobamos si a es mayor que b, si es verdadero escribimos amayor en pantalla y acaba. Pero si no es mayor entonces se evalua si c es menor que d, si es verdadero escribimos c menor en pantalla y acaba. En caso contrario se ejecuta el } else { y escribimos en pantalla Ni a es mayor, ni c menor y ya por fin acaba.
else if()
Este se pone al acabar un if, y es la parte de codigo que se ejecuta si la condicion de este (el if inicial) no es verdadera.
switch(...){case 1:...}
El switch es una especie de if pero mas rigido y potente. A diferencia de un if en el cual podemos valorar distintas variables, aqui solo se permite una (de ahi su rigidez), pero nos permite evaluar segun su valor.
Sintaxis:
switch(variable){
case 1: //cuando la variable vale 1
.....
break;//termina la sentencia switch, si no se pone seguira ejecutandose hacia abajo se cumpla o no el case
case 2:
.....
break;
default: //en caso de no haber encontrado una coincidencia en los case anteriores
.....
}
El break es importante usarlo pero no es indispensable. Cuando hacemos uso de el, sale de la sentencia switch. Hay en casos en los que su uso no es necesario. Imaginad que tenemos un programa de gestion, y somos una empresa que hacemos regalos en base al dinero gastado:
10€->llavero, 100€ ->llavero y parking, 1000€->llavero,parking y loquesea... entonces para resolver este problema se puede hacer sin el uso de break.
switch(dinero){
case 1000:
regaloLoquesea();
case 100:
regaloParking();
case 10:
regaloLlavero();
}
Cuando el programa llegue al switch comprobara el valor de dinero, ejecutara el case que le corresponda y seguira ejecutando los case hacia abajo aunque no se cumpla la condicion (amos que despues de evaluar el primero que corresponda, en los subsiguientes ignora el case y ejecuta lo que hay dentro de cada uno de ellos).
for (;;) {...}
Esto es un bucle que se repetira tantas veces como necesitemos. Tenemos dos formas hacerlo finito e infinito. Tal y como esta puesto en el titulo es infinito.
for(variable;condicion;incremento)
Este es un bucle finito, que se ira ejecutando hasta que no se cumpla la condicion. Vemos un ejemplo y lo analizamos.
for (int a=0;a<=10;a++){
.....
} int a=0, esta es la parte de la variable, podemos poner una variable ya inicializada o declarar una especialmente para el bucle. Si hacemos esto ultimo la variable se borrara de memoria una vez terminado el bucle. Importante!! Si declaramos una variable para el bucle no os olvideis de inicializarla osea dadle valor (como en el ejemplo.
a<=10, esto es la condicion. Mientras esta devuelva verdadero se ejecutara el bucle.
a++, con esto vamos aumentando en 1 el valor de a cada vez que se hace una iteraccion del bucle. Tambien podemos poner cosas asi a*=10 , o a +=2.....
No solo se hace de una variable, sino que pueden ser multiples variables.
for (int a=0 , b=10; a <=10 && b<=1000;a++, b*=a)
for(;;)
Este bucle no tiene fin. ¡¡Cuidado!! porque esto puede bloquear el programa. Para poder salir de el deberemos usar la sentencia break
for (;;){
.....
if (lokesea) break; //tambien se puede escribir un if o cualquiera de las sentencias de esta leccion sin {} siempre y
//cuando el bloque de codigo a ejecutar ocupe una sola linea tambien seria valido
// if (lokesea)
// break;
}
while(condicion){...}
Este bucle se usa cuando la ejecucion del bucle no depende de si misma para terminar O_O. mm...pos no me sale mejor explicacion (delicioso sueño). Veamos un ejemplo, tenemos un menu y no podemos hacer nada hasta que no se elija una de las opciones.
#include
#include
void main(){
printf ("Elija una opcion");
int op=0;
while(op<1 || op>2){
scanf("%d",&op);
}
switch (op){
case 1:
printf("Menu 1");
break;
default:
printf("Menu 2");
}
getch();
}
Mientras que no se pulse 1 o 2 no terminara el bucle.
Tambien podemos terminarlo mediante un break.
do{...}while()
Es exactamente igual al anterior pero la condicion se evalua al final del bucle y no al principio, esto sirve para que se cumpla o no la condicion se ejecute una vez el contenido del bucle.
#include
#include
#include
void main(){
int op=0;
do{
clrscr();
printf ("Elija una opcion");
scanf("%d",&op);
}while(op<1 || op>2);
switch (op){
case 1:
printf("Menu 1");
break;
default:
printf("Menu 2");
}
getch();
}
continue
Esto nos servira para poder ejecutar la siguiente iteraccion del bucle. imaginad que quiero mostrar los 10 primeros multiplos de cualquier numero que me digan. El codigo seria asi:
#include
#include
void main(){
int op;
do{
printf("Escriba un numero menor que 100: ");
scanf("%d",&op);
}while(op>100);
for (int a=1; a <=op*10;a++){
if (a%op!=0) continue;
printf("%d\n",a);
}
getch();
}
RECURSIVIDAD
buff...veamos...esta forma de proceder traga recursos sin conicimiento, pero es muy potente y reduce el tamaño del codigo fuente. Esta especificada para bucles de no mucho recorrido y finitos. Consiste en hacer una llamada a una funcion dentro de si misma, esto repercute en un aumento espectacular del uso de la pila. Para un principiante suele ser dificil de comprender e incluso de implementar bien. El programa anterior pero con recursividad.
#include
#include
int recursiva (int a,int op);
void main(){
int op;
do{
printf("Escriba un numero menor que 100: ");
scanf("%d",&op);
}while(op>100);
if (recursiva(0,op)) printf ("Fin");
getch();
}
int recursiva(int a,int op){
a++;
if (a%op==0) printf("%d\n",a);
if (op*10<=a) return 1;
recursiva(a,op);
}
Bueno con esto lo dejamos por hoy, deberia haber nombrado tambien aqui el goto, pero es de mala practica usarlo. Solo una de cada mil veces que lo useis es correcta asi que mejor no usarlo nunca. Espero que esto os vaya sirviendo, a partir de aqui las lecciones cada vez van a ser mas complejas y se va a dar por hecho que todo lo expuesto anteriormente se conoce a la perfeccion. Y cuando me pille bien los formatos en la pagina lo pondre mas bonito visualmente.
A pasarlo bien.