martes, 10 de enero de 2017

Capítulo 8. Iteraciones

Capítulo 8. Iteraciones Iteracion con etiquetas Es la manera primigenia de implementar iteraciones pero lo cierto es que el uso de etiquetas no se recomienda ya que es dificil de entender y mantener un programa con etiquetas. A ser posible hay que evitarlas. /** * Loop.cpp * * Programa que muestra como usar iteraciones * Pello Xabier Altadill Izura * Compilar: g++ Loop.cpp -o Loop */ using namespace std; #include // Programa principal int main () { cout << " Hola, vamos a mostrar un loop " << endl; //Inicializamos variables int i = 0; int max = 0; // Le pedimos al usuario que meta el total de iteraciones cout << " Cuantas vueltas damos? "; cin >> max; // Vamos a implementar una iteracion con etiquetas // en general no es recomendable usar etiquetas bucle: i++; cout << "Contador: " << i << endl; // si no superamos el tamaño maximo, volvemos a la etiqueta if (i < max) goto bucle; // fin de programa return 0; } Bucles Bueno, ahora en forma de clase vamos a ver una serie de iteraciones. No tienen ningun misterio se implementan como en c, php, perl, java, ... /** * Bucles.hpp * * Clase que muestra distintos tipos de iteraciones * Pello Xabier Altadill Izura */ using namespace std; #include class Bucles { private: int max; 31 Capítulo 8. Iteraciones public: // Constructor Bucles(); // Destructor ~Bucles(); // Contructor parametrizado Bucles(int maximo); // Bucle tipo while void bucleWhile(int maximo); // Bucle tipo for void bucleFor(int maximo); // Bucle tipo do while void bucleDoWhile(int maximo); }; Y aqui la implementacion /** * Bucles.cpp * * Clase que muestra distintos tipos de iteraciones * Pello Xabier Altadill Izura * Compilar: g++ Bucles.cpp -o Bucles */ #include "Bucles.hpp" // Constructor Bucles::Bucles(){} // Destructor Bucles::~Bucles(){} // Contructor parametrizado Bucles::Bucles(int maximo){} // Bucle tipo while void Bucles::bucleWhile(int maximo){ int temp = 0; cout << " iniciamos el bucle WHILE: " << temp << " y max " << maximo << endl; while (temp < maximo) { cout << temp << " es menor que " << maximo << endl; temp++; } } // Bucle tipo for void Bucles::bucleFor(int maximo){ 32 Capítulo 8. Iteraciones int temp = 0; cout << " iniciamos el bucle FOR: " << temp << " y max " << maximo << endl; for (temp=0; temp < maximo; temp++) { cout << temp << " es menor que " << maximo << endl; } } // Bucle tipo do while void Bucles::bucleDoWhile(int maximo){ int temp = 0; cout << " iniciamos e bucle: " << temp << " y max " << maximo << endl; do { cout << temp << " es menor que " << maximo << endl; temp++; } while (temp < maximo); } int main () { // Creamos dos instancias de la clase Bucles Bucles ciclador = Bucles(); Bucles cicladorparam = Bucles(34); // Invocamos los metodos ciclador.bucleWhile(23); cicladorparam.bucleFor(10); ciclador.bucleDoWhile(5); return 0; } Switch/case Por supuesto tenemos el clasico switch-case en c++ En este ejemplo creamos una clase para mostrar el funcionamiento de un menu de seleccion. /** * Menu.hpp * * Clase que especifica un menu de seleccion de opciones * que implementaremos con un case * Pello Xabier Altadill Izura */ using namespace std; #include class Menu { private: int resultado; 33 Capítulo 8. Iteraciones public: // Constructor Menu(); // Destructor ~Menu(); // Menu tipo case int menu(); }; Y su implementacion /** * Menu.cpp * * Clase que implementa Menu.hpp * Pello Xabier Altadill Izura * Compilar: g++ Menu.cpp -o Menu */ #include "Menu.hpp" // Constructor Menu::Menu(){} // Destructor Menu::~Menu(){} // Menu tipo case int Menu::menu(){ int temp = 0; // Iniciamos un bucle que no para hasta que se seleccione // algo distinto de 0. do { cout << " MENU Seleccion." << endl; cout << " 1. Ensalada" << endl; cout << " 2. Cordero " << endl; cout << " 3. Merluza " << endl; cout << " 4. Pato " << endl; cout << " Elije algo: "; cin >> temp; // Segun lo elegido sacamos algo. switch (temp) { case 0 : cout << " Nos vamos " << endl; break; case 1 : cout << " Estas a dieta? " << endl; break; case 2 : cout << " Vaya digestion... " << endl; break; 34 Capítulo 8. Iteraciones case 3 : cout << " Que sano eres " << endl; break; case 4 : cout << " Vaya finolis esta hecho " << endl; break; default : cout << " Chico, decidete." << endl; temp = 0; } //end switch } while(!temp); return temp; } int main () { // Aqui guardaremos el resultado int resultado = 0; cout << " Vamos a sacar el menu." << endl; // Creamos dos instancias de la clase Menu Menu menutero = Menu(); // Invocamos los metodos resultado = menutero.menu(); cout << " El resultado es: " << resultado << endl; return 0; } 35 Capítulo 8. Iteraciones Largo es el camino. Bueno, aun queda un huevo por recorrer... 36 Capítulo 9. Punteros Los punteros Acaso creiais que en c++ no habia punteros? eso solo ocurre en Java. Los punteros no contienen datos, contienen direcciones de memoria. Para cada tipo de dato hay que definir un puntero. /** * Puntero.cpp * * Clase que muestra las direcciones de variables * Pello Xabier Altadill Izura * Compilar: g++ Puntero.cpp -o Puntero */ using namespace std; #include int main () { // Creamos varias variables: int pruebaInt = 99, prueba2Int; short pruebaShort = 34; char carac = ’a’; int *puntero = 0; int *punteroNuevo; // Ahora las mostramos por pantalla: cout << "Variable pruebaInt: " << pruebaInt << endl; cout << "Direccion pruebaInt: " << &pruebaInt << endl << endl; cout << "Variable prueba2Int: " << prueba2Int << endl; cout << "Direccion prueba2Int: " << &prueba2Int << endl << endl; cout << "Variable pruebaShort: " << pruebaShort << endl; cout << "Direccion pruebaShort: " << &pruebaShort << endl << endl; cout << "Variable carac: " << carac << endl; cout << "Direccion carac: " << &carac << endl << endl; cout << "Variable puntero: " << puntero << endl; // ATENCION, si el puntero no tiene valor dara // SEGMENTATION FAULT y la CAGAREMOS de gordo //cout << "Variable puntero: " << *puntero << endl; cout << "Direccion puntero: " << &puntero << endl << endl; puntero = &pruebaInt; cout << "Variable puntero: " << puntero << endl; cout << "Variable puntero: " << *puntero << endl; cout << "Direccion puntero: " << &puntero << endl << endl; return 0; } Veamos otro ejemplo... /** * Puntero2.cpp * * Clase que muestra mas usos de los punteros * Pello Xabier Altadill Izura 37 Capítulo 9. Punteros * Compilar: g++ Puntero2.cpp -o Puntero2 */ using namespace std; #include // prototipo de funciones que implementamos luego int devuelve(int *punteroInt, int entero); int main () { // Creamos varias variables: int pruebaInt = 99, prueba2Int; short pruebaShort = 34; char carac = ’a’; int *puntero = 0; int *punteroNuevo; // Ahora las mostramos por pantalla: cout << "Variable pruebaInt: " << pruebaInt << endl; cout << "Direccion pruebaInt: " << &pruebaInt << endl << endl; cout << "Variable prueba2Int: " << prueba2Int << endl; cout << "Direccion prueba2Int: " << &prueba2Int << endl << endl; cout << "Variable pruebaShort: " << pruebaShort << endl; cout << "Direccion pruebaShort: " << &pruebaShort << endl << endl; cout << "Variable carac: " << carac << endl; cout << "Direccion carac: " << &carac << endl << endl; cout << "Variable puntero: " << puntero << endl; // ATENCION, si el puntero no tiene valor dara // SEGMENTATION FAULT y la CAGAREMOS //cout << "Variable puntero: " << *puntero << endl; cout << "Direccion puntero: " << &puntero << endl << endl; puntero = &pruebaInt; cout << "Variable puntero: " << puntero << endl; cout << "Variable puntero: " << *puntero << endl; cout << "Direccion puntero: " << &puntero << endl << endl; *puntero = 345; cout << "Variable puntero: " << puntero << endl; cout << "Variable puntero: " << *puntero << endl; cout << "Direccion puntero: " << &puntero << endl << endl; // Ahora las mostramos por pantalla: cout << "Variable pruebaInt: " << pruebaInt << endl; cout << "Direccion pruebaInt: " << &pruebaInt << endl << endl; *punteroNuevo = devuelve(puntero,34); cout << " Tras llamada: " << endl; cout << "Variable puntero: " << punteroNuevo << endl; cout << "Variable puntero: " << *punteroNuevo << endl; cout << "Direccion puntero: " << &punteroNuevo << endl << endl; return 0; } int devuelve (int *punteroInt, int entero) { 38 Capítulo 9. Punteros cout << "Variable param. puntero: " << punteroInt << endl; cout << "Variable param. puntero: " << *punteroInt << endl; cout << "Direccion param. puntero: " << &punteroInt << endl << endl; return (*punteroInt) + entero; } new y delete Con las instrucciones new y delete podemos reservar y liberar espacio libre de memoria. Se utilizan con los punteros (ademas de los objetos) y es muy necesario liberar siempre la memoria con la instruccion delete para evitar memory leaks: espacio de memoria marcados como okupados pero que ya no se usan porque el puntero que les correspondia ahora apunta a otro lado. /** * Puntero.cpp * * Clase que muestra la okupacion/liberacion de memoria con new y delete * Pello Xabier Altadill Izura * Compilar: g++ Puntero.cpp -o Puntero */ using namespace std; #include int main () { // Creamos varias variables: int *pruebaInt = new int; short *pruebaShort = new short; pruebaInt = 777; pruebaShort = 23; // Ahora las mostramos por pantalla: cout << "Variable pruebaInt: " << pruebaInt << endl; cout << "Direccion pruebaInt: " << &pruebaInt << endl << endl; cout << "Variable pruebaShort: " << pruebaShort << endl; cout << "Direccion pruebaShort: " << &pruebaShort << endl << endl; // Liberamos la memoria delete pruebaInt; delete pruebaShort; // Contra la especulacion del sistema (operativo) // volvemos a oKupar un espacio de memoria int *pruebaInt = new int; short *pruebaShort = new short; pruebaInt = 666; pruebaShort = 21; // quiza tengamos un error, pero se puede comprobar: if ( pruebaInt == NULL || pruebaShort == NULL ) { cout << "Error al reservar memoria" << endl; return 0; } // Ahora las mostramos por pantalla: cout << "Variable pruebaInt: " << pruebaInt << endl; cout << "Direccion pruebaInt: " << &pruebaInt << endl << endl; cout << "Variable pruebaShort: " << pruebaShort << endl; cout << "Direccion pruebaShort: " << &pruebaShort << endl << endl; 39 Capítulo 9. Punteros return 0; } Objetos y punteros Se pueden crear punteros a objetos y atributos que son punteros. Veamos este ejemplo de una clase llamada Objeto: /** * Objeto.hpp * * Clase que muestra distintos tipos de punteros * que se usan con los objetos * * Pello Xabier Altadill Izura */ using namespace std; #include // Inicio de la clase class Objeto { private: int *privado; public: int atributo; // Constructor Objeto(); // Constructor Objeto(int atributo); // Destructor ~Objeto(); // Menu tipo case int devuelveAlgo(); }; Y su implementacion: /** * Objeto.cpp * * Clase que muestra distintos tipos de punteros * que se usan con los objetos * Pello Xabier Altadill Izura * Compilar: g++ Objeto.cpp -o Objeto */ #include "Objeto.hpp" // Constructor Objeto::Objeto(){ atributo = 666; } 40 Capítulo 9. Punteros // Constructor Objeto::Objeto(int atributo){ this->atributo = atributo; } // Destructor Objeto::~Objeto(){} // Menu tipo case int Objeto::devuelveAlgo(){ int temp = 0; return temp; } int main () { // Aqui guardaremos el resultado int resultado = 0; cout << " Vamos a jugar con los objetos." << endl; // Creamos la instancia del objeto puntero Objeto objeto = Objeto(); //Creamos un puntero a ese objeto, // pero cuidado, no asignarle un constructor directamente Objeto *objetopuntero; // esto si... objetopuntero = &objeto; // Invocamos los metodos resultado = objeto.devuelveAlgo(); // Observese la diferencia al acceder al atributo publico: cout << " El valor de atributo con Objeto es: " << objeto.atributo << endl; cout << " El valor de atributo con Objeto es: " << objetopuntero->atributo << endl; return 0; }

No hay comentarios:

Publicar un comentario