Vous êtes sur la page 1sur 65

Introduccin a la programacin 1. Cmo hablo con la mquina?

Pongamos que, un buen da, ante tus ojos, tienes una maravillosa mquina que la gente llama ordenador. La miras con cautela (morder?), y lo primero que tus ojos observan, es que consta de varios trozos. Uno de ellos, de verdad, es clavado a la tele de la salita (podr ver la peli de la 2 desde aqu?). Otro de esos trozos recuerda a las mquinas de escribir de nuestra infancia (le podr mandar una carta a mi abuela?; y por dnde meto el papel?). Sin embargo, en un ordenador "medio", suele haber algo ms, que lo primero que recuerda es a una caja grande de zapatos, con la diferencia de que no tiene zapatos dentro. Se le suele llamar "torre" (pues yo no veo ningn castillo) o, simplemente, caja. Si la abrimos, entre todo el maremgnum de cables existente, podemos ver unas plaquitas muy finas. Un consejo: no las rompas. Tienes ante ti, al cerebro pensante (es un decir) de la mquina, y a todos sus sbditos. Entonces, como eres una persona emprendedora, te preguntas, "y cmo demonios le convenzo para que se ponga la peli de la 2?", "sabr hacer ganchillo?", "podremos hacernos amigos?". Esto ltimo depende de ti, y slo de ti. Porque, lo primero que tienes que tener pero que muy claro es que la mquina har nica y exclusivamente lo que t le digas. Lo segundo, es saber que tu mquina tiene limitaciones (lo siento mucho, pero sin brazos dudo mucho que pueda hacerte la comida) y que est diseada para unas tareas concretas ("pero bueno, puedo o no puedo ver la peli de la 2?!"). Lo tercero: tienes que aprender el lenguaje de la mquina. Porque, claro, si le recitas algn poema, nadie te salvar de su gesto de indiferencia: no te entiende. La pregunta lgica, pues, y cul es el idioma de la mquina? ("que no sabr ruso y mira cmo se lo calla?"). Si eres despierto, habrs observado con especial atencin cuando he dicho que hay un maremgnum de cables en alguna parte. No importa tanto lo de la parte como lo de los cables. Bien, veamos: cables. Y yo para qu quiero un cable? Bueno, s, puedo querer estrangular al perro de la vecina, vale, pero eso no me ayuda a saber cmo hablarle a mi mquina (ni siquiera al perro de la vecina). Por dnde bamos? Ah, s... CABLES. Bueno, ahora que lo pienso, por los cables pasa la corriente. Uuummm... CORRIENTE, s, vamos bien. Y qu le pasa a la corriente? ("ah, yo no s, pregntale a ver"). Pues que, como el dinero, *est* o *no est*. Vale, vamos progresando. Si te fijas ms an, en esas placas que te he sugerido que no rompas, hay dibujitos como los de las "pelis" futuristas con un montn de lneas, y hay como una cajita negra grandota con un montn de patitas ("Agh, por Diox, una cucaracha!, Traedme el insecticida!") Vaya, pero si de esas patitas salen ms de esas lneas!

No te engaes: esas lneas son cables, y la cucaracha grande es la que manda. Esa cucarachita est preparada para entender un idioma (no tan rico como el castellano) que le permite hacer sus cuentas, encargarle a alguien que las haga por ella ("tiene una calculadora?"), y, lo ms importante, por medio de esos cables, dar rdenes a diestro y siniestro a sus sbditos y recibir las respuestas de los mismos. Tiene muchas responsabilidades encima, para ser una cosa tan chica. Y suele responder al nombre de "procesador" (aunque no se gira cuando le llamas). Sus colaboradores se encargan (si estn todos lo cables enchufados como toca, cosa que presuponemos) de hacer cuentas, de enviar seales de vdeo a esa cosa "clavada a la tele de la salita" para que puedas ver desde unas tristes letras blancas en fondo negro (aunque tienen su encanto) a la ltima novedad en 3D con muchos colorines, de permitirnos que al pulsar una tecla aparezca por esa pantalla, en fin... todo un mundo! Y el procesador, para que le hablen, simplemente necesita que le digas: "0" o "1". ("Pero bueno, y para esto tanto rollo con que si lenguajes de programacin que si historias?"). Qu significa esto? Por qu, de entre todas las posibles formas de comunicacin, ha ido a elegir la ms estpida? Bueno, en realidad no lo es tanto. Lo que quiere decir es, "0": ausencia de corriente. "1": presencia de corriente. Es la manera ms fcil. Pero esto no acaba aqu. Como podrs imaginar, los 0 y 1 pueden aparecer de muchas maneras. Ah, ah has dado con la clave de todo: 0 y 1 son "el alfabeto", pero todas las formas en que pueden aparecer son sus "palabras" (aunque no te recomendara que asociaras palabra con esto). Ya est claro: tengo que saber hablar en 0 y 1 si quiero tener algn tipo de relacin con mi ordenador. Pero no es nada "humano", digamos intuitivo. Lo ideal sera que pudiera hablarle de forma que se parezca ms a mi manera de hablar, puesto que no estamos ahora para ir aprendiendo idiomas tan "exticos". Y entonces llega el ser humano con su ingenio, y decide inventarse un lenguaje ms sencillo con el que hablarle a la mquina: y naci el ensamblador. Pero, para una persona cuyo objetivo ms ambicioso (por ahora) es escribir un "Hola Mundo", resulta demasiado complicado. Por qu? Pues porque requiere conocer a la mquina como a uno mismo, y si uno mismo no llega a conocerse bien, qu me direis de su mquina. As, en un alarde de ingenio, el ser humano repite jugada, y se inventa otros lenguajes que, ahora s, son ms parecidos a nuestra forma de pensar. Estos lenguajes, como todo, hay que aprendrselos, pero tienen una ventaja, y es que hay varios puntos en comn. Todos constan de unos determinados tipos de variables. Una variable es como una caja, donde ahora puedo meter un zapato y maana un tomate. Ahora, yo puedo haber etiquetado mis cajas y decir "aqu slo fruta": ser una variable de tipo FRUTA. O, "aqu slo legumbres": ser una variable de tipo LEGUMBRE. Esto es interesante, porque en

el momento en que yo vea FRUTA, ya s que dentro no hay cerveza (y tendr que buscar en otro sitio, jo, qu sed...). Pero no slo eso: yo s que tengo muchas cajas para frutas, pero puedo querer bautizarlas ("t sers la caja de frutas Juana"), y as llamarlas por su nombre. Podr cambiar (o no) su contenido (hoy Juana tiene un meln pero maana le pondr ciruelas), pero NO lo que puede contener: FRUTA. Esto tambin lo tiene en comn los lenguajes de programacin. Slo que sus variables son de otro TIPO. Pueden ser enteros (s, como los nmeros que nos ensearon en la infancia), nmeros con decimales, cadenas de caracteres (no es ms que un carcter detrs de otro) y otros que ahora no comentamos (quedan para ms adelante). Lo normal es declarar las variables al principio de un programa. Declarar no es ms que decir "mira, yo quiero tres variables enteras, y quiero que una se llame Pepi, otra Juani y otra Yoli". A partir de este momento, podrs meter un -4 en Pepi, un 2 en Yoli, y hacer Pepi+Yoli. El resultado ser -2. Vaya, esto se pone interesante. Qu ms cosas me permite hacer un lenguaje de programacin? Pues me permite hacer operaciones conocidas por todos como sumar, restar, multiplicar y dividir. Los lenguajes de programacin, cuentan todos en su haber con un juego de "instrucciones". Una instruccin no es ms que una orden que nosotros le damos a la mquina. Y es que, al fin y al cabo, un PROGRAMA no es ms que una secuencia de instrucciones (escritas en algn lenguaje de programacin) pensado para RESOLVER algn tipo de PROBLEMA. Si no sabemos resolver este problema, no podremos escribir el programa. A ti se te puede ocurrir una manera de resolverlo. A tu vecino, otra. Este METODO con el que resolveis el problema, es lo que se llama ALGORITMO, y es lo que vamos a ver en este cursito cmo se hacen. Un algoritmo no es ms que una secuencia de pasos que, seguidos uno a uno, me permiten resolver un problema. Por ejemplo, cuando quiero ver una pelcula de vdeo, podra hacer: 1. Elijo una pelcula de las de mi coleccin. 2. 3. Compruebo SI TV y vdeo estn conectados a la red (y procedo). 4. 5. SI la TV est apagada, la enciendo, SI NO, pues no. Y lo mismo con el vdeo. 6. 7. Abro el estuche de la pelcula. 8. 9. Saco la pelcula de su estuche. 10. 11. Introduzco la pelcula en el vdeo. Dejo el estuche sobre el vdeo. 12.

13. SI la TV no est en el canal adecuado, la cambio, SI NO, pues no. 14. 15. Cojo los mandos a distancia (el del TV y el del vdeo). 16. 17. Me pongo cmodo. 18. 19. Pulso PLAY en el mando del vdeo. 20. A qu no se os haba ocurrido? Fijaos bien en unos detalles que son fundamentales y que aparecen en este algoritmo: 1. La descripcin de cada paso no me lleva a ambigedades: los pasos son absolutamente explcitos y no inducen a error. 2. El nmero de pasos es finito. Y es que no puedes tener eternamente pensando a la mquina si pretendes que te d algn resultado en algn momento. Podra poner una definicin rigurosa de lo que es un algoritmo, pero me parece que con esto se coge la idea. Notar tambin que he escrito en maysculas las palabras SI y SI NO. Como podeis imaginar, formar parte de la manera en que se escriben algoritmos. Por ahora, os invito a que describais algortmicamente situaciones cotidianas de vuestra vida. En la prxima entrega har un resumencito escribiendo las cosas de forma algo ms rigurosa (al principio lo que importa es que se entiendan las ideas), completar lo dicho sobre las variables, y seguiremos por esos pecaminosos senderos del mundo de la programacin: las instrucciones de control de un programa. Introduccin a la programacin 2. Las variables, usos y costumbres La vez anterior nos quedamos hablando de variables, aquellas cajitas donde podemos ir almacenando cosas como lechugas, tomates y tambin... ENTEROS: Como su nombre indica, aqu podremos meter nmeros enteros, tanto positivos como negativos. Cuando decimos que podemos tener tanto enteros positivos como negativos, lo que se suele decir es "enteros con signo". Si slo vamos a tener enteros positivos (incluyendo el cero), decimos entonces "enteros sin

signo". Esta nomenclatura de "con signo" y "sin signo" es aplicable a otros tipos, como el siguiente. REALES: Trex cuartos de lo mismo, aqu podemos poner nmeros con decimales, tanto positivos como negativos. Hay reales con signo y reales sin signo, pero, si no decimos lo contrario, se sobreentiende que son con signo. Obviamente, dado que la memoria de la mquina es finita (vamos, que por muchos megas, incluso Gigas de RAM, algn da sta se nos acabar), el tamao de los datos que almacenemos tambin ser finito. Esto quiere decir que, por ejemplo, el nmero Pi jams cabr en la memoria de un ordenador. Por tanto, para cada tipo de dato, segn el lenguaje, se especifica cuntas cifras tiene, aunque suele ser unnime. CARACTERES: Si tenemos una variable de tipo caracter, lo que podemos almacenar ser un caracter como 'p', 's', '3', '#' y otros. Estos son los tres tipos de datos bsicos, y son los que yo usar. Como ya coment, las variables se suelen declarar al principio del programa, y esta ser la norma que yo voy a usar; toda variable utilizada, debe haber sido previamente declarada. Para ello, escribir algo como esto: Declaracion de variables:

ENTERO: i,j,k REAL: x,y,z CARACTER: a,b,c

Fin de la declaracion de variables Esto querr decir que las variables i, j, k sern enteras (con signo), que las variables x, y, z sern reales (con signo) y que las variables a, b, c sern caracteres. Al escribir la declaracin de variables de esta forma, si alguna se nos ha olvidado, es muy fcil incluirla. Una variable, en el momento que la declaramos, est vaca, hueca, sin vida, sentido ni VALOR. Y hasta que dicha variable no tenga valor, lo mejor ser no hacer cosas con ella. Entonces, aqu viene la pregunta: y cmo meto en mi variable un 7? Puedo meter un 23? Para poder meter cosas en las variables, lo que hacemos es asignarles un valor, es decir, "Pepe es una variable de tipo entero. Si a Pepe le asigno 14, a partir de ahora, poner Pepe es tanto como poner 14".

Para ello, nosotros vamos a usar un smbolo, una flechita. Cuando queramos hacer asignaciones, haremos esto: Pepe <- 14 (asignamos un entero)

Carolina <- -9.65 (asignamos un real) Juan <- 'a' (asignamos un caracter)

Y podemos hacer cuantas asignaciones queramos a nuestra variable. Por ejemplo, si hacemos: Pepe <- 14 Pepe <- 4 Pepe <- -3 Pepe <- 42 al final, en Pepe tenemos almacenado el valor 42. Lo que no debemos hacer es: Pepe <- 14 Pepe <- 2.5 pues estamos metiendo un valor REAL en una variable que slo quiere ENTEROS. Qu pasar aqu? Pues depende del compilador. Quiz nos trunque los decimales, quiz los redondee, quiz, simplemente, nos d un error y no lo permita. En cualquier caso, si queramos un 2.5 con toda nuestra alma, una variable entera no es lo ms recomendable para guardarlo. "Muy bien, ya s cmo meter cosas en las variables, ahora... qu puedo hacer con mis variables?" Como los caracteres son un tanto especiales, sern tratados aparte, para que no haya confusin. As que, por ahora, nos vamos a entender con las variables numricas. Como obviamente parece, podemos sumar, restar, multiplicar y dividir variables. Si dividimos por una variable que en ese momento valga cero, tendremos un error. Pero, por lo dems, podemos hacer todas estas cosas. Por el mismo motivo que he comentado arriba, es mejor no mezclar enteros con reales al hacer operaciones, a no ser que de verdad uno sepa que quiere mezclarlos y por qu quiere mezclarlos. Para estas operaciones, usaremos la notacin usual que nos ensearon ya desde pequeitos. Entonces, podremos hacer todas estas cosas:

Pepe <- 2 Mari <- 3 Juan <- Pepe*Mari Tendremos que en Juan est almacenado el valor 2*3=6 :) Pepe <- 2 Mari <- 3 Juan <- Pepe+Mari Ahora, en Juan est almacenado el valor 2+3=5 :)

Pepe <- 2 Mari <- 3 Juan <- Pepe-Mari Y ahora, en Juan est almacenado el valor 2-3=-1 :) Como estos, os podeis poner cuantos ejemplos querais. Adems, los compiladores suelen traer libreras matemticas con muchas funciones ms avanzadas (aunque *todas* esas funciones se consiguen a partir de las cuatro operaciones bsicas), funciones con las que podemos hacer ms operaciones con nuestras variables. Por ejemplo, podemos escribir: Mari <- Pi Pepe <- sin(Mari) Y tendremos en Pepe almacenado el valor sin(Pi)=0 Ms adelante, os pondr como ejercicio implementar alguna funcin matemtica como el seno, la exponencial (u otras), el algoritmo ser muy sencillo, y vereis como todos los clculos no son ms que combinaciones de las cuatro operaciones bsicas que nos ensearon en la escuela. De momento, eso es todo en cuanto a variables numricas. Las variables de tipo carcter son un poco ms especiales, es mejor esperar a tener un poco ms de rodaje en otras cuestiones bsicas Introduccin a la programacin 3. Estructuras de control; secuenciales y selectivas

Bueno, bueno: ya hemos hablado un poco de variables; qu son, y cosas que podemos hacer con ellas. Tambin hablamos un poco por encima de lo que es un algoritmo, pero an no sabemos cosas sobre ellos. Una posible "definicin rigurosa" sera la siguiente (no hay que tomarla como un dogma de fe): Un algoritmo es una sucesion finita de pasos no ambiguos que se pueden llevar a cabo en un tiempo finito. Sucesin finita es lo contrario de infinita: esto quiere decir que se acaba en algn momento ;) Pasos no ambiguos son pasos tan claros que hasta una mquina los puede entender, de ah la necesidad de la no ambigedad ;) Lo del tiempo finito es una cuestin prctica: no creo que tengamos tanta paciencia (ni que lleguemos vivos, sobre todo) como para ver la salida de un programa que calcule Pi :) No vamos a entrar en filosofas de qu puede ser considerado como un algoritmo, qu no lo es, etc... , no porque no sea interesante en s, sino porque a nosotros lo que nos preocupa en estos momentos es aprender a resolver problemas, y a eso es a lo que vamos. No hay que confundirse: un algoritmo no es lo mismo que un programa, para hacer un programa necesitamos algo ms: unas estructuras de datos. Hay distintas formas de escribir un algoritmo, bien usando un lenguaje especfico de descripcin de algoritmos, bien mediante representaciones grficas. Yo he elegido la primera: el pseudocdigo. Que sea un lenguaje especfico no significa que haya que aprender un idioma nuevo, lo nico que quiere decir es que hay unas cuantas palabras que son clave, y que son las palabras que, de acuerdo a unas reglas muy sencillitas, nos ayudan a describir el algoritmo. La estructura del pseudocdigo es bastante parecida a la de algunos lenguajes de programacin (por ejemplo, el Pascal), por ello me ha parecido la ms recomendable. El pseudocdigo tiene algunas ventajas:

Es fcil hacer cambios si nos equivocamos en la lgica del programa Es independiente del lenguaje de programacin que vaya a usarse; un algoritmo que est escrito en pseudocdigo es fcilmente traducible a muchos lenguajes de programacin.

Y ya, sin ms prembulos, vamos a lo que nos interesa: nosotros queremos resolver problemas con el ordenador, no es as? Pues veamos con qu herramientas nos podemos defender para escribir nuestros propios algoritmos.

Elementos bsicos para la descripcin de algoritmos El principio y el fin Para delimitar el comienzo y el final de un algoritmo, o de un trozo de algoritmo (por ejemplo, en los ciclos, y otros, como vamos a ver), haremos lo siguiente: inicio

... Aqui va el algoritmo en cuestion

fin Tambin, en vez de inicio y fin se puede usar "empezar" y "fin", o lo que querais, pero siempre quedando clara la intencin. No hay que ser estrictamente riguroso con la aplicacin del "inicio-fin", muchas veces, una buena indentacin hace su papel. Asignaciones Sobre las asignaciones ya hablamos la vez pasada, al tratar el tema de las variables, vamos a recordarlo brevemente: Cuando hayamos declarado una variable, llegar un momento en el que querremos que la variable tome algn valor. Por ejemplo, tenemos una variable de tipo entero que se llama I y queremos asignarle el valor 3, entonces, escribiremos: I <- 3 Comentarios Poner comentarios de lo que vamos haciendo es muy til, sobre todo cuando llega la hora de revisar el algoritmo, si no, ms de una vez nos encontraremos diciendo "uumm... qu demonios haca esto?" No cuesta nada documentar el cdigo y nos ahorrar dolores de cabeza :) La convencin que seguiremos ser poner los comentario entre llaves. As, {esto ser un comentario} ESTRUCTURAS DE CONTROL Las estructuras de control tienen una finalidad bastante definida: su objetivo es ir sealando el orden en que tienen que sucederse los pasos de un algoritmo.

Veamos un ejemplo: supongamos que acabamos de mostrar un mensaje en la pantalla que pregunte al usuario "desea seguir adelante?". Obviamente, de la respuesta del usuario va a depender la siguiente accin del programa. Por ejemplo, si este mensaje se nos presenta tras haber pulsado un botn de cerrar la aplicacin, si nosotros elegimos "S", la aplicacin se cerrar, y si elegimos "No", la aplicacin seguir adelante. El programador tiene que haber escrito cdigo para las dos posibilidades, aunque cuando el programa est funcionando, slo se elegir una. Las estructuras de control son de tres tipos: 1. Secuenciales 2. Selectivas 3. Repetitivas Estructuras SECUENCIALES. Una estructura de control secuencial, en realidad, no es ms que escribir un paso del algoritmo detrs de otro, el que primero se haya escrito ser el que primero se ejecute (al implementarlo, por ejemplo). Veamos un ejemplo: queremos leer el radio de un crculo, calcular su rea y mostrar por pantalla al usuario el resultado. Declaracion de variables REAL: radio, area fin declaracion de variables

inicio mostrar por pantalla 'dame el radio del circulo' leer del teclado la variable radio area <- 3.14159*radio mostrar por pantalla 'el area del circulo es:' mostrar por pantalla el contenido de la variable area fin Notar una cosa: cuando queremos hacer cosas relativas a entrada o salida por algn dispositivo, como el teclado, la pantalla o la impresora, yo pongo cosas como "mostrar por pantalla", o "leer del teclado". Dado que cada lenguaje de programacin tiene sus funciones de entrada/salida, no uso la forma particular de ninguno,

simplemente, lo que le diramos al ordenador en caso de que fuera una persona ("oye, por favor, scame esto por impresora"). Por otro lado, cuando queramos decir que nos muestre el contenido de una variable, yo he puesto "mostrar por pantalla el contenido de la variable area", pero poda haber puesto igualmente "mostrar por pantalla area", o cosas similares. Vosotros elegs la forma que os resulte ms clara o ms cmoda, lo importante es que las intenciones sean claras, o, lo que es lo mismo, "no ambiguas" ;) Adems, si os fijais, para que quede claro que una cosa es mostrar por pantalla una cadena, y otra cosa es mostrar por pantalla el valor de una variable, el texto que aparece entre ' ' es una cadena, mientras que el que no aparece entre ' ' no es una cadena, sino que se refiere a una variable. Ahora vamos a pasar a las estructuras selectivas y a las repetitivas. Para ello, necesitamos primero hablar un poco de... CONDICIONES. La palabra condicin nos sugiere frases como "lo har a condicin de que me dejes tu boli". Analicemos esta frase con un poco de detenimiento. Decimos "lo har", pero, "lo har" siempre, pase lo que pase? o, por el contrario, "lo har" si antes hay algo que debe cumplirse? En la frase est claro que no se ha dicho "lo har" sin ms, si no que hay como una pequea clusula "SI me dejas tu boli". Ya nos ha vuelto a aparecer el SI; esto parece querer decir que debe ser algo importante. Lo que significa "SI me dejas tu boli" es lo siguiente, en caso de que la accin "dejarme tu boli" sea cierta (o verdad, usar ambas palabras), yo "lo har". Pero si la accin "dejarme tu boli" es falsa (o mentira), yo NO "lo har". En esto reside el "quid" de las estructuras que vamos a ver a continuacin: se EVALUA una condicin, y se acta en consecuencia, segn que la condicin sea VERDADERA o FALSA. Estructuras SELECTIVAS Estas estructuras se utilizan para TOMAR DECISIONES (por eso tambin se llaman estructuras de decisin o alternativas). Lo que se hace es EVALUAR una condicin, y, a continuacin, en funcin del resultado, se lleva a cabo una opcin u otra. Alternativas SIMPLES Son los conocidos "si... entonces". Se usan de la siguiente manera (una vez ms, la escritura es ms o menos personal, siempre que las intenciones queden claras para todos): yo quiero evaluar una condicin, y si se cumple (es decir, si es cierta), entonces realizar una serie de pasos. Esto lo podemos escribir as:

SI se cumple la condicion, ENTONCES: Hago el paso 1 .... Hago el paso N fin del SI

Muy estrictamente, sera: SI se cumple la condicion, ENTONCES: inicio Hago el paso 1 .... Hago el paso N fin fin del SI pero con una buena sangra nos podemos evitar escribir de ms ;) Es importante cerrar el SI, ya que, si no se cumple la condicin, el programa seguir a continuacin de donde termina el SI. Por ejemplo, queremos calcular la raz cuadrada de un nmero; sin embargo todos sabemos (supongo! ;)) que la raz cuadrada de un nmero negativo NO es un nmero real. Esto quiere decir que, tras leer el nmero por teclado, tendremos que ver si es positivo, ya que slo en este caso podremos calcular su raz cuadrada. Veamos como queda:

Declaracion de variables REAL: numero, raiz fin declaracion de variables

inicio mostrar por pantalla 'introduce un numero' leer del teclado la variable numero SI numero >= 0 ENTONCES: raiz <- raiz_cuadrada(numero) mostrar por pantalla 'la raiz cuadrada es:' mostrar por pantalla raiz fin del SI fin Como extraer una raz cuadrada es una operacin que, en principio, no es elemental, yo he puesto raiz_cuadrada(numero), eso significa que, en alguna parte, tengo definida una funcin que me calcula la raz cuadrada de un nmero. Ya hablaremos de funciones y subrutinas ms adelante, pero hago esta aclaracin para que conste que raiz_cuadrada no forma parte de ningn tipo de especificacin de pseudocdigo ;-) Sin embargo, hubiera sido bonito haber podido avisar al usuario de que no podamos calcular la raz cuadrada en caso de que el nmero fuera negativo, pero no os preocupeis, para ello tenemos las... Alternativas DOBLES O el famoso tro "si ... entonces ... sino" ;-D Se usan de esta forma: queremos evaluar una condicin, si es verdad, realizar una serie de pasos, y SI NO es verdad (es decir, si es falsa, si es una puerca mentira cochina... ;) ), entonces realizar otra serie de pasos. Esto lo podemos escribir as: SI se cumple la condicion, ENTONCES: Hago el paso A1 ....

Hago el paso AN y SI NO se cumple la condicion, ENTONCES: Hago el paso B1 .... Hago el paso BM fin del SI

Con esto, nuestro algoritmo para la raz cuadrada quedara: Declaracion de variables REAL: numero, raiz fin declaracion de variables

inicio mostrar por pantalla 'introduce un numero' leer del teclado la variable numero SI numero >= 0 ENTONCES: raiz <- raiz_cuadrada(numero) mostrar por pantalla 'la raiz cuadrada es:' mostrar por pantalla raiz SI NO es numero >=0 ENTONCES: {es decir, si numero es negativo}

mostrar por pantalla 'lo siento, no puedo calcular la raiz cuadrada de un numero negativo' fin del SI fin Alternativas MULTIPLES Es muy probable que tengamos la necesidad de incluir en nuestros programas alternativas con muchas opciones posibles. Esto lo podramos hacer a base de anidar "si ... entonces ... si no", pero si es un nmero elevado de alternativas, se hace demasiado farragoso como para resultar inteligibles. Por ejemplo, si queremos hacer un men que d a elegir cuatro opciones, un posible algoritmo sera: {Algoritmo MENU a base de 'si ... entonces ... sino'} Declaracion de variables ENTEROS: opcion fin declaracion de variables

inicio mostrar por pantalla 'menu de opciones:' mostrar por pantalla '1. Diccionario de sinonimos' mostrar por pantalla '2. Diccionario de antonimos' mostrar por pantalla '3. Buscar palabra' mostrar por pantalla '4. Salir' leer del teclado la variable opcion

SI opcion = 1 ENTONCES {lo que toque a esta opcion} SI NO, ENTONCES SI opcion = 2 ENTONCES

{lo que toque a esta opcion} SI NO, ENTONCES SI opcion = 3 ENTONCES {lo que toque a esta opcion} SI NO, ENTONCES SI opcion = 4 ENTONCES {lo que toque a esta opcion} SI NO, ENTONCES mostrar por pantalla 'opcion incorrecta' fin del SI fin del SI fin del SI fin del SI fin Fastidioso, verdad? Para evitar esto (Se imaginan que en vez de cuatro fueran 20 las alternativas?), est la estructura "segn sea". La idea es esta; por ejemplo, como en el algoritmo que hemos puesto del men, pedimos al usuario que entre una opcin, y hay cuatro posibilidades, cuatro posibles valores para los que haremos algo. Entonces, SEGUN lo que valga la variable opcin, elegiremos una alternativa de entre todas las posibles. La forma de escribir esto en pseudocdigo es: SEGUN SEA la variable o la expresion HACER VALOR1: {las acciones que toque} ... VALORN: {las acciones que toque} por defecto: {las acciones que toque} fin SEGUN Qu pinta ah ese 'por defecto'? No es ms que una alternativa por si acaso se elige alguna opcin no contemplada entre las que se ofrece.

Como ejemplo, vamos a ver nuestro men utilizando la alternativa mltiple SEGUN SEA: {Algoritmo MENU a base de 'segun sea'} Declaracion de variables ENTEROS: opcion fin declaracion de variables

inicio mostrar por pantalla 'menu de opciones' mostrar por pantalla '1. Diccionario de sinonimos' mostrar por pantalla '2. Diccionario de antonimos' mostrar por pantalla '3. Buscar palabra' mostrar por pantalla '4. Salir' leer del teclado la variable opcion

SEGUN SEA opcion HACER: opcion = 1 : {lo que toque a esta opcion} opcion = 2 : {lo que toque a esta opcion} opcion = 3 : {lo que toque a esta opcion} opcion = 4 : {lo que toque a esta opcion} por defecto: {mostrar un posible mensaje de error} fin SEGUN fin As queda mucho ms claro, no slo para nosotros, si no para cualquier persona que tuviera que leerlo; adems, es una forma ms sencilla de manejar una alternativa mltiple :) Podemos abreviar un poquito el texto; es igualmente vlido poner, dentro del SEGUN, lo siguiente: SEGUN SEA opcion HACER:

1 : {lo que toque a esta opcion} 2 : {lo que toque a esta opcion} 3 : {lo que toque a esta opcion} 4 : {lo que toque a esta opcion} por defecto: {mostrar un posible mensaje de error} fin SEGUN Me quedan las estructuras repetitivas, que las veremos en la prxima entrega, si no esto puede ser mucho trago de golpe O:) En cualquier caso, ya tienen cosas para ir empezando a pensar en la escritura de algoritmos. Yo sugiero los siguientes... EJERCICIOS Sobre estructuras secuenciales: 1. Escribir un algoritmo que calcule el rea de un tringulo. 2. Escribir un algoritmo que calcule el rea de un rectngulo. 3. Escribir un algoritmo que calcule el rea de un trapecio. 4. Escribir un algoritmo que calcule el precio de un artculo tras aplicarle un 16% de IVA. 5. Escribir un algoritmo que intercambie el contenido de dos variables. Sobre estructuras selectivas: 1. Escribir un algoritmo que resuelva una ecuacin de segundo grado, teniendo en cuenta todas las posibles alternativas. 2. Disear un esquema de men de opciones, por ejemplo, un men para seleccionar un libro a leer de entre siete disponibles. 3. Escribir un algoritmo que lea tres nmeros e imprima por pantalla el mayor de ellos. 4. Escribir un algoritmo que lea tres nmeros e imprima por pantalla el menor de ellos. De momento, eso es todo, cuando tengamos las estructuras repetitivas ya podremos hacer muchas ms cosas :) Introduccin a la programacin 4. Estructuras de control; repetitivas

Estructuras REPETITIVAS Este tipo de estructuras marcan como orden de ejecucin la reiteracin de una serie de acciones basndose en un ciclo. Un CICLO (loop, en ingls) es un trozo de algoritmo cuyas instrucciones son repetidas un cierto nmero de veces, mientras se cumple una cierta condicin que ha de ser claramente especificada. La condicin podr ser verdadera o falsa, y se comprobar en cada paso o iteracin del ciclo. Bsicamente, existen tres tipos de estructuras repetitivas; los ciclos "mientras..." (o "while"), los ciclos "repetir... mientras que" (o "do... while") y los ciclos "desde" (o "ciclos for"). Vamos a verlas todas dentro de un ejemplo para clarificar los dos prrafos iniciales, que quedan tan bonitos como oscuros para quien nunca ha visto un ciclo (ni es verde ni tiene antenas, lo siento %-D ). Slo un poco de teora ms antes de pasar a los ejemplos para cada una de las estructuras repetitivas; hay que hacer notar que todo ciclo consta de tres partes bsicas, a saber:

Decisin: donde se evala la condicin y, en caso de ser cierta, se ejecuta el... Cuerpo del ciclo: son las instrucciones que queremos ejecutar repetidamente un cierto nmero de veces. Salida del ciclo: es la condicin que dice cundo saldremos de hacer repeticiones ("mientras protestes, seguirs fregando platos", en cuanto dejas de protestar, se acab fregar ms platos).

Una forma de controlar un ciclo es mediante una variable llamada CONTADOR, cuyo valor se incrementa o decrementa en una cantidad constante en cada repeticin que se produzca. Tambin, en los ciclos suele haber otro tipo de variables llamadas ACUMULADOR, cuya misin es almacenar una cantidad variable resultante de operaciones sucesivas y repetidas. Es como un contador, con la diferencia que el incremento/decremento es variable. S, s, s... ya s que no me habeis entendido ni jota... ya vamos a por ejemplos, y ah vereis a qu me refiero. Una situacin REAL como aplicacin Vamos a suponer que estamos pensando en un programa que deba REPETIR algunas veces una accin. Por ejemplo, el ordenador se ha portado mal (el gindoze se ha vuelto a colgar, no s, por decir algo };-D ), y, como castigo, le vamos a hacer imprimir por pantalla 300 MILLONES de veces la frase "Prometo ser bueno O:-)" Cmo lo hacemos? Escribimos 300.000.000 de veces la instruccin pertinente? Vaya martirio! Ni con "Copy'n'Paste"! Se supone que el castigo es para la mquina, no para uno mismo!

Pues bien, las ESTRUCTURAS REPETITIVAS vienen a rescatarnos de la tediosa tarea de repetir cientos de lneas que en unas pocas quedan apaadas. Estructura MIENTRAS(condicin) En este tipo de estructura, el cuerpo del ciclo (ya sabeis, las acciones que deben ejecutarse repetidas veces) se repite MIENTRAS se cumple una determinada condicin, que especificamos entre parntesis. Su estructura, genricamente, es esta: mientras(condicin) hacer accin 1 ........ accin N fin mientras Aplicado a nuestra situacin real, sera: Declaracin de variables ENTEROS: Contador fin Declaracin variables

inicio

Contador <- 1 mientras(Contador<=300.000.000) hacer mostrar por pantalla 'Prometo ser bueno O:-)' Contador <- Contador+1 fin mientras

fin Con toda la idea, a la variable que "lleva" (por decirlo de alguna manera) la cuenta de las veces que el ciclo se ha ejecutado, la he llamado contador.

Si os fijais, ANTES de entrar en el ciclo le asigno el valor 1. Recordad que no es recomendable usar variables no inicializadas, no sabemos qu tienen dentro. En cuanto vemos la palabra "mientras", ya sabemos que hemos entrado en el ciclo. Estamos en la decisin. Es Contador<=300.000.000? Yo creo que s, al menos si es cierto que 1<=300.000.000 Vale, es cierto, as que deben ejecutarse todas las instrucciones del cuerpo del ciclo. En nuestro caso, se mostrar por pantalla la frase 'Prometo ser bueno O:-)', y, ATENCION, sumo 1 a la variable Contador. Como Contador vala 1, si ahora le sumo 1, creo que todos estamos de acuerdo en que ahora Contador vale 2. Llegamos al fin del mientras. Eso significa que se han terminado las instrucciones del cuerpo del ciclo: debemos volver a evaluar la condicin que tena el "mientras" entre parntesis para ver qu hacemos ahora. Tenemos que ver si Contador<=300.000.000. Ahora, Contador vala 2, y se cumple que 2<=300.000.000, con lo que vuelve a mostrarse por pantalla la expresin 'Prometo ser bueno O:-)' y de nuevo se suma 1 a Contador, con lo que ahora, Contador pasa a valer 3. De nuevo llegamos al fin del mientras. [... un buen rato despus...] Ahora Contador vale 300.000.000. Tenemos que ver si Contador<=300.000.000. Como es cierto que 300.000.000<=300.000.000, se muestra por pantalla el mensaje 'Prometo ser bueno O:-)', y sumamos 1 a Contador. Ahora, Contador vale 300.000.001. Llegamos (una vez ms) al fin del mientras, por lo que tenemos que volver a evaluar la condicin entre parntesis que acompaa al "mientras". Hay que ver si Contador<=300.000.000. Pero no es cierto que 300.000.001<=300.000.000, es ms bien al revs, o sea, la condicin entre parntesis ES FALSA, ES UNA MENTIRA. Eso qu quiere decir? Pues quiere decir que se acab, que ya no se ejecuta el cuerpo del ciclo, sino que hemos llegado al final, a la salida del ciclo, con lo cual, el ciclo ha terminado. Me podra decir alguien qu hubiera pasado si no incluimos la lnea "Contador <- Contador+1" dentro del cuerpo del ciclo? Slo adelanto que se llegara a una situacin que debe evitarse por completo; si tenemos suerte, habr un error de desbordamiento, en el peor de los casos, el ciclo... completad la frase ;) Una nota importante: Fijaos en una cosa, si, por ejemplo, al empezar nuestro algoritmo, en vez de hacer Contador <- 1 hubiramos hecho Contador <- 1.000.000.000.000.000.000 aparte de que tenemos posibilidades de salirnos de rango (vamos a suponer que no fuera as), al entrar en el mientras, la condicin es "Contador<=300.000.000", y Contador es, claramente, mayor estrictamente que 300.000.000

Qu pasara aqu? Pues es sencillo: la condicin es falsa, luego el cuerpo del ciclo se ejecuta CERO veces. Y qu utilidad tiene poner un ciclo para que luego no se ejecute? En este caso concreto, ninguna, pero puede haber situaciones en las que s nos sea til. De hecho, sucede a menudo :) Estructura REPETIR... MIENTRAS QUE(condicin) Aqu, lo que se desea es que un ciclo se ejecute AL MENOS UNA VEZ antes de comprobar la condicin de repeticin. La estructura del REPETIR ... MIENTRAS, genricamente, es esta: repetir accin 1 ........ accin N mientras que(condicin) Notar que no hace falta poner "fin del repetir", puesto que est claro que se acaba donde pone "mientras que(condicin)". Vamos a ver cmo resolver nuestra situacin REAL con este tipo de estructura: Declaracin de variables ENTEROS: Contador fin Declaracin variables

inicio

Contador <- 1 Repetir mostrar por pantalla 'Prometo ser bueno O:-)' Contador <- Contador+1 mientras que(Contador<=300.000.000)

fin

Le seguimos la pista igual que se la hemos seguido al anterior caso: empezamos con la asignacin del valor 1 a la variable Contador. Llegamos a repetir, quien NO NOS EXIGE, para su entrada, verificar condicin alguna. Mostramos por pantalla la frase 'Prometo ser bueno O:-)', y sumamos 1 a la variable Contador, con lo que ahora pasa a valer 2. Y AHORA es cuando llegamos a la condicin: es Contador<=300.000.000? Yo dira que s, as que ale, de vuelta a repetir: mostramos por pantalla nuestra frase, sumamos 1 a contador... [... varios minutos despus...] Y ya, por fin, Contador alcanza el valor 300.000.001, con lo que la comparacin dice "MENTIRA!", y se acab repetir esa tarea. Nuevamente, os invito a que me digais qu hubiera pasado si no hiciramos Contador <- Contador+1 ... Otra nota importante: Vamos a remarcar una diferencia IMPORTANTE entre esta estructura y la anterior "mientras". Si al empezar nuestro algoritmo, en vez de hacer Contador <- 1 hubisemos hecho Contador <- 1.000.000.000.000.000.000 de nuevo tenemos posibilidades de salirnos de rango, pero va, vamos a poner que esto que no fuera as; la palabra REPETIR no nos est pidiendo nada, as que ejecutamos una vez el cuerpo del ciclo. Se nos muestra la frase, se incrementa el contador, y llegamos al mientras. Como la condicin es falsa, no volvemos a ejecutar el ciclo. Cul es la diferencia? Pues que con la estructura "mientras", el ciclo se ejecutaba CERO veces, sin embargo, con la estructura "repetir...mientras que" el ciclo se ejecuta UNA vez. Esta sutil diferencia es la que hace que unas veces se elija al primero y otras al segundo. Estructura DESDE Esta estructura hubiera sido la ms adecuada para resolver nuestra situacin real, como veremos a continuacin. La estructura "desde", tiene una pequea peculiaridad, y es que ella solita incrementa (o decrementa) DE UNO EN UNO a la variable que utilicemos como contador. Su estructura es: desde Contador<-Inicio hasta Contador=Fin [, decrementar,] hacer accion 1 ........

accion N fin desde La palabra "decrementar" entre corchetes significa que es opcional, es decir, que se puede poner o no. Si NO se pone, por defecto se asume que al terminar las acciones del ciclo, se har Contador <Contador+1 Si ponemos "decrementar", al terminar las acciones del ciclo se har Contador <- Contador-1. Cuidado con esto, pues si no especificamos "decrementar", es ILEGAL escribir desde Contador<-500 hasta Contador=200 hacer as como, si escribimos "decrementar", es igualmente ILEGAL poner desde Contador<-1 hasta Contador=1257 , decrementar, hacer No se admite otro tipo de incrementos/decrementos (de 2 en 2, de 0.5 en 0.5 o de -10 en -10), para ello ya tenemos las estructuras "mientras" y "repetir...mientras", en las que nosotros elegamos el incremento/decremento. En el lenguaje de programacin Pascal esto tambin sucede as en los ciclos FOR. En otros lenguajes, como FORTRAN, BASIC o C, el FOR es mucho ms potente, siendo el caso del lenguaje C el que riza el rizo, pudiendo llegar a hacer verdaderas obras de arte con un "simple" ciclo FOR. Bueno, al grano O:) Supongo que la estructura est suficientemente clara, sin embargo, para terminar de clarificarla, vamos a aplicarla a nuestra BIEN conocida situacin REAL: Declaracin de variables ENTEROS: Contador fin Declaracin variables

inicio

desde Contador<-1 hasta Contador=300.000.000 hacer mostrar por pantalla 'Prometo ser bueno O:-)' fin desde

fin

Umm... lo primero que se observa es que no hace falta asignar el valor 1 a Contador fuera del ciclo, puesto que en la parte Contador<Inicio (Contador<-1, en este caso) ya se asigna automticamente ese valor. Lo siguiente es, como ya he mencionado, que no hace falta que incrementemos el valor de Contador, puesto que es una accin que se realiza sola en un ciclo de este tipo. Por ltimo, como no hemos usado la palabra decremento, se asume entonces que incrementamos de 1 en 1 el valor de la variable Contador. Y cmo se hubiera hecho esto usando decrementos? Pues, por ejemplo, as: Declaracin de variables ENTEROS: Contador fin Declaracin variables

inicio

desde Contador<-300.000.000 hasta Contador=1 , decrementar, hacer mostrar por pantalla 'Prometo ser bueno O:-)' fin desde

fin Aunque yo lo he hecho aqu por estar manejando variables de tipo entero, debo decir que es PELIGROSO usar una comparacin de IGUALDAD entre dos nmeros cualesquiera, y que, para evitar que por truncamientos, redondeos o algn otro motivo que lleve a prdidas de decimales en los nmeros, en vez de poner = es mejor poner <= o >=. As, en nuestros dos ejemplos de ciclo mientras, la lnea "decisoria" en el ciclo (por llamarla de alguna manera) es ms recomendable escribirla as: desde Contador<-1 mientras Contador<=300.000.000 hacer o as, en el caso del decremento: desde Contador<-300.000.000 mientras Contador>=1 , decrementar, hacer Y con esto queda terminado el captulo de las estructuras bsicas para escribir nuestros algoritmos.

Notar que aqu he cambiado la palabra hasta por la palabra mientras. Lo que quiere decir es que, mientras que Contador sea menor o igual que 300.000.000, seguiremos dentro del ciclo. "Ah, no, con la paliza que nos has dado, ahora la que no se escapa eres t. A ver, y qu hay de esas variables llamadas 'acumuladores' que has mencionado antes y que no has usado para nada?" Bueno, este... me alegro de que me haga esa pregunta! :-D Voy a poner un ejemplo de un acumulador para que se vea claro para qu sirven. Suponed, por ejemplo, que quiero sumar los primeros 10 nmeros naturales. Una posible solucin sera esta: Declaracin de variables ENTEROS: i,acum fin declaracin variables

inicio

acum<-0 desde i<-1 hasta i<=10 hacer acum<-acum+i fin desde

mostrar por pantalla acum fin Probad a seguirle la pista al ciclo, y decidme qu sale. Lo sabrais escribir usando las otras dos estructuras repetitivas vistas hoy? Si es as, hacedlo }:-) En el primer paso del ciclo, acum vale 0, y le sumamos lo que vale i, que es 1. Vale, ahora acum vale 1. Se incrementa i y volvemos al cuerpo del ciclo. Sumamos a acum lo que vale i. Ahora acum vale 1, e i vale 2; tras la suma, acum vale 3. A eso es a lo que me refera antes, unas cuantas (pero cuntas) lneas atrs, cuando deca eso de "ACUMULADOR, cuya misin es almacenar una cantidad variable resultante de operaciones sucesivas y repetidas. Es como un contador, con la diferencia que el incremento/decremento es variable". A diferencia de nuestro ejemplo REAL, en el que el incremento era siempre 1, aqu el incremento primero es 1, luego 2, luego 3... espero

que con este ejemplo quede ms claro, y si no, me peds que ponga otro, y otro... hasta que lo entendais. Otra nota (no s cuntas llevo): podemos anidar los ciclos. Esto es: dentro de un ciclo, podemos ejecutar otro ciclo, con la condicin de que ese otro ciclo est COMPLETAMENTE CONTENIDO dentro del primero, si no, el algoritmo no es vlido. Por ejemplo: El caso ms tpico de ciclo anidado es querer asignar valores a una matriz. Quien no sepa qu es una matriz, que espere al captulo 7 del curso. Supongamos que nuestra matriz tiene por dimensiones 10 y 12, y queremos asignar valores a cada una de sus componentes. Esto lo haremos as: Declaracin de variables A: Matriz(1..10,1..12) de ENTEROS ENTEROS: i,j {variables para recorrer la matriz} Fin declaracin de variables

Inicio

desde i<-1 hasta i<=10 hacer desde j<-1 hasta j<=12 hacer A(i,j)<-i+j fin desde {j} fin desde {i}

Fin Como veis, el ciclo que gobierna la variable j est totalmente contenido dentro del ciclo gobernado por la variable i, y, por cada iteracin del ciclo que dirige i, se ejecutan las 12 repeticiones del ciclo dirigido por j. Quin me dice cmo quedar nuestra matriz tras la asignacin de valores que hemos hecho? Para no marearos, tomar las filas con la i, y las columnas con la j, como es usual en la notacin de matrices. Vamos ahora a por lo que a m me gusta... los ejercicios };-D 1. Suponed que teneis un vector de 20 componentes (ver el captulo 7 del curso). Escribid un algoritmo que lo invierta, es decir, la componente 1 pasa a ser la 20, la 2 pasa a ser la 19, la 3 ser la 18... y as con todas.

2. Escribid un algoritmo que muestre por pantalla las tablas de multiplicar del 1 al 10. PISTA: Usad ciclos anidados. 3. Escribid un algoritmo que muestre por pantalla la suma de los cuadrados de los N primeros nmeros. 4. Escribid un algoritmo que calcule la media aritmtica de una serie de N nmeros. Eso es todo (ahora s), nos vemos en la prxima entrega, en la que hablaremos de... FUNCIONES Y PROCEDIMIENTOS. Introduccin a la programacin 5. Funciones y Procedimientos FUNCIONES Qu es una funcin? Matemticamente, una funcin no es ms que una aplicacin, esto es, una REGLA o CRITERIO para obtener un cierto resultado a partir de unos valores ya existentes. Este concepto se ha trasladado as al campo de la informtica, aunque conviene matizar un poco ms la idea. La idea de funcin es la de una "caja negra" en la que nosotros metemos datos, dentro de esa "caja" pasa *algo*, y entonces, de la "caja", sale un resultado, un "producto". Qu pasa dentro de esa "caja negra" depende; si somos nosotros quienes hemos de programarla, lo sabremos, pero si no, no tenemos por qu. Para poder usar la funcin slo necesitaremos saber qu datos de entrada admite, y de qu tipo ser el resultado. Hay que remarcar un detalle importante: las funciones devuelven un UNICO VALOR. Por ejemplo; dentro de un programa, podemos querer calcular la media aritmtica de una serie de datos. En principio, nosotros lo escribimos cuando tenemos que hacer los clculos. Pero ahora, resulta que ms adelante tenemos que volver a calcular la media aritmtica de otros datos. Y ms adelante, otra vez. Vamos a escribir el cdigo tantas veces? No sera ms lgico definirnos una funcin que se encargara de esa parte, y llamarla cuando la necesitemos? Muy bien... y cmo definimos una funcin? Pues de la siguiente manera: funcion NOMBRE (arg1,...,argN) : TIPO variables ......... {se declaran}

accion1 ....... accionN Resultado <- Valor fin funcion TIPO es el tipo de dato que devolver la funcin al terminar de hacer su trabajo. NOMBRE es el nombre que le vamos a dar a la funcin; por ejemplo, nuestra funcin se puede llamar Pepe o se puede llamar Media_Aritmetica. arg1 ... argN es la lista de parmetros que vamos a pasar a la funcin. La seccin "variables" es una seccin donde se declararn las variables a usar por la funcin. Ms adelante hablar del mbito de las variables, para que se entienda el por qu de esto. accion1 ... accionN es toda la faena que debe hacer la funcion. Al final de esa faena, la funcin devuelve un Resultado, que es el que hemos especificado como "Valor". Y a dnde va a parar ese "Valor"? Bueno, es que para poder usar una funcin, tenemos que *invocarla*, llamarla de alguna manera. Si las funciones son cajas que devuelven valores, tendremos que disponer algn sitio para meter ese valor que nos devuelva la funcin. Cmo la llamamos? Para poder llamar a una funcin, tendremos que tener definida en nuestra declaracin de variables una variable del MISMO tipo que devuelva la funcin. Entonces, lo que hacemos es asignar a esa variable lo que nos devuelva la funcin, haciendo lo siguiente: Variable <- Nombre_Funcion(arg1, ..., argN) Esta lnea hace lo siguiente: llama a la funcin Nombre_Funcion, pasndole los parmetros arg1, ..., argN; entonces, se ejecuta el cdigo de la funcin, hasta que llega al final, momento en que devuelve un valor, y este valor devuelto es asignado a la variable Variable. Vamos a ver un ejemplo. Supongamos que queremos hacer un programa que calcule, en varios puntos, la suma de los N primeros nmeros naturales, pero este N vara conforme el programa lo necesita. Queremos hacer una funcin que nos simplifique el trabajo. Cmo lo hacemos? Bueno, lo primero que hay que plantearse siempre es qu parmetros necesita la funcin para trabajar, qu tipo de valor va a devolver y, por ltimo, cmo va a hacer lo que tenga que hacer la funcin. En nuestro caso, la funcin slo necesita saber quin es N, que ser de tipo entero; como la suma de naturales es natural, el resultado a devolver tambin tendr que ser una variable de tipo entero. Falta ver cmo implementamos esa funcin. Por ejemplo, lo podemos hacer as (no voy a entrar ahora en mejoras):

funcion Suma_N_Naturales(ENTERO N) : ENTERO variables ENTERO: Suma,i

Suma <- 0 desde i<-1 hasta i=N hacer Suma <- Suma+i

Resultado <- Suma fin funcion y ahora, vamos a usarla. En nuestro programa podemos poner: Declaracion variables ENTEROS: N, Suma fin declaracion variables

inicio

desde N=1 hasta N=200 hacer Suma <- Suma_N_Naturales(N); mostrar por pantalla ('La suma de los ',N,' primeros naturales es ',Suma) fin desde

fin Con esto, hacemos 200 veces, incrementando en 1 cada vez N, la asignacin a la variable Suma del resultado obtenido por la funcin Suma_N_Naturales, y mostrando por pantalla el resultado. Cada vez que se llegue a la lnea de la asignacin, se llamar a la funcin Suma_N_Naturales, se ejecutar el cdigo de esa funcin, y al devolver el resultado, el programa principal recupera el control de la ejecucin.

Sin embargo, dentro de la funcin tenemos declarada una variable que se llama Suma, y en el programa principal hay otra variable que se llama Suma... cmo sabemos cul es la buena? no se mezclan ni nada parecido los valores? Bueno, creo que este es un buen momento para hablar de... AMBITO DE LAS VARIABLES Como ya hemos visto, un programa no tiene por qu estar formado por un nico mdulo (vamos a llamarle as) principal, si no que puede estar formado por muchas funciones, y por muchos procedimientos (de los que hablaremos ms adelante). Cada funcin, o cada procedimiento, puede tener, dentro de su seccin de declaracin de variables, sus propias variables, aunque se llamen igual que las de la funcin de ms arriba, puesto que, al declarar una funcin o un procedimiento, las variables que usan son LOCALES a ellos, es decir, slo ellos saben que existen y, por tanto, pueden usarlas. Como contraposicin a las variables locales, tenemos las GLOBALES, que se declaran en una seccin VARIABLES GLOBALES; estas variables son reconocidas por cualquier funcin o procedimiento que exista en nuestro programa, cualquiera puede modificar su valor en cualquier momento. Ahora, y si hay una variable global que tiene el mismo nombre que una variable local en una funcin que estoy usando? En ese caso, se usa la variable que es local a la funcin. En nuestro ejemplo no se da este conflicto, al no haber una seccin de variables globales (eso implica que no las hay), ya que cada variable Suma pertenece a una funcin distinta. Algunas notas respecto al tema de funciones: Es una buena costumbre escribir, justo antes de la definicin de la funcin, un comentario sobre qu hace la funcin, para qu nos van a servir los parmetros que vamos a pasarle, y qu es lo que devuelve. Hay que distinguir entre lo que se llama parmetros FORMALES y parmetros ACTUALES. Cuando definimos una funcin, en su CABECERA (la lnea donde pone su nombre, los argumentos que recibe y el tipo de valor que devuelve) aparecen nombrados los argumentos. El nombre que ponemos en ese momento es lo que se llama parmetros formales. Pero, cuando la llamamos, por ejemplo, Suma_N_Naturales(27), le estamos pasando el parmetro concreto 27: a estos parmetros se les llama parmetros actuales. Como ejercicio, escribid una funcin que devuelva el resultado de:

siendo x un nmero real y n un nmero natural. PROCEDIMIENTOS Se llama as a un subprograma que ejecuta unas ciertas acciones sin que valor alguno de retorno est asociado a su nombre. En otras palabras: NO devuelven valores (en cierto sentido). Los procedimientos son normalmente llamados desde el algoritmo principal mediante su nombre y una lista de parmetros actuales (como las funciones) a travs de una instruccin especfica: LLAMAR (CALL, en ingls) Se diferencian de las funciones en que los parmetros de llamada pueden ser modificados si as se especifica dentro del procedimiento; en ese sentido se puede interpretar como que devuelven valores. La forma de declararlos es la siguiente: PROCEDIMIENTO Nombre (Lista de parmetros formales) variables

accin1 ....... accinN Fin Procedimiento y la forma de usarlos: LLAMAR_A Nombre(Lista de parmetros actuales) Vamos a ver un ejemplo de todo esto: queremos tener una forma de calcular la suma, la resta, el producto y el cociente de dos nmeros cualesquiera. Obviamente, vamos a necesitar 6 variables; 2 de ellas sern los factores, y las otras 4, el resultado de las correspondientes operaciones. Podramos pensar en 4 funciones que devolvieran cada una de ellas un nmero (entero, real, ...), pero podemos hacer esto de forma ms compacta con un procedimiento. Veamos cmo lo declararamos:

PROCEDIMIENTO Cuentas(ENTERO a, ENTERO b, ENTERO sum, ENTERO dif, ENTERO mul, ENTERO dif)

sum <- a+b dif <- a-b mul <- a*b div <- a/b

Fin Procedimiento y luego lo podramos llamar as: LLAMAR_A Cuentas(5, 3, SUMA, RESTA, MULT, DIV) con lo que a las variables SUMA, RESTA, MULT, DIV les seran asignados sus correspondientes valores; estas variables se supone que ya estn declaradas previamente. Y llegamos al ltimo punto de esta entrega: RECURSIVIDAD Una buena definicin de este concepto es la siguiente. Recursivo: ver recursivo ... :-D ... O:-) Aunque, si lo quereis de otra forma: propiedad de una funcin o de un subprograma de llamarse a s mismo. Ilustremos esto con un ejemplo, nuestra funcin para sumar los N primeros nmeros naturales. Vamos a escribirla de esta otra forma: funcion Suma_N_Naturales(ENTERO N) : ENTERO variables ENTERO: Suma

si (N=1) entonces Suma <- 1 si no Suma <- N+Suma_N_Naturales(N-1)

fin si

Resultado <- Suma fin funcion Y vamos a llamarla con Suma_N_Naturales(4), detallando los pasos: si (4=1) {falso, no se ejecuta} si no {cierto, se ejecuta} Suma <- 4+Suma_N_Naturales(4-1) {4-1=3} Entramos en Suma_N_Naturales(3): si (3=1) {falso, no se ejecuta} si no {cierto, se ejecuta} Suma <- 3+Suma_N_Naturales(3-1) {3-1=2} Entramos en Suma_N_Naturales(2): si (2=1) {falso, no se ejecuta} si no {cierto, se ejecuta} Suma <- 2+Suma_N_Naturales(2-1) {2-1=1} Entramos en Suma_N_Naturales(1): si (1=1) entonces Suma <- 1 y se devuelve el control al punto donde se llam a Suma_N_Naturales(2), donde tenemos Suma <- 2+1, con lo que se devuelve el control al punto donde se llam a Suma_N_Naturales(3), teniendo Suma<-3+(2+1), momento en el que se devuelve el control al punto donde se llam a Suma_N_Naturales(4), donde tenemos Suma <- 4+(3+(2+1)), justo el resultado esperado. Introduccin a la programacin 6. Punteros; esos desconocidos Antes de explicar qu son, para qu sirven y cmo hacer uso de ellos, vamos primero a exponer unas cuantas consideraciones: Los punteros no estn disponibles en todos los lenguajes de programacin, ello significa que si, por ejemplo, programais en C, podeis utilizarlos, pero si programais en Basic no. Su uso produce unas ciertas ventajas sobre los programas, y es que aumentan la flexibilidad a la hora de, por ejemplo, declarar vectores o matrices cuyo tamao no sea predefinido. No acaban ah las ventajas, con estructuras de datos ms complejas son el pan nuestro de cada da, pero de todo eso ya hablaremos. Sin embargo, no todo es maravilloso, y tienen serios inconvenientes que provocan ms de un quebradero de cabeza. Es muy fcil equivocarse usndolos y con ello escribir en alguna zona de memoria no aconsejable (como las reservadas por el sistema operativo), lo que

provoca el consiguiente cuelgue en sistemas poco robustos que permitan escribir en cualquier parte. No hay nada ms peligroso que un puntero incontrolado o sin inicializar. Vistas las pegas (ya las descubrireis cuando el programa se os cuelgue sin motivo aparente), vamos a ver qu es eso de los punteros, pues parece que tenemos que tenerles un cierto respeto :-D Qu es un puntero Intuitivamente, un puntero es una flecha que apunta a alguna parte. A qu parte? Obviamente, si estamos hablando de ordenadores, apuntar a una cierta direccin de memoria. Es decir, un puntero es una representacin simblica de una direccin de memoria. (Nota importante: voy a usar la notacin de C para los punteros) Veamos un ejemplo; supongamos que tenemos declarada la variable Variable_Misteriosa en nuestro programa. Si queremos saber cul es la direccin de dicha variable, pondremos lo siguiente: &Variable_Misteriosa { el smbolo & precediendo a una variable es el operador direccin de memoria } y si, por ejemplo, escribimos en nuestro programa: Mostrar_por_Pantalla(&Variable_Misteriosa) saldr en pantalla (por decir algo): 56743 que no es ms que la celdilla de la memoria en la que se almacena el valor que nosotros identificamos con Variable_Misteriosa. Es decir, si hemos hecho previamente (suponiendo que fuera una variable entera): Variable_Misteriosa <- 9 lo que significa es que en la direccin de memoria 56743 est almacenado el valor 9. Est todo claro hasta aqu? Bien, pues sigamos :) En el caso que he puesto como ejemplo, lo que tenamos era una *constante* puntero. Pero tambin podemos declarar como variables, variables de tipo puntero. Estas variables contendrn, como hemos dicho, una direccin de memoria. Por ejemplo, si tenemos una variable puntero que se llame Mi_Puntero, y una variable normal que se llame Mi_Variable, podemos hacer cosas como esta: Mi_Puntero <- &Mi_Variable con lo que en Mi_Puntero tenemos almacenada la direccin de memoria de Mi_Variable (y decimos que Mi_Puntero APUNTA a Mi_Variable). Y aqu surge el primer problema. Si hacemos: Mi_Puntero <- Mi_Variable

en Mi_Puntero est almacenada, como direccin de memoria, el valor de la variable Mi_Variable. Si luego hemos de escribir algo en la zona de memoria a la que apunta Mi_Puntero, ya la hemos liado, puesto que no sabemos qu puede haber ah. Resumiendo: no es lo mismo la direccin de memoria de una variable que el contenido de la variable (o, lo que es lo mismo, el contenido de esa direccin de memoria). Seguimos. Como hemos dicho que Mi_Puntero es una variable de tipo puntero, podemos hacer, ms adelante en el curso del programa, que apunte a otra variable de la misma forma. Ya sabemos que Mi_Puntero apunta a Mi_Variable. En este caso, podemos utilizar el operador de indireccin * (tambin es de C; no confundirlo con el operador de multiplicacin) para encontrar el valor almacenado en Mi_Variable. Cmo? Escribiendo (por ejemplo): Mi_Puntero <- &Mi_Variable Mostrar_por_Pantalla(*Mi_Puntero) es exactamente lo mismo que hacer: Mostrar_por_Pantalla(Mi_Variable) Lo que hemos hecho ha sido apuntar a Mi_Variable con Mi_Puntero (es decir, Mi_Puntero contiene la direccin de memoria de Mi_Variable) y despus, con el operador *, mostrar el CONTENIDO de lo que hay en la direccin de memoria que guarda Mi_Puntero. Es decir, lo que hace el operador de indireccin es, seguido de un puntero, dar el valor almacenado en la direccin de memoria a la que apunta el puntero. S que todo esto es un trabalenguas de cuidado, as que releed con cuidado la primera parte del texto y seguidle bien la pista. Haced algn dibujo si eso os ayuda. Mientras, yo prosigo con el punto siguiente: Declaracin de punteros. He dicho antes que podemos tener variables de tipo puntero, as que, lo lgico es querer saber cmo declararlas, y a eso es a lo que vamos. Cuando declrabamos (hace ya mucho tiempo) variables de tipo entero, ponamos: a,b,c : ENTEROS No podramos poner para los punteros algo como:? a,b,c: PUNTEROS Bien, pues la respuesta es NO. Y por qu no? Pues porque para declarar un puntero necesitamos saber, aparte de que va a apuntar a alguien, a qu TIPO de alguien va a apuntar, es decir, a qu tipo de variable va a apuntar. No ser lo mismo apuntar a un entero que a un caracter o que a un real, pues estos tipos ocupan distintos

tamaos en memoria, y eso es algo fundamental para otra cosa que veremos ms adelante, la aritmtica de punteros. Para declarar una variable de tipo puntero a un tipo de dato, lo haremos como sigue: *Puntero1 *Puntero2 : CARACTER : ENTERO

*Puntero3, *Puntero4 : REAL (esto en C lo haramos as: char *Puntero1; int *Puntero2; float *Puntero3, *Puntero4 ;) y tenemos que Puntero1 ser una variable puntero que apunte a una variable de tipo caracter, Puntero2 apuntar a una variable de tipo entero y Puntero3 y Puntero4 apuntarn a variables de tipo real. Ahora que los tenemos declarados, suponiendo que tengamos las variables Var1 de tipo caracter, Var2 de tipo entero y Var3 de tipo real, podemos inicializarlos haciendo lo que ya hemos visto: Puntero1 <- &Var1 Puntero2 <- &Var2 Puntero3 <- &Var3 y acceder a sus contenidos escribiendo: *Puntero1 *Puntero2 *Puntero3 sin embargo, si se nos ocurre usar en el programa: *Puntero4 puede pasar de todo. Por qu? Pues porque este puntero no est inicializado (lo he dejado a drede). Eso significa que, en principio, puede contener cualquier cosa. Al ser un puntero, esa ''cualquier cosa'' ser interpretada como una direccin de memoria, y el contenido de ''cualquier direccin de memoria'' puede ser de lo ms inslito, lo que no es muy recomendado si, por ejemplo, estamos haciendo clculos. Una cosa que no hay que perder de vista es que los punteros, al ser variables, tienen una posicin de memoria en la que se guarda su contenido. Es decir, si hacemos: &Puntero1 estamos accediendo a la direccin de memoria del puntero Puntero1. Y el contenido de esa direccin de memoria es la direccin de memoria de la variable a la que apunta.

Aritmtica de Punteros. Trabajando con punteros, qu sentido tiene hacer:? Puntero <- Puntero + 1 Pues eso depende de a qu tipo de variable est apuntando la variable Puntero. Si Puntero apunta a un carcter, como un carcter ocupa 1 byte en memoria, al hacer la operacin anterior, Puntero est apuntando al byte siguiente al que apuntaba antes. Si la operacin que hacemos es: Puntero <- Puntero - 1 lo que hace es apuntar al byte anterior. Sin embargo, si Puntero apunta a un real, como un real ocupa en memoria 10 bytes, en este caso apunta a los 10 bytes anteriores al que estaba apuntando. En otras palabras, cuando sumamos 1 a un puntero, no estamos dicindole que apunte a la direccin siguiente, sino que pase a apuntar a la siguiente celdilla de memoria de acuerdo con el tipo base al que apunta. Y si en vez de sumar (o restar) 1, sumamos (o restamos) N, avanzamos N veces lo que ocupe el tipo de variable al que estamos apuntando. Adems, tambin podemos sumar y restar punteros. Veamos unos ejemplos para aclararlo. Supongamos que Puntero1 y Puntero2 son punteros a enteros, y hacemos: Puntero2 <- Puntero1 + 4 entonces, Puntero2 apunta a la posicin de memoria 8 bytes posterior a la que apunta Puntero1. Y si hacemos: Puntero2 <- Puntero1 - 1 Puntero2 apunta a la posicin de memoria 2 bytes anterior a la que apunta Puntero1. Tambin podemos hacer: i <- Puntero2 - Puntero1 Esto normalmente se hace dentro de un mismo array, para saber cuntos elementos los separan. Notar que el resultado que da no es en bytes, sino en las mismas unidades que el tamao del tipo del array. Este resultado debe ser asignado a una variable de tipo entero (la variable i que aparece en el ejemplo se presupone previamente declarada). Y todo esto para qu sirve? Hablar de punteros por hablar puede ser muy entretenido si no se tiene nada mejor que hacer, pero resulta que yo he dicho que son muy tiles y no lo he dicho gratuitamente. Por ejemplo, ahora que sabemos lo que son los punteros, vamos a ver que estn relacionados con el paso de parmetros en las funciones, con lo que hablaremos de paso de variables por valor y por referencia. En su da hablamos de funciones y de procedimientos, y dijimos que, en el caso de las funciones, pasbamos una serie de variables que no eran modificadas, y se nos devolva un nico valor. Por contra, en los

procedimientos pasbamos una serie de variables que podan ser modificadas pero, a cambio, no se nos devolva ningn valor. Esto es as en lenguajes como el Pascal, pero en C esto no sucede. Quiero decir, que en C no tenemos funciones y procedimientos, sino que slo tenemos funciones. Las funciones siguen teniendo la caracterstica de que devuelven un nico valor, y que las variables que le pasamos como argumentos no pueden ser modificadas. Y si necesito que se me devuelvan dos valores? Cmo lo hago, si el C slo me permite funciones? Pues lo hago con lo que se llama ''paso de parmetros por referencia''. En primer lugar, he de decir que en C, cuando pasamos variables a las funciones, lo que hacemos es un ''paso de parmetros por valor''. Es decir, la funcin recibe los valores de las variables, pero no sabe nada ms de ellas. Cuando hacemos un paso por referencia, lo que estamos pasando a la funcin no es el valor de la variable, sino la direccin de memoria. Y la funcin, al tener la direccin de memoria de la variable, ya s puede modificarla, pudiendo, en cierto sentido, ''devolvernos'' varios valores, solucionando el problema que tenamos al no disponer de procedimientos. Voy a poner un ejemplo de esto comentado para que se entienda la estructura y el por qu. Y para ello, voy a utilizar un ejercicio que ya propuse, el de escribir un procedimiento que intercambie el valor de dos variables. El algoritmo de este procedimiento es algo tan sencillo como esto: PROCEDIMIENTO Intercambia(X,Y: ENTEROS) variables auxiliar: ENTERO

inicio

auxiliar <- X X <- Y Y <- auxiliar

fin y lo podemos llamar desde cualquier punto del programa principal sin ms que poner LLAMAR_A Intercambia(Un_Valor,Y_Otro_Valor)

Sin embargo, como ya he comentado, en C no tenemos procedimientos, cmo salvamos este escollo?. Pues lo salvamos con una funcin como la siguiente: void Intercambia(int *x,int *y) { int aux; aux=*x; *x=*y; *y=aux; } y llamamos a esta funcin desde el programa principal como sigue: int main(void) { int a=2,b=3;

printf("\nPrimero, a=%d y b=%d\n",a,b); Intercambia(&a,&b); printf("\npero ahora, a=%d y b=%d\n",a,b); return 0; } Veamos cosas: para empezar, al llamar a la funcin Intercambia, no le hemos pasado los valores de las variables (paso por valor), sino que le hemos pasado las direcciones de las variables (paso por referencia). As pues, los parmetros formales de la funcin Intercambia estn recibiendo direcciones de memoria, por lo que deben declararse como punteros, cosa que hemos hecho en la cabecera de la funcin, indicando que recibe dos punteros. Ahora veamos la funcin: en primer lugar, creo la variable auxiliar necesaria para hacer el cambio. Sin embargo, en vez de hacer: aux <- x hago: aux <- *x es decir, asigno a aux el contenido de la direccin de memoria a la que apunta x. Como, al llamar la funcin, hemos pasado unas direcciones de memoria, *x da como resultado el contenido de la direccin de memoria donde se guarda la variable a. Si hubiera hecho: aux <- x en aux tendr almacenada la posicin de memoria de la variable a y no su contenido, que es lo que yo quiero. A continuacin hacemos:

*x <- *y es decir, al contenido de la posicin de memoria a la que apunta x se le asigna el contenido de la posicin de memoria a la que apunta y. Y ya termina el intercambio con: *y <- aux con lo que al contenido de la posicin de memoria a la que apunta y se le asigna el valor de la variable aux, que era el contenido de la posicin de memoria a la que apuntaba x originalmente, en otras palabras, el valor de la variable a. Si tras leer con calma este punto un par de veces os perdeis, me dejais una nota con las lneas que os parezcan ms oscuras, porque esto es un buen trabalenguas mental O:) La otra gran utilidad es la reserva dinmica de memoria. Si quereis, puedo dar aqu unos pequeos esbozos, pero eso ya quedara para otro captulo. Creo que con 400 lneas sobre punteros, para empezar, ya teneis bastante O:) Introduccin a la programacin 7.I. Vectores La idea de vector, en informtica, es la siguiente: imaginad que en vuestro programa necesitais 10.000 variables de tipo entero que representen cada una de ellas la temperatura de unos pueblos. Imagino que a nadie se le habr ocurrido ponerse, en la declaracin de variables, a declarar una por una las 10.000 variables que se necesitan. Dado que son variables que estn relacionadas entre s por su significado (y eso es algo que lo decide siempre el programador), parece lgico querer ponerles un nombre comn, y que sea el ndice (en qu componente de vector se encuentran) lo que las distinga. Vemos pues que los vectores nos dan unas ciertas ventajas: declarar muchas variables relacionadas entre s de un mismo tipo de una vez, y acceder a cualquiera de ellas usando tan slo un ndice. Declararemos algo como esto (lo precisamos un poco ms adelante): Temperaturas: es un vector de reales con 10.000 componentes Para referirnos a los elementos de un vector, tenemos que especificar el ndice del elemento que estamos tratando: v[i]. As, asignaremos un valor haciendo v[i] <- 3 y leeremos un valor haciendo m <- v[i]. Asignaremos valores a las componentes de nuestro vector de temperaturas, bien a mano: Temperaturas[1] Temperaturas[2] Temperaturas[3] Temperaturas[4] ... <<<<23.5 22.7 25.2 20.4

o bien en un ciclo:

desde i=1 hasta i=10.000 hacer Temperaturas[i] <- Medida_Temperatura fin desde y, en la memoria del ordenador, lo que tendremos ser algo como: |--------| | 23.5 | Este es Temperaturas[1] |--------| | 22.7 | Este es Temperaturas[2] |--------| | 25.2 | Este es Temperaturas[3] |--------| | 20.4 | Este es Temperaturas[4] |--------| | ...... | |--------| | 19.2 | Este es Temperaturas[10000] | -------| Para acceder a cualquier componente del vector, slo tendremos que poner Temperaturas[posicion], donde posicion ser el nmero de orden. Vamos a ser un poco ms precisos con la nomenclatura: para declarar un vector de N elementos (numerados del 1 al N) de tipo X, lo haremos de la siguiente manera: Variable: Vector[1..N] de Tipo; Por ejemplo, para declarar un vector de 20 enteros, haremos: v: Vector[1..N] de Entero; Qu cosas podemos hacer con un vector? Esto depende de quines lo integren; me explico: si nuestro vector est formado por nmeros, podremos sumar, restar y multiplicar vectores. Sin embargo, estas funciones ya NO forman parte del lenguaje de programacin, si no que tendremos que hacrnoslas nosotros. En el caso de vectores numricos, veremos cmo se puede escribir el pseudocdigo para algunas de ellas.

Ya he mencionado que los vectores no slo pueden ser de nmeros, sino tambin de caracteres. Por ejemplo, podemos tener el siguiente vector de caracteres: |-----| | A | |-----| | G | |-----| | J | |-----| | H | |-----| | R | |-----| Quiz sin mucho sentido, pero s con caracteres :) Ahora, no hace falta un alarde mucho mayor de imaginacin para poner el siguiente vector de caracteres: |-----| | H | |-----| | O | |-----| | L | |-----| | A | |-----| Vaya sorpresa: una palabra ;) S, los vectores de caracteres se usan para formar lo que se conoce bajo el nombre de "cadenas de caracteres". Las forma de trabajar con las cadenas de caracteres depende del lenguaje de programacin usado. Nosotros emplearemos la siguiente convencin: para declarar una cadena de caracteres, usaremos el tipo "cadena", diciendo cuntos caracteres tiene la cadena. Por ejemplo: str: Cadena[10]; Esto ser una cadena de 10 caracteres. Adems, escribiendo str estamos haciendo referencia a la cadena completa, mientras que si escribimos str[i] nos estamos refiriendo al carcter i-simo de la cadena. Como deca ms arriba, la suma de dos vectores tiene sentido si hablamos de vectores numricos, pero, qu sentido tiene "sumar" dos cadenas de caracteres? Pues el que nosotros le queramos dar, y este suele ser el de CONCATENAR, es decir, obtener una nueva cadena de caracteres, de mayor tamao, y que tenga, primero, los caracteres de la primera cadena para, a continuacin, pasar a tener los caracteres de la segunda cadena (mucho ojo, que esto no es tan trivial como suena). Por ejemplo, supongamos que tenemos las cadenas siguientes: cadena1 <- ['H','o','l','a'] cadena2 <- ['M','u','n','d','o']

y hacemos: cadena <- cadena1+cadena2 tendremos, en cadena: cadena <- ['H','o','l','a','M','u','n','d','o'] y no cadena <- ['H','o','l','a',' ','M','u','n','d','o'] puesto que al concatenar, no se aaden espacios. Como ya hemos dicho, el mundo de las cadenas de caracteres depende del lenguaje de programacin, por lo que nosotros las usaremos sin entrar en consideraciones especiales. Ser cuando aprendamos un lenguaje de programacin concreto cuando tendremos que atenernos a sus normas. Antes, cuando he hablado de "operaciones" con vectores, he dicho que haba que definirlas. Veamos algunos ejemplos: Queremos sumar dos vectores. Lo primero de todo, es que el nmero de componentes ha de ser el mismo (si nos vamos al smil de algn espacio Rn). Llamamos U y V a nuestros dos vectores, y W al vector suma. Las componentes de W, como sabemos, las obtendremos as: desde i=1 hasta i=tamanyo hacer W[i] <- U[i] + V[i] fin hacer La resta es igualmente sencilla (y queda como ejercicio al lector ;) ). Ahora, multiplicar dos vectores... cmo? Si nuestro vector representara algo en R3, tenemos dos productos (conocidos) para estos vectores: el vectorial y el escalar, en otro Rn, tenemos el producto escalar. Pongamos que queremos calcular el producto escalar. Sabemos que el resultado de esa multiplicacin NO es un vector, sino que el resultado es un nmero. En el caso del producto vectorial, el resultado es un vector. O podemos inventarnos nosotros el producto. Podemos querer que sea como la suma: que la componente i-sima del vector sea el producto de las componentes isimas de los vectores factores. Todo depende del sentido que le queramos dar a esa operacin. Por ejemplo, en el caso en que queramos que cada componente sea el producto de las otras dos, el algoritmo es un mero calco del de la suma: desde i=1 hasta i=tamanyo hacer W[i] <- U[i]*V[i] fin hacer Y, en el caso, del producto escalar, tampoco tiene mucha complicacin. producto=0 desde i=1 hasta i=tamanyo hacer producto <- producto + ( U[i]*V[i] )

fin hacer Resumiendo: no hay definidas operaciones para vectores, slo las que nosotros queramos usar, y para ello tendremos que programarlas. Tambin podemos querer hacer otras cosas con vectores, como, por ejemplo, ORDENARLO, cuestin que resolveremos ms adelante. Unos pequeos ejercicios: 1.- Escribid funciones que implementen las operaciones conocidas con vectores (y las que se os ocurran): suma y resta de vectores, producto de un nmero por un vector... 2.- Dados dos vectores de caracteres, escribid una funcin que devuelva un vector de caracteres que sea la concatenacin de los dos dados. Eso es todo por ahora :) Introduccin a la programacin 7.II. Matrices Tenemos otra estructura, fuertemente basada en la idea matemtica de matriz, y que tiene el mismo nombre: matriz (o "array", para quien le guste ms el ingls). Una matriz representa la idea de "tabla": una disposicin de la informacin en forma de filas y columnas. Por ejemplo: [ 3 -4.5 [ 4.1 2 0.1 ] -1 ]

En este ejemplo tenemos una matriz formada por dos filas y tres columnas. El elemento de la posicin (2,3) (fila 2, columna 3) es el -1. Podemos entender las matrices como vectores cuyos elementos son vectores. De hecho, en casi todos los lenguajes de programacin, esto es as. Segn este punto de vista, la matriz del primer ejemplo es un vector de dos elementos: el primero, el vector [3, -4.5, 0.1], y el segundo, el vector [4.1, 2, -1]. Para declarar una variable de tipo matriz escribiremos: m: Array[1..N,1..M] de Tipo; siendo N el nmero de filas que tendr la matriz, y M el nmero de columnas. Para referirnos a la posicin (i,j), usaremos la nomeclatura m[i,j]. Por ejemplo: m: Array[1..3,1..5] de Entero; m[2,3] <- 4; m[1,5] <- -2; No perder de vista la declaracin de una matriz: puede contener elementos de cualquier tipo. Enteros, reales, cadenas de caracteres, o tipos definidos por el usuario (estos los estudiamos en el captulo siguiente).

Recorrer los elementos de una matriz requiere de un ciclo dentro de otro ciclo. Por qu? Pues porque, para cada fila que recorramos, tendremos que recorrer cada elemento de las columnas. As, empezaremos entrando en la fila 1, y dentro de la fila 1 recorreremos los elementos 1 a M de que constan las columnas. Hecho esto, pasamos a la fila 2, y dentro de la fila 2 volvemos a recorrer los elementos 1 a M de las columnas. Siguiendo este proceso, acabaremos recorriendo todos los elementos de la matriz. Por ejemplo, para sumar dos matrices (en el sentido matemtico, teniendo en cuenta que entonces sern de tipo numrico), tendremos que ir elemento a elemento sumando los valores que se encuentren en las posiciones (i,j). Es obvio que la suma de dos matrices slo tiene sentido cuando las matrices a sumar tienen el mismo nmero de filas y de columnas. Una algoritmo sencillo para sumar dos matrices, almacenando su suma en una tercera, sera: desde i <- 1 hasta i = N hacer desde j <- 1 hasta j = M hacer C[i,j] <- A[i,j] + B[i,j]; fin desde fin desde Anlogamente realizaramos la resta. Tenemos una clara aplicacin de las matrices en el mundo de la programacin grfica. Las transformaciones de los puntos pueden representarse en trminos de unas ciertas matrices, y obtener la transformacin de un punto (una rotacin, una traslacin o un cambio de escala) consiste sencillamente en multiplicar las coordenadas del punto por la matriz correspondiente. Introduccin a la programacin 8. Tipos definidos por el usuario (el tipo registro) Qu es un tipo definido por usuario? Vamos a responder a esta pregunta poniendo un ejemplo. Imaginemos que queremos realizar un programa que trabaje con fichas de alumnos. Debemos empezar plantendonos qu datos son los que queremos almacenar del alumno. Por ejemplo, podemos querer su nombre, apellidos, edad, curso y nota media. Perfectamente podemos, simplemente, hacer la siguiente declaracin de variables: Nombre, Apellidos: Cadena[255]; Edad, Curso: Entero; NotaMedia: Real; e ir usndolas en el programa. Esta declaracin nos sirve para una nica ficha de alumnos. Si queremos trabajar con dos alumnos, entonces tendramos que hacer:

Nombre1, Nombre2, Apellidos1, Apellidos2: Cadena[255]; Edad1, Edad2, Curso1, Curso2: Entero; NotaMedia1, NotaMedia2: Real; Si queremos trabajar con tres, la cosa empieza a enrevesarse. Tenemos cada vez ms variables. Podra definir un tipo "Alumno" que contuviera la informacin que quiero y usarlo como si fuera una nica variable? La respuesta es s. Este tipo "Alumno" sera lo que se conoce como "tipo definido por el usuario". Ahora bien, cmo lo definiramos? Usaremos la notacin: Tipo TAlumno Nombre, Apellidos: Cadena[255]; Edad, Curso: Entero; NotaMedia: Real; Fin Tipo; es decir: Tipo NombreTipo Variable1: Tipo1; ... VariableN: TipoN; Fin Tipo; Ahora, para declarar variables de tipo TAlumno, simplemente escribiremos: Alumno: TAlumno; O, si queremos ms de una variable de tipo TAlumno: Alumno1, Alumno2, Alumno3: TAlumno; Para acceder a las variables contenidas en el tipo, usaremos la notacin punto (.). Por ejemplo, para acceder a los apellidos del segundo alumno declarado, escribiremos: Alumno2.Apellidos Podemos usar esta notacin tanto para recuperar el valor almacenado como para establecer uno nuevo: NombreAlumno := Alumno3.Nombre; Alumno2.Edad := 17; La definicin de tipos es muy poderosa: dentro de la definicin de un tipo, podemos usar como tipo para una variable otro tipo definido por nosotros previamente declarado. Por ejemplo, una vez definido el tipo TAlumno, podemos definir un tipo TClase que contenga, a su vez, tipos TAlumno: Tipo TClase Alumnos: Vector[1..30] de TAlumno; NumeroClase: Entero;

LetraClase: Carcter; ProfesorTutor: Cadena[255]; Fin Tipo; Hemos visto, adems, que tipos definidos por el usuario y vectores se pueden combinar de igual manera: dentro de un tipo definido por el usuario, puedo declarar una variable de tipo vector. Si declaramos la variable: Clase: TClase; acceder a la edad del alumno nmero 23 de dicha clase ser tan sencillo como hacer: Clase.Alumnos[23].Edad Ahora podemos empezar a pensar en resolver problemas complejos. Por ejemplo, tengo una clase de 30 alumnos y quiero ordenar ese vector de alumnos por orden alfabtico. Ejemplos 1. Definir una estructura que represente una ficha de un empleado con los datos siguientes: Nombre, apellidos, ao de entrada en la empresa, sueldo mensual bruto, sueldo mensual neto. Declarar dos variables de este tipo. 2. Tipo TEmpleado 3. 4. Nombre, Apellidos: Cadena[100]; AnyoEntrada, SueldoBruto, SueldoNeto: Entero;

5. Fin Tipo; 6.

Empleado1, Empleado2: TEmpleado; Tambin puede definirse: Empleados: Vector[1..2] de TEmpleado; 7. Definir una estructura que represente una ficha de un paciente con los datos siguientes: Nombre, apellidos, fecha de entrada en el hospital, clase de dolencia. Declarar cincuenta variables de este tipo. 8. Tipo TPaciente 9. Nombre, Apellidos: Cadena[100];

10. 11. 12. 13.

DiaEntrada, MesEntrada, AnyoEntrada: Entero: Dolencia: Cadena[255]; Fin Tipo;

Pacientes: Vector[1..50] de TPaciente; Ejercicios 1. Definir una estructura que represente una ficha de un empleado con los datos siguientes: Nombre, apellidos, direccion, nmero de telfono, fecha de entrada en la empresa, sueldo bruto al mes, sueldo neto al mes, cargo, departamento al que pertenece. Declarar 20 variables de este tipo. 2. Definir una estructura que represente una ficha de alumno con los datos siguientes: Nombre, apellidos, direccion, nmero de telfono, fecha de nacimiento, curso, notas de las cinco asignaturas, nota media. Declarar 30 variables de este tipo. 3. Definir una estructura que represente una ficha de un libro con los datos siguientes: Nombre del libro, autor, fecha de la edicin, ISBN. Declarar 50 variables de este tipo. Introduccin a la programacin 9.I. Algoritmos de ordenacin Los algoritmos de ordenacin son aquellos que se preocupan por ordenar los elementos de un vector. Para ordenar los elementos de un vector hay que decidir dos cosas: por qu campo vamos a ordenar, y que querr decir que un vector est ordenado. Por ejemplo, podemos tener un vector cuyas componentes sean registros que contengan datos sobre personas (nombre, apellidos, telfono, etc). Tenemos varias posibilidades: decidir ordenar por nombre, por apellidos, por telfono... Adems, si ordenamos por nombre, ser de la A a la Z o de la Z a la A; igual si ordenamos por apellidos, mientras que si ordenamos por telfono podemos querer hacerlo de forma ascendente o descendente. Si nuestro vector es, por contra, numrico, tenemos menos cosas que decidir, ya que al no tratarse de una estructura compleja hay un nico campo por el que ordenar. An as, tendremos que decidir si

consideraremos que el vector est ordenado de forma ascendente o descendente. Vamos a estudiar los dos algoritmos ms sencillos de ordenacin. No son los ms eficientes, pero sirven para ofrecer una primera idea de cmo realizar la tarea de ordenacin. Para aprender sobre algoritmos ms eficientes podemos buscar informacin adicional en la web (Google es siempre un buen aliado). Algoritmo de seleccin El mtodo de seleccin se basa en la siguiente idea: tenemos un vector inicialmente desordenado. Buscamos el elemento ms pequeo dentro del vector y lo comparamos con el elemento de la primera posicin. Si el elemento de la primera posicin es mayor que el mnimo del vector, entonces intercambiamos los elementos. Ahora ya tenemos en la primera posicin el elemento ms pequeo. Nos olvidamos de l, y buscamos, dentro del subvector [2..N] (N el nmero de elementos del vector) el elemento ms pequeo. Comparamos este mnimo con el elemento de la primera posicin del subvector. Si el elemento de la primera posicin del subvector es mayor que el mnimo del subvector [2..N], intercambiamos los elementos. Procedemos de forma anloga hasta terminar de recorrer el vector. Vamos a ver un ejemplo que aclarar cmo funciona este mtodo. Supongamos que tenemos el vector formado por los elementos [5, 4, 3, 2, 1] y queremos ordenarlo de forma ascendente. Empezamos buscando el valor mnimo del vector: el 1. El elemento de la primera posicin es el 5. Como 5>1, intercambiamos los elementos 1 y 5, quedando el vector como sigue: [1, 4, 3, 2, 5] Ya tenemos el 1 bien colocado. Ahora examinamos el subvector [2..5] (los elementos de las posiciones 2 a 5, es decir, [4, 3, 2, 5]). El mnimo dentro de este subvector es el 2, mientras que el primer elemento del subvector es el 4. Como 4>2, intercambiamos los elementos, quedando el vector como sigue: [1, 2, 3, 4, 5] Ya tenemos el 1 y el 2 bien colocados. Ahora examinamos el subvector [3..5] (los elementos de las posiciones 3 a 5, es decir, [3, 4, 5]). El mnimo dentro de este subvector es el 3, y el primer elemento del subvector es el 3. Como coinciden, no realizamos ningn intercambio, quedando el vector como sigue: [1, 2, 3, 4, 5] Ya tenemos el 1, el 2 y el 3 bien colocados. Examinamos el subvector [4..5] (los elementos de las posiciones 4 a 5, es decir, [4, 5]). El mnimo dentro de este subvector es el 4, y el primer elemento del subvector es el 4. Como coinciden, no realizamos ningn intercambio, quedando el vector como sigue: [1, 2, 3, 4, 5] Y ya no es necesario seguir, porque el subvector que nos quedara por comprobar slo tiene un elemento, que seguro que es el ltimo.

Suponiendo que tenemos un vector de enteros, el algoritmo quedara como sigue: VARIABLES v: Vector[1..N] de Entero; i, j, min, posMin, aux: Entero; FIN VARIABLES

desde i = 1 hasta N-1 hacer min = v[i]; posMin = i; desde j = i hasta N hacer si v[j] < min entonces min = v[j]; posMin = j; fin si fin desde

aux = v[i]; v[i] = v[posMin]; v[posMin] = aux; fin desde Algoritmo de la burbuja La idea de este algoritmo consiste en ir comparando elementos adyacentes e intercambiarlos si el orden no es correcto. Vamos a ver un ejemplo que nos mostrar cmo exactamente. Tenemos el vector [3, 1, 5, 4, 2]. Empezamos comparando entre s la primera pareja: 3 y 1. Como 3>1, los intercambiamos, quedando el vector: [1, 3, 5, 4, 2] Ahora comparamos la siguiente pareja: 3 y 5. Como 3<5, no es necesario intercambiarlos, quedando el vector: [1, 3, 5, 4, 2]

Comparamos la siguiente pareja: 5 y 4. Como 5>4, los intercambiamos, quedando el vector: [1, 3, 4, 5, 2] Comparamos la ltima pareja: 5 y 2. Como 5>2, los intercambiamos, quedando el vector: [1, 3, 4, 2, 5] Est ya el vector ordenado? No, como puede comprobarse. Qu hemos hecho con este proceso, entonces? Pues hemos conseguido "empujar" el elemento ms grande del vector a la ltima posicin, de manera que este elemento ya sabemos que est ordenado, y ahora hemos de repetir el proceso, pero no ya con todo el vector, sino slo con el subvector [1..4]. Vamos a ir viendo cmo se mueven los elementos en esta segunda vuelta: Inicialmente: [1, 3, 4, 2, 5] [1, 3, 4, 2, 5] (no se mueven porque 1<3) [1, 3, 4, 2, 5] (no se mueven porque 3<4) [1, 3, 2, 4, 5] (los intercambiamos porque 4>2) (no comparamos 4 con 5 porque ya sabemos que 5 est bien colocado) Ya hemos conseguido "empujar" el segundo elemento ms grande del vector a la penltima posicin. Ahora repetimos el mismo proceso, pero para el subvector [1..3]: Inicialmente: [1, 3, 2, 4, 5] [1, 3, 2, 4, 5] (no se mueven porque 1<3) [1, 2, 3, 4, 5] (los intercambiamos porque 3>2) (no comparamos 3 con 4 porque ya sabemos que 4 est bien colocado) Ya hemos "empujado" el tercer elemento ms grande del vector a su posicin correcta. Repetimos el proceso, pero para el subvector[1..2]: Inicialmente: [1, 2, 3, 4, 5] [1, 2, 3, 4, 5] (no se mueven porque 1<3) (no comparamos 2 con 3 porque ya sabemos que 3 est bien colocado) Y ya hemos terminado, puesto que el subvector que queda es de un nico elemento que, por fuerza, tiene que estar bien colocado, ya que hemos "empujado" a los mayores que el a la posicin correcta. El algoritmo, suponiendo que estamos tratando con un vector numrico (de enteros, por ejemplo), sera: VARIABLES v: Vector[1..N] de Entero; i, j, aux: Entero; FIN VARIABLES

desde i = 1 hasta N hacer desde j = 1 hasta N - i hacer si v[j] > v[j+1] entonces aux = v[j]; v[j] = v[j+1]; v[j+1] = aux; fin desde fin desde Introduccin a la programacin 9.II. Algoritmos de bsqueda Los algoritmos de bsqueda son aquellos que se centran en buscar un cierto elemento dentro de un vector y, quiz, devolver la posicin en la que se encuentra dicho elemento. Vamos a estudiar dos algoritmos: el algoritmo bsico de bsqueda (bsqueda secuencial), y el algoritmo de bsqueda dicotmica. Este ltimo es ms rpido que el primero, pero como contrapartida tiene que slo funcionar cuando el vector en el que se busca est ordenado. Si el vector no est ordenado, no tiene ningn sentido hacer una bsqueda dicotmica. Algoritmo de bsqueda secuencial Es muy sencillo: se trata de recorrer el vector, elemento por elemento, preguntando si el elemento que visitamos es igual al que estamos buscando, y terminando de buscar cuando lo encontremos. El algoritmo quedara como sigue (nuevamente, suponemos que tratamos con un vector de enteros): VARIABLES encontrado: Logico; v: Vector[1..N] de Entero; i, elemBuscado: Entero: FIN VARIABLES

Leer_del_teclado(elemBuscado);

encontrado = Falso; i = 1;

mientras NO(encontrado) Y (i < N) hacer si v[i] = elemBuscado entonces encontrado = Verdadero; fin si

i = i + 1; fin mientras Es evidente que si al terminar de recorrer el vector, tenemos que encontrado=Falso, quiere decir que no se ha encontrado el elemento dentro del vector. Algoritmo de bsqueda dicotmica Como ya hemos dicho, este algoritmo asume que estamos trabajando con un vector ordenado. Esta asuncin no es a la ligera, y no debemos olvidarla, como comprobaremos a continuacin. La idea es empezar a buscar el elemento objetivo por la mitad del vector, es decir, miraremos si el elemento que est en el centro del vector coincide con el elemento buscado. Si coincide, ya hemos terminado. Si no coincide, entonces miramos qu sucede: si el elemento buscado es menor que el elemento que est en el centro del vector, entonces slo buscaremos en el subvector izquierdo; si el elemento buscado es mayor que el que est en el centro del vector, entonces slo buscaremos en el subvector derecho. Se entiende por subvector izquierdo el vector formado por los elementos [1..centro 1] y por subvector derecho el vector formado por los elementos [centro + 1..N]. Dentro del subvector adecuado, repetimos el proceso: comparamos con el elemento central. Si es igual, hemos terminado, si es menor, buscamos en el subvector izquierdo, si es mayor, buscamos en el subvector derecho. La manera de colocarnos en el subvector adecuado es por medio de tres variables auxiliares, que llamaremos izq, der y medio. En la variable izq almacenaremos la posicin del vector que se corresponder con el extremo izquierdo del subvector, en la variable der almacenaremos la posicin del vector que se corresponder con

el extremos derecho del subvector, y en la variable medio almacenaremos la posicin central del subvector. Por ejemplo, si tenemos el vector [1, 2, 3, 4, 5], empieza siendo izq = 1, der = 5 y medio = 3. Ahora bien, el subvector izquierdo correspondera a izq = 1, der = 2 (= medio - 1), mientras que el subvector derecho correspondera a izq = 4 (= medio + 1), der = 5. Es decir, si nos toca movernos al subvector izquierdo, ajustaremos el valor de der como der = medio - 1 dejando izq como est, mientras que si nos toca movernos al subvector derecho, ajustaremos el valor de izq como izq = medio + 1, dejando der como est. En ambos casos hay que recalcular medio = (izq + der)/2, ya que al movernos a cualquiera de los dos subvectores, la posicin central cambia. Vamos a estudiarlo con detenimiento en el siguiente ejemplo. Buscamos si el valor 12 est en el siguiente vector: v = [1, 2, 3, 4, 12, 13, 14] El vector tiene N = 7 elementos, izq = 1, der = 7, medio = (izq + der) / 2 = (1+7)/2 = 4. As que empezamos viendo si v[medio] = 12. Pero v[4] = 4, que no es 12. Ahora bien, 12 < 4? No, entonces no buscamos en el subvector izquierdo (que sera [1, 2, 3]). Si 12 <> 4 y no es 12 < 4, tiene que ser 12 > 4, as que buscamos en el subvector derecho: [12, 13, 14]. Esto requiere que ajustemos los valores de izq, der y medio. Como nos hemos movido al subvector derecho, izq = medio + 1 = 5, der = 7, y ahora medio = (izq + der)/2 = (5+7)/2 = 6 (observamos que la posicin 6 del vector se corresponde con el centro del subvector [12, 13, 14]). As que vemos si v[6] = 12. Pero v[6] = 13, que no es 12. 12 < 13? S, pues entonces buscamos en el subvector izquierdo, que es [12]. Tenemos que ajustar de nuevo los valores de izq, der y medio. Como nos hemos movido al subvector izquierdo, izq se queda como est (izq = 5), der = medio - 1 = 6-1 = 5, medio = (izq + der)/2 = (5+5)/2 = 5. As que vemos si v[5] = 12. Efectivamente, v[5] = 12, que es el valor buscado. Grficamente (para intentar aclarar un poco ms):

Ahora bien, cmo sabemos si un elemento no est dentro del vector utilizando este algoritmo? Lo sabremos en el momento en que izq > der. Cuando se crucen los valores de izq y der es porque no se ha encontrado el elemento. Vamos a ver cmo sera el algoritmo: VARIABLES v: Vector[1..N] de Entero; encontrado: Logico; izq, der, medio, elemBuscado: Entero; FIN VARIABLES

Leer_del_teclado(elemBuscado);

encontrado = Falso; izq = 1; der = n;

mientras (izq < der) Y NO(encontrado) hacer

medio = (izq + der) / 2;

si v[medio] = elemBuscado entonces encontrado = Verdadero; sino si v[medio] < elemBuscado entonces izq = medio + 1; sino (* v[medio] > elemBuscado *) der = medio - 1; fin si fin si fin mientras Introduccin a la programacin 10. Introduccin a la POO (programacin orientada a objetos) La programacin orientada a objetos (POO u OOP en ingls) es una filosofa de programacin que se basa en considerar que los programas estn compuestos de unas unidades llamadas objetos, y las acciones que se ejecutan por tanto estn relacionadas con ellos. Un objeto es un tipo de datos especial que rene una estructura de datos (lo que hemos llamado "tipo definido por el usuario"), as como a los procedimientos que trabajan con estos datos. A partir de un objeto se pueden derivar otros objetos ms especializados (lo que se conoce como herencia), situacin que permite modelar ciertas jerarquas que se dan en la vida real. Pongamos, por ejemplo, que queremos realizar un programa que trate sobre seres vivos. Crearemos un objeto "ser vivo" que tendr una serie de datos como "tiempo medio de vida" y unos mtodos (se llama mtodo a la funcin o procedimiento que trabaja con los datos de un objeto) que permitirn manipular estos datos. Ahora resulta que dentro de los seres vivos tenemos a las plantas y a los animales. Estas dos entidades son una especializacin del objeto primitivo "ser vivo". Cada uno de ellos es un ser vivo, pero tienen detalles que les hacen diferentes entre s y por eso tienen que ser tratados de forma distinta. Dentro de los animales, a su vez, tenemos vertebrados e invertebrados. De nuevo, una especializacin, que tiene todas las caractersticas de los antecesores y algunas propias. Dentro de los

vertebrados, tenemos peces, anfibios, reptiles, aves y mamferos: una nueva especializacin. Vamos a poner ahora un ejemplo ms cercano al mundo de la programacin. Supongamos que queremos hacer un programa de dibujo. Probablemente querremos poner elementos como ventanas, botones, mens, barras de desplazamiento... y otros. Pensando un poco, todo esto se puede llevar a cabo con lo que uno sabe de programacin procedural, sin embargo, no sera ms fcil (por ejemplo) tener un objeto VENTANA? Este objeto podra tener las siguientes variables: coordenadas del rectngulo en el que se va a dibujar, estilo de dibujo... y podra tener unas funciones que, leyendo estos datos, dibujaran la ventana, cambiaran su tamao, la cerraran... La ventaja que tendra esto es que ya podemos crear cuantas ventanas queramos en nuestro programa, puesto que las funciones asociadas tendran en cuenta las variables de este objeto y no deberamos pasrselas como argumentos. Igual que con la ventana, se podra crear el objeto BOTON, a partir del objeto ventana (pues a fin de cuentas se trata de un rectngulo que debemos de pintar), que podra tener como variables las coordenadas (heredadas de la ventana), si est pulsado o no, si est el ratn sobre l o no... y unas funciones que lo dibujaran, lo dibujaran pulsado, detectaran si se ha pulsado el botn, hicieran algo si ese botn se ha pulsado... Las funciones de un objeto nos proporcionan un interfaz para manejarlo: no necesitamos saber cmo est hecho un objeto para poder utilizarlo. Cuando creamos un objeto, en realidad estamos creando un 'molde', que recibe el nombre de clase, en el que especificamos todo lo que se puede hacer con los objetos (ahora s) que utilicen ese molde. Es decir, en realidad lo que uno hace es crear una clase. Cuando va a utilizarla, crea instancias de la clase, y a estas instancias es a lo que se le llama objeto. No vamos a dar una notacin rigurosa para la definicin de clases puesto que esto es slo una introduccin, y sobre POO se puede hablar bastante. Lo que vamos a dar es una pequea orientacin sobre cmo emplear la notacin de acceso a las partes de un objeto, pues el lector puede as a partir de aqu empezar a programar en un entorno como sera Delphi, sin saber mucho sobre POO, pero sabiendo lo suficiente como para emplear los objetos que Delphi pone a su disposicin. Por ejemplo, en el caso de la ventana, podramos definir una clase de la manera siguiente: CLASE Ventana VARIABLES x0, y0, x1, y1: ENTEROS FUNCIONES Inicializar_Coordenadas() Dibujar_Ventana()

Mover_Ventana() FIN CLASE Ventana Y cuando queramos tener una (o varias) ventanas, las declararamos (instanciaramos) como cualquier otro tipo de variable: Ventana Ventana1, Ventana2; A la hora de acceder a las variables que tiene cada una de estas ventanas (cuyos valores son distintos para cada ventana) o de utilizar las funciones de cada una de estas ventanas, habra que poner: Ventana1.x0 = 3; Ventana2.Dibujar_Ventana(); es decir: Objeto.Variable Objeto.Funcion(argumentos) En la definicin de una clase se distinguen las partes privadas de las partes pblicas. Un elemento privado de una clase es aquel que nicamente puede modificarse/emplearse desde la propia clase. Si, en el ejemplo de la clase Ventana, declaramos las variables x0, y0, x1, y1 como privadas, slo desde el cdigo de las funciones de la clase Ventana se podra tener acceso/modificar estos valores, mientras que desde cualquier otro punto (funcin principal del programa, otras funciones del programa) obtendramos un error al intentar acceder a estas variables. La motivacin de esto es la siguiente: cuando diseamos un objeto, existen partes del mismo que no deben ser modificadas ms que por el propio objeto, pues cualquier acceso desde otra parte del programa podra causar comportamientos extraos. As, declarando ciertas partes del objeto como privadas, se previenen los accesos indebidos que podran provocar problemas. Todo lo contrario sucede con las partes pblicas de un objeto: son variables o funciones que pueden ser accedidas desde cualquier punto del programa. Esto ser as porque su uso/modificacin en cualquier parte del programa no desencadenar comportamientos extraos en el objeto. Existen, adems, dos funciones especiales llamadas constructor y destructor. La misin del constructor es inicializar aquellas variables que sea necesario tener inicializadas (muy probablemente pasando dichos valores al constructor) as como poner a punto algunos comportamientos necesarios, quiz llamando a alguna de las funciones de la clase, o bien reservar memoria en el caso de que trate con variables dinmicas. La misin del destructor ser, principalmente, la de liberar todos los recursos que hayan podido reservarse por el objeto. Introduccin a la programacin A1. Acciones bsicas

A lo largo de la primera parte del curso, hemos estado hablando de algoritmos, funciones, procedimientos, estructuras repetitivas, y otras cosas no menos importantes para escribir un programa. Sin embargo, una accin muy comn cuando uno se enfrenta con una mquina es coger el teclado y ponerse a escribir. Paralelamente, uno se espera que lo que escribe vaya apareciendo por la pantalla. Cuando alguien realiza un programa, lo ms normal es que vaya a interactuar con el usuario de alguna manera, bien pidiendo datos, bien mostrando paso a paso los resultados de un cierto proceso, o bien leyendo la posicin del puntero del ratn para ir dibujando puntos... Lgicamente, querremos que los resultados de una entrada del usuario vayan a parar a algunas variables que nosotros habremos dispuesto para luego operar con ellas. Luego, podremos querer mostrar por pantalla el resultado de una accin, que tendremos almacenado en alguna variable, para que el usuario pueda comprobar valores, usarlos posteriormente, etc... Y en todo lo que hemos visto anteriormente, slo muy de pasada, hemos visto cmo podamos llevar a cabo estas operaciones bsicas de entrada/salida. El nombre, formato, etc., depende del lenguaje escogido; sin embargo, todas tienen algo en comn, y eso es lo que vamos a describir ahora. Tenemos tres acciones bsicas: asignacin, lectura (o entrada) y escritura (o salida). De la asignacin ya hablamos en el tema de las variables. Acciones de LECTURA Las acciones de entrada nos permiten obtener determinados valores a partir de un perifrico (teclado, ratn, un fichero...) y ASIGNARLOS a unas determinadas variables. Cuando escribimos un algoritmo, la accin de lectura se escribe: leer de (periferico) (lista de variables de entrada) Por ejemplo: leer de teclado (x,y,z) Si ahora el usuario introduce los nmeros 20, 10, 12, automticamente se habrn realizado las acciones de asignacin: x <- 20 y <- 10 z <- 12 Acciones de ESCRITURA Las acciones de salida permiten transferir a un perifrico (pantalla, un fichero, impresora, ...) resultados obtenidos por la mquina. En un algoritmo, esta accin la pondremos de la siguiente forma:

mostrar por (perifrico) (lista de variables de salida) Por ejemplo, tras hacer: A <- 100 B <- 101 C <- 99 si en nuestro algoritmo pone: mostrar por impresora (A,B,C) nuestra impresora se pondr en marcha y nos sacar los valores 100, 101, 99 Una pequea PostData PD: Existe una estructura de salto incondicional, se llama GOTO, y tiene la forma GOTO etiqueta donde etiqueta es un nombre que nosotros elijamos como referencia. Usualmente van seguidas de : para saber que se trata de una etiqueta y no una variable (por ejemplo) NO declarada. El funcionamiento es bien sencillo: en cuanto llegamos al GOTO, el flujo del programa automticamente da un salto a la zona especificada a partir de la etiqueta. Su uso no es nada recomendado por varios motivos: dificulta la lectura del programa y pueden descontrolarse muy fcilmente si no se les sigue bien la pista. Lo que se puede hacer un GOTO se puede hacer con las otras estructuras que hemos visto. Por ejemplo: i <- 0 suma <- 0 saltar: suma <- suma + i si (i<10) entonces hacer i <- i+1 GOTO saltar fin si puede hacerse tambin as: suma <- 0 desde <-0 mientras i<10 hacer

suma <- suma+i fin desde Mucho ms compacto y menos engorroso. Sin embargo, podemos estar en un ciclo demasiado anidado y quiz en algn momento el programa tenga un parn crtico y haya que salir de ese ciclo como sea: quiz ese momento sea el nico en que el GOTO nos pueda salvar, pero salvo en algo muy crtico, lo mejor es evitarlo. Me refiero en lenguajes de alto nivel, claro O:-D .... Introduccin a la programacin A2. Introduccin a la lgica Estamos realizando un clculo complejo siguiendo (por ejemplo) algn mtodo iterativo en el cual, como condicin de parada, necesitamos que sucedan varias cosas:

No exceder de una cierta tolerancia o cota del error No exceder de un nmero mximo de iteraciones Tener un nmero mnimo de cifras exactas en el resultado

y estas condiciones deben comprobarse A LA VEZ. Cmo lo hacemos? Bueno, espero que quede claro tras la siguiente (necesaria y breve) introduccin a la lgica. En primer lugar, tenemos las proposiciones. Una proposicin es una afirmacin de la que se puede decir sin ambigedad y de forma excluyente que es cierta o falsa. El valor lgico de la verdad es 1, y el valor lgico de la mentira es 0. Por ejemplo: ''Mara es una chica'' es una proposicin, puesto que afirmamos algo sin ambigedad alguna y, adems, o es verdad, o no lo es. O es chica, o no lo es. Sin embargo: ''si no tienes dinero, eres pobre o gastas mucho'' no es una proposicin. No es una afirmacin de la que se pueda decir sin ambigedad y de forma excluyente que sea verdad o mentira. No tener dinero puede ser consecuencia de un robo, o de muchas otras cosas. Sin embargo, esto lo podemos dividir en proposiciones ms sencillas: ''no tienes dinero'' (evidentemente, o es verdad o no lo es), ''eres pobre'' (cierto o no) y ''gastas mucho'' (verdad o mentira). Estas proposiciones estn unidas mediante lo que se llaman CONECTORES LOGICOS. Estos son los siguientes: o || y no o exclusivo && ! XOR

condicional

-> "si... entonces..."

doble condicional <-> "... si y slo si..." He usado la notacin de C para los tres primeros, por no tener disponibles los smbolos lgicos O:) Si tenemos dos proposiciones p, q unidas por alguno de estos conectores, el valor de verdad de la proposicin compuesta, segn el valor de verdad de p y de q, viene dado en la siguiente tabla (llamada Tabla de Verdad): p q !p p && q p || q p -> q p <-> q p XOR q 1 1 0 1 0 0 0 1 1 1 0 0 1 1 1 1 0 1 1 0 0 0 1 1

0 0 1 0 0 1 1 0 Claramente, p && q ser cierta cuando sean ciertas p y q. No podemos decir "verdad" y "mentira" a la vez y pretender que esto sea cierto. Sin embargo, p || q es cierta cuando es cierta una de las dos proposiciones. Si tengo "verdad" o "mentira", est claro que una o la otra (si no las dos) es cierto. Para aclarar el XOR, pondr un ejemplo: O ests vivo o ests muerto, pero ni puedes estar las dos cosas a la vez ni puedes estar ninguna, por eso slo es cierto cuando nicamente una de las dos proposiciones es cierta. Una forma proposicional que es SIEMPRE VERDAD se llama TAUTOLOGIA. Si es SIEMPRE FALSA se llama CONTRADICCION. Siempre tendremos que p || (!p) es tautologa, mientras que p && (!p) es contradiccin. Cuando -> es tautologa, se llama IMPLICACION. Cuando <-> es tautologa, se llama DOBLE IMPLICACION y la simbolizar con <|=|> Voy a poneros las propiedades de &&, || (podeis convenceros haciendo las tablas de verdad), que muchas veces os sern tiles: Leyes asociativas p || (q || r) <|=|> (p || q) || r p && (q && r) <|=|> (p && q) && r Leyes conmutativas p || q <|=|> q || p p && q <|=|> q && p Leyes distributivas p && (q || r) <|=|> (p && q) || (p && r) p || (q && r) <|=|> (p || q) && (p || r) p && 1 <|=|> p (1 es tautologa) p || 0 <|=|> p (0 es contradiccin) p && p <|=|> p p || p <|=|> p p || (!p) <|=|> 1 p && (!p) <|=|> 0

p <|=|> !(!p) Como consecuencia, se tiene (podeis comprobarlo): !1 <|=|> 0 !0 <|=|> 1 !(p && q) <|=|> !p || !q !(p || q) <|=|> !p && !q Estas dos ltimas se conocen como "Leyes de De Morgan", y son muy importantes. Adems, pueden generalizarse a n proposiciones. Espero que con esto tengais un pequeo instrumento que os ayude a pensar en trminos lgicos a la hora de evaluar una condicin. Al fin y al cabo, vosotros quereis que la mquina haga algo si el resultado lgico es 0 o 1, as que esto es precisamente lo que necesitais. Introduccin a la programacin A3. Consejos varios a la hora de desarrollar un algoritmo, un programa o, si me apuras, hasta una receta de cocina En este "breve" texto voy a exponer el procedimiento "ideal" de desarrollo de un programa. No son ms que unas pocas consideraciones que, en proyectos cortos, quiz no hagan mucha falta, pero que a la hora de afrontar algo "grande" ya s hay que prestarle ms atencin a qu se quiere hacer y cmo se quiere hacer. Muy esquemticamente, lo que tendramos que hacer es lo siguiente: Analizar el problema: Para ello, tendremos que definir el problema con precisin, especificar los datos de partida (los datos que tendremos que entrar) y especificar la informacin que ha de darse al resolverse el problema (datos de salida, un mensaje comunicando algo...) Por ejemplo, si queremos escribir un algoritmo para calcular el rea de un rectngulo, tendremos que pensar en las siguientes cosas: "Me tienen que dar dos datos, uno de ellos ser la base del rectngulo, y el otro la altura. Estos datos sern reales. Por otro lado, la salida es el rea, que tambin ha de ser un real." Disear el algoritmo No es ms que pensar cmo resolver el problema, y escribirlo de acuerdo a unas reglas. Sin embargo, no todos los problemas son tan sencillos como querer calcular el rea de un rectngulo. Muchos de ellos son mucho ms complejos (como, por ejemplo, buscar si existe un tal "Pepe BuenaVida" dentro de las fichas de un videoclub).

Por ello, hay una estrategia conocida con el nombre de "divide y vencers". Se basa en dividir un problema gordo y complejo en otros ms sencillos. Tiene algunas ventajas:

El algoritmo es ms fcil de entender, al tenerlo dividido en trocitos. Es ms fcil modificar cada trocito que si lo hubiramos hecho a la brava (adems, el hacer las cosas a la brava tiene la pega de que buscar el lugar donde hay que hacer modificaciones es ms complicado).

Ademas, otra recomendacin es describir primero los algoritmos en un nmero reducido de pasos y, en una segunda vuelta, describir con ms detalle estos pasos. Por ejemplo, si pensamos en "hacer pollo frito", lo primero que pensamos es: 1. Coger los ingredientes 2. Coger los utensilios 3. Hacer el pollo frito Pero luego, a su vez, estos tres pasos se pueden detallar mucho ms. Me dais sugerencias? (y as, de paso, me preparo un pollo frito a vuestra salud ;) ) Usar el ordenador para programar ese algoritmo y ver cmo funciona Obviamente, a nosotros puede parecernos que nuestro algoritmo est impecable, pero siempre es bueno probarlo, traducindolo al lenguaje que ms nos guste (o, simplemente, al que vayamos a usar), porque, si no obtenemos la salida deseada, podemos pararnos a revisar nuestro algoritmo en busca de fallos. A la fase de conversin de un algoritmo en las instrucciones de un lenguaje de programacin la llamamos codificacin, y al algoritmo, una vez que lo tenemos escrito en un lenguaje de programacin especfico, lo llamamos cdigo. Estos pequeos consejos, aunque obvios, son ignorados muchas veces, y hacen padecer, desde el principio, a un programa de una mala estructura. Pararse a pensar un poco en lo que se quiere hacer y recapacitar en la mejor manera posible puede ahorrarnos que, ms adelante, cuando queramos hacer alguna modificacin al programa, tengamos que reescribirlo por completo.

Vous aimerez peut-être aussi