Вы находитесь на странице: 1из 143

El

Arte

de

Programar

El arte de programar
Aprendiendo a resolver problemas con computadoras usando C bajo

Builder
Ingeniero Armando Alberto Recabarren Ingeniera Flavia Irene Arnoldo Ingeniero Pablo Moliterno
1

El

Arte

de

Programar

El

Arte

de

Programar

INDICE

INTRODUCCIN 1 COMENZANDO 2 FUNCIONES Y VARIABLES 3 EL ENTORNO VISUAL 4 BUCLES Y COMPARACIONES 5 EL ARTE DE RESOLVER PROBLEMAS 6 DIAGRAMAS ESTRUCTURADOS 7 ARREGLOS 8 MAS SOBRE FUNCIONES 9 BASES DE DATOS 10 RECURSIVIDAD

5 15 25 69 91 111 123 133 143 170 200

El

Arte

de

Programar

El

Arte

de

Programar

INTRODUCCIN
De qu trata este libro?. De acuerdo al titulo, se ocupa de explicar, describir, el arte de escribir programas,programas? qu programas? Programas que le permiten a una computadora digital realizar una determinada tarea Ms de un circunstancial lector del titulo de este libro habr pensado que se trata de un anacronismo. Arte de programarera el de los pioneros, los que programaban antes de que los conceptos de la programacin estructurada1 tomarn difusin. En realidad las tcnicas modernas que nos acompaan en la construccin de nuestros programas no suplantan las habilidades que debemos poner en juego para disear un algoritmo, paso sin el cual no puedo escribir un programa. Estas habilidades no se pueden ensear sino que se deben aprender haciendo. Quiero detenerme un minuto estimado lector en aclarar este aparente sin sentido ya que el mecanismo de enseanza aprendizaje esta compuesto de dos partes, y entonces siempre alguien ensea y otro aprende, pero puede ser que ambas funciones se renan en una sola persona y este, normalmente, es el caso cuando lo que se debe aprender son tareas del intelecto No se puede ensear a pensar, se puede guiar, se pueden sugerir estrategias, se puede acompaar, pero ensear mostrando con ejemplos como se hace, definitivamente no se puede. Ud. ensea a realizar una tarea manual y se asegura que quien la aprende la puede repetir sin errores, pero el trabajo creativo es siempre como toda obra del intelecto humano genial y por lo tanto no acotado, no limitado, no estandarizado.
1

A lo largo del libro desarrollaremos este concepto.

El

Arte

de

Programar

Programar una computadora es un trabajo creativo, que puede ser aprendido por todo el mundo pero que no todo el mundo esta dispuesto a aprender. Para poder escribir un programa lo ltimo que necesito es un lenguaje de programacin, si bien no puedo llegar a un buen final sin l, es lo ltimo que necesito. En este libro lo vamos a guiar para que aprenda a resolver problemas con la computadora, para ello a no dudarlo, deber escribir un programa, sin embargo el lenguaje que vamos a utilizar podra eventualmente ser reemplazado por otro dentro del mismo paradigma, digamos, si esta palabra no le gusta, dentro de las mismas reglas de juego, pero la formulacin del problema, su precisa definicin y el despliegue de la estrategia que lleve a su solucin es el arte que Ud. va a dominar.

Para quin es este libro.


persona que quiera desarrollar Para toda sus habilidades para resolver problemas. Siguiendo las enseanzas de Kenneth L. Bowles vamos a proponer problemas cuyas soluciones no requieren ningn conocimiento de clculo ms all del que puede resultar para evaluar un producto o un cociente. Estos problemas entonces, pueden ser resueltos por todas las personas que hallan completado el ciclo primario de enseanza.
Conseguir que en la pantalla de la computadora aparezca una palabra en diagonal no requiere de ningn conocimiento matemtico pero si requiere averiguar que debo hacer para conseguirlo. Resolver un acertijo no requiere en general conocimiento sino ingenio. Y en este punto es necesario

El

Arte

de

Programar

que sepa que si no le gusta resolver acertijos es muy probable que tenga en sus manos el libro incorrecto. Y djeme decirle porque digo probable. Es posible que a Ud. le gustara ser capaz de resolver acertijos, pero como no le va bien la mayor parte de las veces, el fracaso lo angustia, le molesta, evita esas situaciones, no le gusta. Resolver un acertijo es resolver un problema y solo se aprende a resolverlos, hacindolo, de manera que su problema no es su problema, su problema es su actitud porque, ms acertijos (problemas) resuelva, ms experiencia adquiere, ms experto, ms problemas resuelve y lo hace ms rpido. De manera que si Ud. est dispuesto a tratar y repetir cada vez que fracase, yo le aseguro que los problemas no sern un problema para Ud.

Que obtendr de este libro.


Una gua ordenada de procedimientos que le permitirn abordar la solucin de una serie de problemas mediante la computadora. El proceso a seguir va a permitirle descubrir como piensa y adecuar sus razonamientos para que sus juicios sean correctos en referencia a los problemas tratados, pero esto le dar un entrenamiento que le ser til en general. Piaget propuso una teora que sirvi de respaldo al desarrollo del Lenguaje Logo por parte de Seymour Papert en el Laboratorio de Inteligencia Artificial del Instituto Tecnolgico de Massachussets, no es mi intencin confrontar la

El

Arte

de

Programar

teora, sin embargo tras haber aplicado estas tcnicas durante muchos aos, puedo resumir los resultados de la siguiente manera. La computadora no tiene ningn tipo de inteligencia, pero puede ejecutar una serie de instrucciones que permiten automatizar la obtencin de conclusiones a partir de premisas dadas, sin ningn tipo de creatividad. Repite una y otra vez el mismo resultado en repuesta a los mismos datos. En ese aspecto es idntico su funcionamiento a un viejo juego de mediados del siglo pasado llamado El Cerebro Mgico . Se trataba de un tablero con una serie de contactos ubicados en las intersecciones de una cuadrcula. Para explicrselo en forma sencilla piense que en una pared hay colgados una serie de cuadros uno al lado del otro y a su vez las filas de cuadros as formadas, estn una arriba de otra de manera que la pared esta llena de cuadros. En estos cuadros hay preguntas y respuestas, mitad y mitad. Para cada pregunta est la repuesta correcta, slo una. En cada cuadro hay una llave de encendido de luz. El juego consiste en elegir una pregunta accionando la llave que est en su cuadro y luego tratar de encontrar la repuesta correcta, si la eleccin es correcta al accionar la llave que est en el cuadro repuesta se prende una luz. Descripto de esta manera, el juego debera llamarse la Habitacin Mgica. Qu tiene de mgica?. Prende la luz cuando le acierto a la repuesta correcta!. Ud. estimado lector est apostando que si cambia de lugar los cuadros, se acaba la magia. Con slo cambiar cualquiera de los dos cuadros por otro cualquiera, accionando de nuevo las mismas

El

Arte

de

Programar

llaves la luz se prendera, pero en este caso habra un error. Claro, la clave est en colgar los cuadros adecuados. Porque la luz siempre para ese par de llaves se prender. De manera que la magia en realidad la puso el que colg los cuadros. La computadora permite flexibilizar el tipo de cuadros a colgar y en realidad admite que haya cuadros o estructuras de cuadro ms elaboradas, pero al igual que El cerebro mgico , alguien que sabe como es el problema, y como se soluciona se lo dice a la mquina. Y entonces para qu me sirve la computadora?, se estar preguntando Ud. Nos sirve para tareas que por lo tediosas y repetitivas cansan o son falibles por exigir una atencin que no siempre el humano puede mantener, o para resolver problemas que el hombre podra solucionar si viviera la cantidad de tiempo suficiente y los resultados obtenidos de esta forma fuesen tiles. Y es en est obviedad en la que radica la utilidad de la computadora como herramienta epistemolgica. Si un problema no est bien resuelto, no es la mquina la que se equivoc, es Ud. Djeme ilustrar el punto de esta manera. La dificultad ms grande en la comunicacin humana radica en que lo que digo no es generalmente lo que pienso, y lo que escucho no es lo que normalmente me queran decir. De manera que ante una determinada situacin normalmente nos retiramos de una discusin con la satisfaccin de que ms all de lo que el otro piense la razn nos asiste, y si como normalmente ocurre, al menos en mi caso, estoy equivocado, permanezco en error.

El

Arte

de

Programar

Es razn ms que humana que en caso de duda prefiero mi verdad a la del otro. Pero con la computadora la cosa es diferente si el problema no se resuelve el equivocado es Ud. Bueno, djeme decirle que esto slo ser as si Ud. persevera porque al principio y por algn tiempo hasta que aprenda. La equivocada ser la mquina Quin lo duda?. As que tenemos buenas y malas noticias, la mala noticia es que Ud. aunque no lo crea, no sabe pensar. La buena noticia es que si trabaja duro se va a divertir descubriendo cuantas veces Ud. no tiene la razn. Y se va a divertir porque el nico que lo sabr ser Ud. y por eso se va a corregir. Por favor entindame bien no estoy cuestionando su inteligencia, solamente estoy diciendo que es tan inteligente que procede o decide sin ponerse a pensar y por eso Se equivoca! Cuando el resultado que la mquina de, no sea el esperado, sea incorrecto, hay alguien que est equivocado y ese es Ud. De manera que deber corregir sus creencias, ajustar sus datos y procedimientos hasta conseguir el resultado correcto y va a descubrir no sin gran sorpresa que Ud. no era tan infalible como lo crea. Y esto djeme decirle, le va a reportar tantos beneficios en el mediano y largo plazo que va a felicitarse una y otra vez por haberse decidido a cultivar el arte de programar.

10

El

Arte

de

Programar

Que necesito.
Una computadora que soporte el Sistema Operativo Windows y cualquiera de las versiones del programa de programacin visual Builder, si bien el libro se ha escrito usando la versin 5.0, cualquiera de las versiones sirve, solamente remtase al apndice A para ajustar su accionar a la versin que posea. Suponemos que Ud. est familiarizado con el ambiente Windows por lo tanto prepare una carpeta en el directorio que habitualmente guarda sus tareas, para almacenar los programas que iremos escribiendo, busque el icono de Builder o llmelo de la manera que Ud. pone en marcha sus programas si tiene xito ver aparecer la ventana de Builder. Si ya lo hizo y tiene la pantalla antes sus ojos. Confiselo, tiene miedo! Para qu ser todo eso?. Cree que han puesto ms cosas de las que necesita. Piensa que jams podr entender todo lo que all ve. Si, tiene razn, son muchas cosas, son tantas que todas juntas sugieren la idea de un elefante. Yo tengo un amigo que aconseja que la mejor forma de comerse un elefante, es comer un pedacito cada vez. De manera que vamos a poner en prctica el consejo y vamos a dar un paso cada vez y solamente nos vamos a enfocar en ese paso. Para ello le sugiero:

Que hacer cuando nada funciona.


Una vez ms, perseverancia es el nombre del juego, pero hay algunos consejos que es conveniente que le d y que Ud. deber aplicar siempre an, o mejor, sobre todo si le parece trivial o tonto.

11

El

Arte

de

Programar

Recuerde: Empiece de nuevo tantas veces como haga falta. Pero asegrese que entiende o al menos cree que entiende las modificaciones que efecto. Porque seguro algo deber modificar. Intentar que algo que no llega al punto o resultado esperado funcione tan solo por repetirlo se llama tozudez. No importa lo seguro que Ud. est de lo hecho, el error es suyo Todo problema complejo puede dividirse en problemas menores. Asegrese que el problema tal como est ya no se puede dividir ms. Resuelva el problema con papel y lpiz y slo entonces proceda a escribirlo para su solucin con la computadora. La mquina no puede interpretar nada. Ud. debe escribir respetando las reglas sintcticas con precisin absoluta. Vuelva siempre a partir del ltimo punto que sabe que funcion bien. Si despus de cambiar algo dej de funcionar. Ah est el problema, no importa que tan seguro est Ud. que esa modificacin es menor y no tiene nada que ver. Ah est el problema, bueno lo admito, ah generalmente est el problema.

12

El

Arte

de

Programar

Los bucles infinitos son eso, infinitos. Detenga la computadora, aunque sea desenchufndola y empiece de nuevo.

Vuelva a leer estos puntos tantas veces como lo considere necesario, yo mismo le recordar eso a lo largo del libro.

13

El

Arte

de

Programar

14

El

Arte

de

Programar

1 COMENZANDO
Listo para comenzar?. Djeme recordarle algo de lo que dijimos en la introduccin y que es fundamental que Ud. lo haga: Nuestro objetivo es desarrollar nuestra habilidad para resolver problemas. Vamos a usar una computadora y su software asociado para resolverlos La clave est en tratar de nuevo cada vez que fracasamos pero ajustando la estrategia.

Analicemos el problema varias veces hasta estar seguro que lo podemos definir Asegrese que el problema no puede dividirse todava en un conjunto de problemas ms simples. Vuelva tantas veces como sea necesario a leer la separata de la Introduccin titulada Que hacer cuando nada funciona

Entendiendo el entorno.
Nuestro primer problema ser entender el ambiente de trabajo. De nuevo, recuerde que la computadora es un artefacto con muchas pretensiones pero con muy pocas capacidades, de manera que los logros que obtengamos sern por nuestro exclusivo esfuerzo. Mire de nuevo la pantalla, complicado no?, si Ud. ha comenzado a leer en esta pgina se ha perdido la explicacin de la Introduccin y como se pone en funcionamiento el programa que vamos a usar. Si Ud. ha seguido las instrucciones sabe, a que me refiero. Desanima no?. Todos esos dibujos, barras, algunos parecen botones para qu sern? Que pasara si los aprieto?.

15

El

Arte

de

Programar

Dse el gusto apritelos. En el peor de los casos tendr que rearrancar la mquina y eso es algo que normalmente le ocurrir an corriendo programas comerciales. Definamos nuestro problema: Aprender que es y para que sirve cada uno de los comandos representados por los distintos botones. Admite subproblemas?. S claro cada uno de los botones. Bien entonces empecemos. Vamos a escribir nuestro primer programa. Para ello y hasta que dominemos algunas tcnicas bsicas del arte de programar vamos a escribir programas que no funcionan en el ambiente Windows. Esto es, se ejecutan en un modo llamado DOS que es simplemente una pantalla monocolor generalmente blanco sobre fondo negro en la que podemos escribir caracteres alfanumricos constituidos por las letras del alfabeto, los nmeros y algunos smbolos. Queremos que la mquina salude escribiendo en la pantalla Hola Mundo. Algn da se enterar porque elegimos este particular saludo. Los pasos que vamos a listar a continuacin formarn parte de cada uno de los programas que vamos a escribir. Escrbalos en una tarjeta y mantngalos a mano, si lo desea para agilizar el manejo posterior de los pasos. Elija en el men Files, New Se abre una ventana que permite elegir New Items, elija Console Wizard (En la ventana que aparece deje un punto en C y asegrese

16

El

Arte

de

Programar

que hay un tilde en Console Application) pulse OK Ponga uno como nombre y guarde en la carpeta que prepar Ponga primero como nombre y guarde en la carpeta que prepar

Djeme traer el texto que ah figura // #pragma hdrstop // #pragma argsused int main(int argc, char* argv[]) { return 0; } // Las palabras en negritas son palabras reservadas y van a formar parte de todos nuestros programas. A riesgo de cansarlo le repito que lo que Ud. est viendo es su primer programa, si pulsa el botn con forma de flecha y color verde, el programa se va ejecutar luego de una preparacin previa que se ejecutar automticamente y que explicaremos luego. Si no lo hizo todava, hgalo ahora, ubique el cursor del ratn sobre el botn verde con forma de flecha y apriete el botn derecho del ratn, o si le resulta ms cmodo pulse F9. Qu pas?. Nada.. Qu tena que pasar?. Nada. Entonces estamos bien. Bueno en realidad si mira con atencin ver aparecer una ventana negra que desaparece rpidamente. Vamos a detener la ventana, para ello escriba gets(); detrs de la llave { Asegrese que el punto y coma siga a los dos parntesis. El programa debe quedar como el siguiente modelo.

17

El

Arte

de

Programar

// #pragma hdrstop // #pragma argsused int main(int argc, char* argv[]) { gets(); return 0; } // Las lneas que empiezan con la doble barra son comentarios y el compilador (qu ser un compilador?) lo ignora para ello debe ocupar a lo sumo un rengln y empezar con dos barras inclinadas. Y las lneas que empiezan con el signo numeral # se las explicaremos luego, pero tambin son prescindible por ahora. Si ahora pulsa F9 o el botn verde, ver que la ventana negra aparece y permanece, si ahora pulsa la tecla ENTER, ver que vuelve al ambiente de trabajo de Builder. La ventana es la que muestra las aplicaciones DOS, la diferencia lograda con la incorporacin de gets() es que la ventana DOS permanece fija, eso es porque esta instruccin es un comando que al ejecutarse espera el pulsado de la tecla ENTER. Si Ud. no entiende Ingls gets significa conseguir, y el comando gets() ordena obtener una serie de caracteres terminados por una nueva lnea, al pulsar Enter estamos terminando el ingreso de caracteres por eso el comando se cierra y el programa continua terminando a su vez. Con el objeto de poder ver los resultados de nuestro trabajo, vamos a incorporar gets() al final de cada uno de los programas que requieran ser vistos en la pantalla de DOS.

18

El

Arte

de

Programar

Sin embargo vamos a pagar un precio por esto: El compilador (pronto se va a enterar que es o quin es ) nos advierte(warning) que estamos haciendo algo no muy bien con el siguiente cartel.
[C++ Warning] Unit1.c(10): W8065 Call to function gets with no prototype

Por el momento vamos a ignorar esto. Antes de escribir el programa nmero uno expliquemos rpidamente que sucede luego de dar la orden de ejecutar , apretando F9 o usando el ratn. Un programa en C o C++ (los lenguajes de base que usa Builder), como cualquier programa de computadora debe ser escrito respetando las reglas sintcticas estrictamente. El concepto general que se tiene acerca de los lenguajes de computacin hace que esto sea muy difcil de entender por los estudiantes. Es que por las mismas razones ya expuestas se acepta que la mquina es inteligente, de manera que al igual que nosotros, debiera entender lo mismo si en vez de poner gets ponemos get. Bien, es cierto que hablamos de lenguajes, pero este no cumple las mismas funciones que los que usamos los humanos, simplemente porque la computadora es una mquina. Lo que Ud. imagine y lo que le gusta escribir al periodismo en general, no le agrega a la mquina la ms elemental de las habilidades que un ser vivo tiene, ni siquiera los actos reflejos, si Ud. supone que estos son los ms primitivos que un ser vivo pueda tener. En realidad el programa que nosotros escribimos es traducido a las combinaciones de ceros y unos que permitirn la conexin o no de los distintos componentes dentro de la computadora que harn la tarea encomendada a travs del programa. Un solo punto mal puesto generar, en el mejor de los casos combinaciones que carecen de sentido. El programa encargado de hacer esta traduccin recibe el nombre de compil ador.

19

El

Arte

de

Programar

De manera que cuando pulsamos F9 ponemos a trabajar al compilador y sus amigos y estos nos entregan un programa que llamamos ejecutable. El compilador vigila que lo que nosotros escribamos se ajuste a la sintaxis correcta, cualquier error que cometamos nos avisar Y deberemos corregirlo. Sin embargo hay ms de una posible causa para un tipo de error, de manera que entre las habilidades que Ud., como programador deber cultivar es aprender a interpretar los mensajes de error del compilador.
El comando que nos permite escribir en pantalla es el siguiente. printf() Pero escribir qu?. Vea la siguiente versin de uno Programa 1.1 // pragma hdrstop // #pragma argsused int main(int argc, char* argv[]) { printf(HOLA MUNDO); gets(); return 0;} Si lo ejecuta ver que escribe en la pantalla la frase HOLA MUNDO. El compilador se ha puesto ms nervioso, exactamente el doble de nervioso, pero seguiremos ignorando sus advertencias. De cualquier manera lea los mensajes y comprelos, no importa si no entiende Ingls siempre algo queda. Es decir printf() escribe en pantalla lo que esta entre parntesis y encerrado entre apstrofes.

20

El

Arte

de

Programar

En realidad los argumentos (as se llama lo que queda entre parntesis ) que admite printf() son muchos ms pero, recuerde, un pedazo cada vez. Vamos a utilizar estos dos comandos, printf() y gets() para practicar el uso de las herramientas que nos ofrece el entorno Builder. Pero antes miremos los detalles del programa que estamos escribiendo y para ello eliminemos realmente lo innecesario, nuestro programa queda as: main() {} Este programa no hace nada pero desde el punto de vista del compilador es correcto, lo acepta sin acusarnos error (sin embargo nos advierte que las cosas no estn tan bien hechas). Es ms, si incorporamos los comandos que hemos estado usando veremos que igualmente funcionan a condicin que estn bien escritos (respetando estrictamente cada uno de los caracteres que deben contener.)

Escriba y ejecute los siguientes programas, para ello deber borrar todo lo que le presenta BUILDER cada vez que empieza.
Programa 1.2 main() {printf(Esta frase va a quedar sola\n); printf(\n);// aqu se va a imprimir una sola lnea printf(x\n);// las siguientes cuatro escriben xilo printf(i\n); printf(l\n); printf(o\n); gets();} El compilador se ha enloquecido mucho ms ahora, pero solo nos dice cada vez que usamos printf(), que falta el prototipo y al final que toda funcin debe devolver un valor. Si ya se, no entiende nada de lo que acabo de escribir, no se haga problema, no lo necesita por ahora.

21

El
Programa 1.3

Arte

de

Programar

main() {printf(Esta frase va a quedar sola); printf( );// aqu se va a imprimir un espacio printf(x);// las siguientes cuatro escriben xilo printf(i); printf(l); printf(o); gets();} Se anima a expresar la conclusin que surge de comparar los resultados de los dos programas.? Sugerencia: Si encuentra algo diferente propngase nuevos programas usando y dejando de usar el elemento diferente en programas ms simples. Preste atencin a los comentarios incorporados en los dos programas compuestos. Antes de explicrselo vamos a agregar algo ms, observe lo siguiente

D I A G O N A L Un programa que permite escribir eso en pantalla es el siguiente:

22

El

Arte

de

Programar

program 1.4;; main() { printf(D\n); printf( I\n); printf( A\n); printf( G\n); printf( O\n); printf( A\n); printf( L\n); gets(); } Estoy seguro que Ud. Ya haba encontrado que \n hace la diferencia que printf() inserte si est o no inserte si no est, la orden de cambiar a la prxima, la lnea de impresin. Adems al poner en cada lnea una nueva letra cuidamos de agregar tantos espacios como hagan falta para lograr el efecto deseado en la impresin. Para terminar COMENZANDO disee un programa que escriba: Esta frase se escribi en la primer lnea. Pero esta otra se escribe tres lneas ms abajo Y E S T O C O M O

23

El

Arte

de

Programar

S E R A ? Aqu el numero dos esta puesto por una sentencia sola 2 Si no lo ha hecho todava hgalo ahora. Suprima ; o la llave final y vea y aprenda a interpretar los mensajes de error del compilador.

24

El

Arte

de

Programar

2 FUNCIONES Y VARIABLES
Si ha resuelto el ltimo ejercicio del captulo anterior se imaginar fcilmente como puede mediante un programa lograr que en la pantalla aparezca lo siguiente: aaaaaa a a a a aaaaaa bbbbbb b b b b bbbbbb Este ejemplo nos va a permitir ilustrar el concepto de funcin y el concepto de variable. Esta claro que la figura presenta claras evidencias de estar formada por una serie de elementos ms simples que a su vez se repiten. As por ejemplo debemos disponer de una sentencia que imprima las 6 a, sentencia que se repite dos veces, otra sentencia que imprima las dos a separadas por espacios que tambin la usamos dos veces y finalmente necesitamos dos sentencias similares para usar con las b. El sentido comn nos sugiere que debiera haber una forma de utilizar estas simetras y semejanzas para ahorrar esfuerzo. Bien la idea ya la hemos analizado se trata de: divide y reinaras. En el lenguaje que estamos usando de

25

El

Arte

de

Programar

base, esto se hace por medio de funciones. Una funcin podemos, sin cometer un error de concepto muy grave, decir que es un programa dentro de otro programa. Y programa tal como hemos visto, es una secuencia de acciones, de comandos que actuando sobre, por ejemplo caracteres, permiten manipularlos y obtener determinados resultados. A partir del problema que estamos tratando de resolver, podramos considerar a nuestro programa constituido por otros subprogramas cada uno de los cuales resuelve un problema menor. El siguiente listado muestra como se resuelve lo propuesto Programa 2.1 seis_a() {printf(aaaaaa\n); //declaracin y definicin de funcin } dos_a() {printf(a } a\n); //declaracin y definicin de funcin

seis_b() {printf(bbbbbb\n); //declaracin y definicin de funcin } dos_b(){printf(b b\n); //declaracin y definicin de funcin } main() // funcin principal { seis_a(); // funcin que se ejecuta dos_a(); dos_a(); seis_a(); printf(\n); seis_b(); dos_b(); dos_b(); seis_b(); gets();}

26

El

Arte

de

Programar

Para cada problema simple planteado, hemos declarado y definido una funcin, como se aprecia, la declaracin de cada una, precede a la ahora llamada funcin principal, en la que como vemos, nos limitamos a listar a cada una de las nuevas funciones en el orden en el que la necesitamos. La precedencia de la declaracin de las funciones a la funcin principal es fundamental porque sino el compilador no podra reconocer los nombres. Dos son los objetivos que se pueden alcanzar usando funciones.

Primero, se puede usar para aislar en el proceso principal los pasos para conseguir una accin determinada, de esta manera uno puede concentrarse en cada subtarea y estudiar cada detalle para luego, en la funcin principal, concentrarse en como encaja cada parte. Por constituir pilar fundamental de nuestra propuesta de aprender a resolver problemas volveremos sobre este tema en forma reiterada a lo largo del libro Segundo, normalmente las funciones permiten escribir menos. Este no es el caso con este ejemplo, porque lo simple de las sentencias hace que sean muy pesados los requisitos sintcticos, pero veremos en futuros usos lo vlido de lo aqu aseverado.

Observe que la declaracin de una funcin incorpora todos los elementos definidos para un programa, Encontramos el nombre (main significa principal en Ingls) seguido por los

27

El

Arte

de

Programar

parntesis y luego el par de llaves {}. Vamos a volver sobre las funciones despus, veamos ahora dos conceptos sustanciales para la construccin de programas.

Parmetros
El ejemplo elegido para ilustrar los temas que estamos tratando se presta maravillosamente para definir lo que es un parmetro, en realidad hay dos tipos de parmetros Uno es llamado parmetro formal y el otro parmetro real. Un parmetro es lo que necesitamos para canalizar esa inquietud que su sentido comn le susurra al odo: por qu repetir las funciones si lo nico que cambia es una letra?. cierto?. Tenemos repetidos las funciones seis_x y dos_x porque a pesar de ser funcionalmente iguales, la letra que imprimen no es la misma. Pero podemos describir las acciones que queremos que se celebren para conseguir un determinado resultado mediante un smbolo genrico (el parmetro formal) y luego en el momento de tener que ejecutar las acciones cambiar este smbolo genrico por el valor que se debe usar (parmetro real) . Si ha ido al diccionario habr encontrado que parmetro en sus diferentes acepciones representa la forma en que se tiene en cuenta la diversidad de algo. Efectivamente as es como lo usamos nosotros. Mediante el parmetro formal definimos las tareas a realizar con algo, para luego en el momento correcto decir mediante el parmetro real el valor de ese algo. Hasta ahora hemos usado la funcin printf() (Ud. ya se haba dado cuenta que era una funcin, verdad?) sin aclarar la variedad y forma de sus argumentos. Vamos a necesitar, para lo que queremos hacer ahora, saber un poco mas de ella. La funcin printf() es una de las funciones

28

El

Arte

de

Programar

que acompaa al lenguaje C y que permite la visualizacin de la informacin en la pantalla. Para ello es necesario pasarle dos parmetros: un formato y los argumentos para cubrir dicho formato. La variedad es tan grande que vamos a explicar cada una de las posibles combinaciones a medida que las necesitemos. La forma general es: printf (formato, argumentos) Hasta ahora la hemos usado para mostrar cadenas de caracteres constantes, es decir con un valor nico. Pero si queremos mostrar otro tipo de informacin es necesario especificar por separado el formato y los valores a ser mostrado por ese formato. Por ejemplo printf(%c%c, a,a) Nos mostrar dos as una al lado de otra, mientras que printf(%c %c, a,a) Mostrar las dos as pero separadas por un espacio Por supuesto nosotros ya sabemos que printf(aa) Y printf(a a) Hacen lo mismo pero para poder parametrizar lo que queremos mostrar debemos usar la forma aprendida en ltimo trmino. Por favor no olvide encerrar los simbolos %c entre comillas. Vamos a mostrar esto mediante el siguiente programa.

29

El

Arte

de

Programar

Programa 2.1.1 seis_x(char L){printf(%c%c%c%c%c%c\n,L,L,L,L,L,L);} dos_x(char L){printf(%c%c%c%c%c%c\n,L, , , , ,L);} main(){ seis_x(a); dos_x(a); dos_x(a); seis_x(a); printf(\n); printf(\n); seis_x(b); dos_x(b); dos_x(b); seis_x(b); gets();} Lo primero que observamos es que las funciones son ahora solo 2, que adems al llamarlas en la funcin principal le pasamos, la letra que queremos que se imprima. Leyendo las dos funciones vemos, que el lugar que antes ocupaban las letras a o b ahora la ocupa en todos los casos la letra L que acta como el identificador del parmetro. Al declarar los procedimientos entre parntesis hemos colocado char L Esta declaracin dice que el parmetro identificado con la letra L es del tipo char. Como se interpreta todo esto?. Bien, esto es as: En el cuerpo de cualquiera de las funciones esta la funcin printf (), a la que le decimos que lo que debe imprimir es L con un determinado formato, en el caso del

30

El

Arte

de

Programar

procedimiento seis debe imprimirla 6 veces y por ello tal como exige la sintaxis del comando, est repetido el parmetro 6 veces separado por comas, y en el caso del procedimiento dos debe imprimirla al principio, imprimir 4 espacios y al final de nuevo L, pero, qu es L, L es una pista , L es un lugar. En el encabezamiento de la funcin al declararla lo que hacemos es reservar en la memoria de la mquina un lugar llamado L que debe ser capaz de guardar un carcter (character en Ingls abreviado char). Eso es lo que se llama el parmetro formal . En el cuerpo de la funcin, con la letra L le decimos, que el contenido de esa ubicacin de memoria, el parmetro actual, o parmetro real lo utilice para cumplir el comando. Cuando en main() (la funcin principal) llamamos a la funcin debemos hacerlo dando (pasando) el valor actual que queremos que esta use cada vez que encuentre L. La declaracin de tipo permite hacer la reserva adecuada de memoria, ya que el almacenamiento de un carcter puede y en general no lo es igual al que necesitamos para almacenar un nmero. Si no esta entendiendo nada de lo que escribo no se apresure en sentirse mal, dese la oportunidad de leer un poco ms y luego volver sobre lo leido de nuevo asociando lo anterior con lo que sigue a continuacin. Simplemente piense Cuntas letras diferentes conoce? Cuantos smbolos ?. Permtame orientarlo, 26 letras si tenemos en cuenta el alfabeto Ingls (Los hispanos parlantes hemos llegado despus al mundo de la informtica, por lo que ciertas cosas fueron hechas no tenindonos en cuenta),

31

El

Arte

de

Programar

estas a su vez admiten una variante, 10 smbolos para los nmeros del 0 al 9, alrededor de una veintena de smbolos como + - *, etc., tenemos junto, menos de 128. Por otra parte Cuntos nmeros diferentes tenemos? Infinitos ! Pero ac tenemos un problema Ud. estar pensando. Ya lo creo, No tiene idea del tamao del problema!, pero ya lo ve, ac estamos funcionando y si se queda entre nosotros el tiempo suficiente se va a enterar de cmo lo manejamos.

Lo importante de todo esto es que Ud. entienda que cada dato que se almacene en la computadora deber tener su propio espacio y la declaracin de tipo permite hacerlo adecuadamente.
Aplique lo aprendido para construir un programa que deje en la pantalla lo siguiente. XaaaX a a a a XaaaX XbbbX b b b b XbbbX

No es nuestra intencin que Ud. Se transforme en un Gur de la computacin. Recuerde que nuestro objetivo es aprender a resolver problemas. Sin embargo es importante para nuestro objetivo que a tan temprana edad aprenda algo acerca de los punteros.

32

El

Arte

de

Programar

Variables, Tipos, Memoria y Punteros Este es un buen punto para referirnos a algunos detalles de la mquina como tal. En el prrafo anterior hablamos de parmetros y decamos que es un lugar de memoria, con ms precisin, un nombre para referirnos a un lugar de memoria donde guardamos el dato. Pero, Cmo es ese lugar de memoria?Cmo se guarda el dato?. Mi vida es un glosario de ancdotas y de dichos. y un amigo mo tiene uno. No el del elefante, otro. Que es en realidad un consejo Trata de no saber mucho porque si sabes mucho te van a utilizar mucho. Otro dicho que podra venir a cuento es Menos averigua Dios y perdona. Lo cierto es que vamos a entrar en un terreno en el que conviene que Ud. sepa que los datos, todos los datos se guardan en la computadora en forma de ceros y unos. Por supuesto mediante cdigos, y as, este conjunto de ceros y unos representa el nmero dos y aquel el numero 33, este representa la letra A y aquel la W. Ahora cuantos ceros y unos necesito ? Eso va a depender del Tipo de dato, es por esto que necesito declarar el tipo de datos antes de escribir el programa. Para que el traductor(compilador),-entre lo que yo escribo bajo Builder, y lo que la mquina va a entender- pueda saber como debe tratar cada dato. Podemos resumir todo esto diciendo que 8 ceros y unos es una cantidad que representa la unidad de almacenamiento bsica para la transferencia de datos entre la mquina y el humano, tal es as que tiene nombre propio y todo. Se llama BYTE. Ahora ya sabe porque le vendieron una mquina con tantos bytes por 33

El

Arte

de

Programar

aqu y tantos byte por all. Por medio de un byte puedo representar un carcter alfanmerico ( las letras, los nmeros del 0 al 9 y algunos smbolos especiales). Por medio de 2 bytes puedo representar desde el -32 768 al +32767, etc., etc. No es malo que se imagine a la memoria de la mquina como una pila de bytes, o mejor, de lugares donde se puede almacenar bytes, uno en cada lugar, lugar que a su vez ser identificado mediante un nmero, desde cero hasta el nmero mas grande que comprenda el espacio de almacenamiento, que recibe el nombre de memoria. Es probable, si Ud. es un habilidoso lector que se est preguntando que tiene que ver esta separata con lo nuestro. Mucho, lo voy a poner de esta manera.
Tipos Decimos que los parmetros en particular son un lugar o una pista como explicamos antes. Efectivamente el nombre del parmetro nos sirve para indicar, mediante el parmetro formal un rea de memoria donde se guardara el parmetro real. Suponiendo que el valor del parmetro real sea un nmero no mayor a 65535 el mismo se puede guardar usando 2 Bytes de memoria, si se trata de un carcter bastar con un solo byte, para cada tipo tendremos un nmero diferente de bytes necesarios para poder guardar el dato. Todo esto como vamos a ver nos servir para entender que es una variable

Variables Una variable es un nombre dado a un lugar de memoria donde se guarda o almacena un valor o en 34

El

Arte

de

Programar

lalgunos casos un conjunto de valores asociados para ser usados a lo largo del funcionamiento del programa.
Se requiere declarar la variable destacando el tipo de dato que va a almacenar. En este sentido una variable se parece a un parmetro, sin embargo a diferencia de aquel no existe asignacin de valor en forma automtica a la variable cuando una funcin es llamada. Cada ubicacin referida por una variable guarda un solo valor cada vez. Punteros Resumiendo, los datos se manejan en la computadora guardndolos como parmetros o variables. Para referirnos a ellos usamos el nombre. El nombre, como hemos dicho nos indica a cual variable nos estamos refiriendo, pero a veces vamos a necesitar saber exactamente en que lugar de memoria est esa variable y para ello necesito su direccin que como hemos dicho es un nmero entre 0 y el nmero que indica el ltimo lugar que forma parte de esta pila de bytes que llamamos memoria. Claro, como Ud. ya supone, necesitar referirme a esa direccin, leer, guardar manipular ese nmero, de manera que tendr que reservar un lugar de memoria para guardar esa direccin. Qu debo usar para ello?... Correcto! Una variable! A esa variable le llamamos puntero. Un puntero es entonces una variable usada para guardar la direccin de una variable. El tema es bastsimo de manera que lo vamos a ir tratando a medida que lo vayamos necesitando. Por ahora consolidemos lo aprendido mediante algunos ejemplos. El siguiente programa muestra el uso de variables en un programa. Observe que las variables a ser usadas

35

El

Arte

de

Programar

fueron declaradas antes de ser utilizadas inmediatamente debajo de la llave { que abre el bloque de cdigo que representa las sentencias a ejecutarse en la funcin. Y posteriormente se les asign un valor mediante una sentencia de asignacin del tipo: Nombre de variable = valor a asignarle; El operador de asignacin debe ser interpretado as: El valor que est en el lado derecho del operador deber ser almacenado en la direccin de memoria cuyo nombre est en el lado izquierdo. Programa 2.2 int i;// int nos indica que la variable i es del tipo entera char letra = D; ;// char nos indica que la variable letra es del tipo caracter char letra = D; main() { i=1; letra = D; printf(%*c\n,i,letra); i = i + 1; letra = I; printf(%*c\n,i,letra); i = i + 1; letra = A; printf(%*c\n,i,letra);

36

El

Arte

de

Programar

i = i + 1; letra = G; printf(%*c\n,i,letra); i = i + 1; letra = O; printf(%*c\n,i,letra); i = i + 1; letra = N; printf(%*c\n,i,letra); i = i + 1; letra = A; printf(%*c\n,i,letra); i = i + 1; letra = L; printf(%*c\n,i,letra); gets(); }

Es muy probable que est pensando que lejos de simplificar hemos complicado el programa que escribe DIAGONAL en la pantalla. Debido a que ha aumentado el nmero de lneas escritas, sin embargo fjese la semejanza de los grupos de tres sentencias formadas por las dos sentencias de asignacin y la de impresin, que adrede hemos espaciado. Adems observe que en cada caso se le suma 1 al valor anterior de i en las sentencias que tambin de ex profeso hemos puesto en negrita. En los prximos captulos tomaremos ventaja, y como!, de esta situacin, por ahora djeme decirle que la capacidad de resolver problemas de la computadora depende de su habilidad, amigo lector, para poder reducir los problemas

37

El

Arte

de

Programar

que le presente a formas como la vista. Observe la metamorfosis de printf(). Hemos incorporado un asterisco entre el signo % y el carcter c y luego hemos agregado i separado por una coma del nombre de la variable que debe ser mostrado. Recordemos que la funcin printf() requiere dos parmetros: un formato y una lista de argumentos, %c era necesario en formato para indicar que se debe imprimir un carcter, el carcter debe estar en la lista de argumentos, en este caso una lista de un solo carcter. El * entre % y c dice que el ancho mnimo a usar para imprimir la letra se debe especificar como el primer argumento precediendo al argumento del carcter a imprimir. La explicacin precedente le servir para entender cabalmente el programa. Si ha entendido ahora puede hacer solo, un programa que escriba lo siguiente: _D _I _A _G _O _N _A _L

38

El

Arte

de

Programar

Trabajando con cadenas (strings)


Hemos estado usando un tipo de dato sin haberlo caracterizado. En los ejercicios del capitulo 1 imprimamos frases cuidando solamente que antes del primer carcter y despus del ltimo pusisemos comillas. Luego al presentar los parmetros hablamos de la nocin de tipo de datos. El tipo string en C se declara reservando espacio para almacenar n+1 caracteres de tipo char, el espacio reservado para una variable del tipo string de n caracteres ser el espacio necesario para n variables del tipo char. ms 1, en este espacio se guarda el carcter nulo de C \0. La declaracin necesaria para poder despus usar un variable tipo string es: char nombre_de_la_variable[longitud_de_la_variable ] = sea_lo_que_sea ejemplos: char nombre[5] = hola char frase[19] = parece interesante el nmero entre corchetes representa la cantidad de caracteres de la tira ms 1 El programa listado a continuacin permite ilustrar en detalle lo expuesto. Escrbalo y ejectelo, luego correlacione lo que observa en la pantalla con lo que el programa se supone que hace. Observe que cada carcter del string puede identificarse mediante el nombre del string y el orden que ocupa, para ello al nombre del string se le adosa el nmero de orden encerrado entre corchetes.

39

El
Programa 2.3

Arte

de

Programar

char frase[43]= esta es una tira de 42 caracteres de largo; char letra; int i; main(){ printf(%s\n,frase); // imprimimos la variable tal cual es letra=frase[9]; //almacenamos en letra el noveno caracter de frase printf(%c\n,letra); // y lo imprimimos i = 8; printf(%c %c\n,frase[i],frase[8]); //ojal que coincidan letra =G; frase[3] = letra; printf(%s\n,frase); letra = frase[i-3]; printf(frase%c%d%c %c %c\n,[,i-3,],=,letra); gets(); } Asegrese de entender lo que aparece en pantalla. Si le resulta complicado entender la redaccin del contenido del parntesis del ltimo printf(), sintase bien, no es el nico, a continuacin le listo los distintos parmetros que se le pasa a printf() frase%c%d%c %c %c\n es el formato y luego de la coma esta la lista de argumentos [, i-3,],=,letra. Si ahora hacemos coincidir cada 40

El

Arte

de

Programar

argumento en la posicin marcada por cada letra precedida por el signo % en el formato ver que entiende como funcionan los argumentos de print(). Observe que el argumento que corresponde a %c debe ser un carcter mientras que el de %d debe ser un nmero. Algo que le debe haber llamado la atencin es el uso de expresiones usando variables, en lugar de la variable en si misma, por ejemplo al poner el ndice i-3, y al pasar el parmetro i-3. Ms adelante explicaremos esto con ms detalle. Por ahora usmoslo. Escriba el siguiente programa y ejectelo. Programa 2.4 char frase[]=La mar estaba serena; /* en esta seccin hacemos las declaraciones observe los detalles, declaramos el string y le asignamos el valor por eso no ponemos la cantidad de caracteres entre[]*/ int i; char c,letra[2]; /*declaramos ms de una variable del mismo tipo separando con comas*/ /*Definiremos una funcin que va a realizar una tarea determinada*/ reemplazar(para){ i=1; // note que insistimos en la repeticin de una misma tarea frase[i]=para; 41

El i=i+3; frase[i]=para; i=i+3; frase[i]=para; i=i+3; frase[i]=para; i=i+2; frase[i]=para; i=i+3; frase[i]=para; i=i+2; frase[i]=para; i=i+2; frase[i]=para;

Arte

de

Programar

}; main(){ printf(Ingrese la vocal\n); //avisamos que es lo que queremos que se haga gets(letra); //leemos la letra como si fuera un string c=letra[0]; //extraemos el primer caracter reemplazar(c); //y nuestra funcin la reemplaza en la frase printf(%s\n,frase); //y disfrutamos el resultado gets(); // esperamos antes de irnos } Su desafo es analizar el programa en cada una de sus partes y asegurarse que entiende el porque de cada sentencia, aprovechando las explicaciones dadas en las secciones de comentarios. 42

El

Arte

de

Programar

Algo sobre expresiones aritmticas. Si Ud. es un entusiasta de la computacin puede que no lo sea de las matemticas. Es por eso que hasta ahora no hemos tocado el tema, quera que nos acompaara todo el camino pero algo vamos a necesitar, y entonces algo vamos a explicar. Tal y como se lo enseo su querida maestra el signo + indica que las cantidades que se encuentran a ambos lados de el deben sumarse y el signo indica que la cantidad a la derecha del smbolo debe ser sustrada de la que est a la izquierda. Bien tal vez lo que sigue no le resulte tan obvio pero crame que le va a ser til. A los smbolos + y tambin los llamamos operadores. Y si tenemos definidas A y B como dos variables La expresin que sigue: A+B Indica la adicin del contenido de A y del contenido de B desde el punto de vista de la expresin, A y B reciben el nombre de Trminos. Un operador ms, que vamos a poner en juego ahora est representado por el * e indica el producto, por razones que no escaparn a su aguda inteligencia si usramos el clsico x o X tendramos alguna complicacin. La expresin

43

El

Arte

de

Programar

C*D Indica que el contenido de C ser multiplicado por el contenido de D, a C y a D los llamamos factores. Lo interesante de todo esto y que adems es por lo que lo estamos tratando, es que la expresin aritmtica ser evaluada por el computador toda vez que ella aparezca, as, en los ejercicios anteriores cuando apareci:

i = i + 1; el valor contenido en i fue reemplazado por el valor obtenido al aplicar la expresin i+1. Y cuando apareci: letra = frase[i-3]; se evalo la expresin contenida en el corchete y el resultado se us para indicar que carcter de frase deba almacenarse en letra. Una expresin interesante para revisar lo aprendido es: A*B +C*DE All tenemos 3 trminos A * B, C * D, y E 4 factores A, B, C y D.

44

El

Arte

de

Programar

La pregunta obligada es, como se evala?. Bueno volveremos sobre esto despus, pero djeme decirle que el producto tiene precedencia (esto es, se evala primero) sobre la suma de manera que en la expresin anterior los resultados de A*B y C*D se suman y luego se resta E. El uso de parntesis permite realizar las operaciones en el orden que se desea. Volveremos sobre esto cada vez que lo necesitemos. Punteros y Strings La declaracin de un string tiene distintas posibilidades. Para entenderlas, visualicemos primero un string o cadena de caracteres en la memoria de la mquina. Por ejemplo la cadena Hola se vera en memoria de la siguiente manera:

H o l a \0
0 1 2 3 4 Cada casilla representa un byte de memoria, vemos que en cada uno se aloja un carcter y que en el ltimo esta el carcter Null. Esta es la forma en la que C guarda un tipo String. Los nmeros de cada casillero indican el ndice. Pongamoslo de esta manera, el nombre 45

El

Arte

de

Programar

que le damos, nombra a la variable tipo string y como veremos a continuacin es al mismo tiempo el nombre del puntero (la variable que guarda la direccin) mientras que el indice es el desplazamiento que hay que sumarle a la direccin del primer cracter para obtener la direccin de un determinado caracter dentro del string. Fije esta imagen, mediante ella le va a resultar muy fcil entender los punteros y podr asi usarlos en sus programas aprovechando todas las ventajas que ofrecen. De manera que al string lo declaramos dndole un nombre y entre corchetes la cantidad de caracteres que ocupa ms 1. Por ejemplo supongamos que lo llamamos saludo La declaracin sera char saludo[5] o bien si le asignamos el valor en el momento de la declaracin char saludo[] = Hola Programa 2.5 char cadena[] = hola; main() { printf(La cadena es %s \n, cadena); printf(Los caracteres son: \n); printf(%c \n, cadena[0]); 46

El

Arte

de

Programar

printf(%c \n, cadena[1]); printf(%c \n, cadena[2]); printf(%c \n, cadena[3]); printf(%c \n, cadena[4]); gets(); } Es el momento de hablar un poco ms acerca de los punteros.Habamos dicho que para almacenar o simplemente manipular un puntero debamos guardarlo en una variable. Es necesario como para toda variable declararla y para ello hay que darle un nombre y un tipo. El nombre es arbitrario pero el tipo debe establecer el del dato al que apunta, casi intuitivamente vemos que no debe ser lo mismo el lugar que guarda una variable del tipo char que el lugar que guarda a un puntero a una variable del tipo char. El problema se soluciona mediante un asterisco. Programa 2.6 char cadena[] = hola; char *ptr1,*ptr2,*ptr3; char letra; main() { printf(La cadena es %s \n, cadena); /*Imprimamos ahora el valor del puntero a la primera letra*/

47

El

Arte

de

Programar

printf(El primer puntero es: %d \n,&cadena[0]); /*Observe que hemos usado el operador de direcciones & */ /*Compare el resultado anterior con el siguiente*/ printf(El puntero a comparar es: %d \n,cadena); /*Importante lo que hemos descubierto El nombre del string es al mismo tiempo el nombre de la variable que guarda la direccin del primer elemento del string*/ /*Veamos ahora el valor del ultimo puntero*/ printf(El puntero a comparar es: %d \n,&cadena[4]); /*Podemos ademas guardar en ptr1 y ptr2 los valores del primer puntero y del tercero*/ ptr1=&cadena[0]; ptr2=&cadena[2]; printf(Los punteros ptr1 y ptr2 valen: %d %d\n,ptr1, ptr2); /*finalmente podemos escribir los contenidos de las direcciones marcadas por ptr1 y ptr2*/ printf(Los contenidos de ptr1 y ptr2 son: %c y %c\n,*ptr1, *ptr2); gets(); }

48

El

Arte

de

Programar

Corra (es otra manera de decir ejecute) el programa anterior y observe lo obtenido en la pantalla. Encontrar y aprender muchas cosas, entre otras como se declara un puntero a caracteres, como puede leer una direccin mediante el operador &, como puede mediante la direccin mostrar el contenido de una variable. Si es lo suficiente observador debe haber quedado atnito de ver en el ltimo printf al * ,si es as, vale !, como dira un amigo mo espaol. El operador * tiene entre otras, dos tareas aparentemente diferentes. En una permitir la definicin de un puntero y en otra afectar al nombre de un puntero para mostrar el contenido de la direccin que guarda el puntero. Valo as, el asterisco aplicado a una variable puntero muestra el contenido de la direccin marcada por el puntero En el caso de la declaracin char *ptr diramos el contenido de la direccin marcada por ptr es del tipo char Si le cuesta verlo sonra, Ud. Es uno ms de los muchos que no ven esto. Le aseguro que con el tiempo y de tanto usarlo se va a dar cuenta. Si Ud, es de los agudos, hay va esta char* ptr tambin vale como declaracin de puntero a string

49

El

Arte

de

Programar

A continuacin vamos a rehacer el ejercicio ocho aplicando punteros. Programa 2.7 char frase[]=La mar estaba serena; /* en esta seccin hacemos las declaraciones observe los detalles, declaramos el string y le asignamos el valor por eso no ponemos la cantidad de caracteres entre[]*/ int i; char c,letra[2]; /*declaramos ms de una variable del mismo tipo separando con comas*/ /*Definiremos una funcin que va a realizar una tarea determinada*/ reemplazar(para){ // note que insistimos en la repeticin de una misma tarea i=1; *(frase+i)=para; i=i+3; *(frase+i)=para; i=i+3; *(frase+i)=para; i=i+3; *(frase+i)=para; i=i+2; *(frase+i)=para;

50

El

Arte

de

Programar

i=i+3; *(frase+i)=para; i=i+2; *(frase+i)=para; i=i+2; *(frase+i)=para; }; main(){ printf(Ingrese la vocal\n); //pedimos lo que queremos gets(letra); //leemos la letra como si fuera un string c=letra[0]; //extraemos el primer caracter reemplazar(c); //y nuestra funcin la reemplaza en la frase printf(%s\n,frase); //y disfrutamos  el resultado gets(); // esperamos antes de irnos } Funciones incorporadas para usar con Strings Una funcin en la jerga computacional es un segmento de programa. Uno llama a una funcin (la pone en funcionamiento), colocando su identificador(y la lista de parmetros requeridos), dentro de una expresin. Cundo los pasos dados para evaluar la expresin alcanzan la funcin esta es puesta en ejecucin. Cuando la ejecucin de la funcin concluye, un valor es dejado en reemplazo de su identificador en la expresin, la que contina evalundose. Decimos que la funcin retorna un valor para ser usado en la expresin, tambin se 51

El

Arte

de

Programar

suele decir devuelve o entrega. El tipo de dato que la funcin entrega es especificado en el momento de la declaracin de la misma. El lenguaje C tiene incorporado una serie de funciones que facilitan el trabajar con strings. El siguiente ejercicio ilustra muy bien el uso de cada una de las subrutinas, nombre que tambin es vlido para designar a estos subprogramas. La descripcin de algunas de las funciones que usaremos es la siguiente; StrCat(cadena1,cadena2) Descripcin StrCat concatena cadena2 a continuacin de cadena1 cadena1 debe tener espacio suficiente para ello es probable que haya que usar antes StrCpy(). Ejemplo Programa 2.8; char cadena1[25]= Hasta ; char cadena2[6]=luego ; main() { strcat(cadena1,cadena2); printf(%s\n, cadena1); gets(); } 52

El

Arte

de

Programar

StrCpy(cadena1, cadena2); Descripcin StrCpy copia cadena2 en cadena1, en cadena1 debe haber suficiente espacio Ejemplo Programa 2.9; char cadena1[10]; char cadena2[6]=luego ; main() { strcpy(cadena1,cadena2); printf(%s\n, cadena1); gets(); }

StrStr(cadena2, cadena1);

Descripcin StrStr devuelve la posicin de memoria donde se encuentra por primera vez la cadena 1 en la cadena2 Ejemplo

53

El Programa 2.10;

Arte

de

Programar

char cadena2[16]=Esta es una tira; char *ptr; char cadena1[3] =ta; main() { ptr = strstr(cadena2, cadena1); printf(El caracter %s esta en la posicin: %d\n, cadena1, ptr-cadena2); gets(); } StrSet(cadena1, letra, n); Descripcin StrSet Reemplaza n caracteres de cadena1 con letra; Ejemplo Programa 2.11; char *cadena1 = abcdefghijklmnopqrstuvwxyz; char letra = x; main() { printf(cadena1 antes de strnset: %s\n, cadena1); strnset(cadena1, letra, 13); printf(cadena1 despus de strnset: %s\n, cadena1); gets();} 54

El

Arte

de

Programar

StrLen(cadena1); Descripcin Calcula la longitud de cadena1. Ejemplo Programa 2.12;char *string = Borland International; main() { printf(%d\n, strlen(string)); gets(); } EL ejemplo de la funcin que sigue no lo va a entender, no se aflija luego de estudiar el capitulo sobre bucles vuelva y lo podr leer. Strchr(cadena1,c); Descripcin Explora cadena1 para encontrar la primera ocurrencia del caracter, devuelve el puntero o null si no lo encuentra. Ejemplo Programa 2.13; int main(){ 55

El

Arte

de

Programar

char string[15]; char *ptr, c = 'r'; strcpy(string, "This is a string"); ptr = strchr(string, c); if (ptr) printf("El caracter %c esta en la posicin: %d\n", c, ptrstring); else printf("El caracter no se encontr\n"); gets(); } Pero permtame que en pos de nuestro objetivo. Aprender a resolver problemas. Lo haga razonar de la siguiente manera: Es un proceso expontaneo de nuestro intelecto el ponderar las posibilidades y habilidades antes de tomar accin ante una dificultad, salvo los actos reflejos que actan, gracias a Dios, sin meditar mucho. Pero debido al uso reiterado, se desarrollan ciertos hbitos que nos hacen actuar de tal forma que el proceso no resulta obvio. En este libro pensamos hacerle recapacitar una y otra vez frente a los actos que ejecute para que esa habilidad innata que le acabamos de expresar este siempre presente en forma explicita ante los problemas que deba resolver. S yo le pidiese a Ud. Que contara cuantas palabras tiene una frase. Luego de observarla dira el valor. Si la frase es corta sin dudarlo, si la frase es larga tal vez recurriendo a la tcnica que usa para contar.

56

El

Arte

de

Programar

El proceso al que haca referencia recin; en este caso, es la bsqueda sistemtica de los espacios para identificar una palabra de la otra. Y esto es lo que no es obvio. Si cree que estoy diciendo una verdad de perogrullo piense que pasara si le presentase la frase sin los espacios. Una palabra a continuacin de la otra. Resolvera igual el problema, pero la tcnica que usara sera diferente. Ira agrupando caracteres y encontrando significados que le permitieran aislar las palabras. Se da cuenta?. El primer mecanismo resulta ms obvio que el segundo, es probable que en el segundo se d cuenta de lo que tuvo que hacer, mientras que para el primero, hasta le puede resultar un esfuerzo tremendo el razonar acerca del mecanismo que aplic si se le preguntara, porque le parece tan obvio que hasta le puede parecer ridculo que se pregunte acerca de ello. Bien de eso se trata pretendemos aplicar estos procedimientos de manera expresa. La tcnica se puede resumir diciendo Divide y reinars. A continuacin vamos a mostrar una serie de problemas que se resuelven aplicando las funciones vistas. Por ahora esperamos que Ud. lea detenidamente los programas los comentarios y entienda como funcionan. De esa forma ir incorporando experiencias que le permitirn identificar dificultades similares en problemas futuros. El siguiente programa elimina cada palabra usando el carcter espacio como limite, el

57

El

Arte

de

Programar

procedimiento recortador se ocupa de ello. Programa 2.14 char *ptr,*nespacios,letra[2],frase[80];


/*Definimos una funcin que elimina la primer palabra mediante el simple expediente de apuntar el comienzo del string un caracter mas de dnde esta el espacio*/

recortador(){ nespacios = strstr(frase,letra); // encuentra el primer espacio ptr = nespacios+1; // apunta ptr un caracter mas all del espacio strcpy(frase,ptr); //actualiza la frase original con le nuevo valor printf("%s\n",frase); // y muestra el resultado } main() { strcpy(frase,"que interesante el tema tratado"); strcpy(letra," "); printf("%s\n",frase); recortador(); recortador(); recortador(); recortador(); gets(); } Cada vez que llamamos a recortador en el programa principal el hace su trabajo. Esto es, busca un espacio en el string , luego usa la informacin obtenida y elimina la primer palabra, luego imprime el string que qued. Recortador en este otro ejemplo permite que el programa haga lo siguiente. 58

El

Arte

de

Programar

Que interesante el tema tratado Queinteresante el tema tratado Queinteresanteel tema tratado Queinteresanteeltema tratado Queinteresanteeltematratado Queinteresanteeltematratado Programa 2.15
/*Ahora recortador ubica el primer espacio. Deja solo la primer palabra en la variable original. Salva el resto en una nueva variable y luego las concatena*/

char *ptr,*nespacios,letra[2],frase1[80],frase2[80]; recortador(){ nespacios = strstr(frase1,letra); // encuentra el primer espacio ptr = nespacios+1; //apunta ptr un caracter mas all del espacio strcpy(frase2,ptr); //guarda el resto de la frase original en frase2 frase1[nespacios-frase1]='\0';//limita frase1 a la primer palabra strcat(frase1,frase2); //concatena frase1 y frase2 printf("%s\n",frase1); }// y muestra el resultado } main(){strcpy(frase1,"que interesante el tema tratado"); strcpy(letra," "); printf("%s\n",frase1); recortador(); recortador(); recortador(); recortador(); gets(); } Haga un programa que coloque doble espacio entre cada palabra de la frase original 59

El

Arte

de

Programar

El programa siguiente reemplaza palabras. programa 2.16


/*Veamos ahora una funcin que a partir de una frase y una palabra detecta la posicin de la palabra en la frase la remplaza por otra*/

char *ptr,*ptr1,espacio[2],palabra[10],reemplazo[6],frase1[80],frase2[80]; sustituir(){ ptr = strstr(frase1,palabra); //ubica la palabra strcpy(frase2,ptr); //copia la parte superior de la frase frase1[ptr-frase1]='\0'; //termina frase1 en la primer palabra ptr1=strstr(frase2,espacio); //ubica el primer espacio strcpy(frase2,ptr1); //simplemete elimina la palabra a reemplazar strcat(frase1,reemplazo); //le anexamos la palabra reemplazante strcat(frase1,frase2); printf("%s", frase1);//terminamos la frase} main(){ strcpy(frase1,"Hubo mucho de todo"); // preparamos la frase strcpy(espacio," "); // este es el espacio a buscar strcpy(palabra,"mucho"); //la palabra a sustituir strcpy(reemplazo,"poco"); //la palabra que sustituye printf("%s\n",frase1); sustituir(); gets(); Modifique la funcin sustituir para que a partir de las siguientes dos frases, que el programa deber escribir primero, sustituya las ocurrencias de mucho por poco, algo o lo que a Ud. se le ocurra. La sustitucin la debe hacer la funcin. 60

El

Arte

de

Programar

Ahora ha llegado el momento de probarse. La siguiente es una serie de problemas que le va a permitir poner en prctica lo aprendido.

Pero antes y para que no tenga que borrar todo antes de escribir su programa le sugiero que deje las cosas como estn, esto es asi: //--------------------------------------------------------------#pragma hdrstop //--------------------------------------------------------------#pragma argsused int main(int argc, char* argv[]) { return 0; } //--------------------------------------------------------------Yo le prometo que pronto le voy a explicar cada una de las cosas que a jusgar por lo hecho hasta aqu estn de ms. Para que no se confunda el programa 2.15 debiera quedar as: #pragma hdrstop //--------------------------------------------------------------#pragma argsused /*Veamos ahora una funcin que a partir de una frase y una palabra
detecta la posicin de la palabra en la frase la remplaza por otra*/ char *ptr,*ptr1,espacio[2],palabra[10],reemplazo[6],frase1[80],frase2[80];

61

El

Arte

de

Programar

sustituir(){ ptr = strstr(frase1,palabra); //ubica la palabra strcpy(frase2,ptr); //copia la parte superior de la frase frase1[ptr-frase1]='\0'; //termina frase1 en la primer palabra ptr1=strstr(frase2,espacio); //ubica el primer espacio strcpy(frase2,ptr1); //simplemete elimina la palabra a reemplazar strcat(frase1,reemplazo); //le anexamos la palabra reemplazante strcat(frase1,frase2); printf("%s", frase1);//terminamos la frase }

int main(int argc, char* argv[]) { strcpy(frase1,"Hubo mucho de todo"); // preparamos la frase strcpy(espacio," "); // este es el espacio a buscar strcpy(palabra,"mucho"); //la palabra a sustituir strcpy(reemplazo,"poco"); //la  palabra que sustituye printf("%s\n",frase1); sustituir(); gets(); return 0; } //---------------------------------------------------------------

62

El

Arte

de

Programar

PROBLEMAS Problema 2.1 El siguiente programa fue escrito para presentar las siguientes cuatro lneas. X XXX XXXXX XXXXXXX programa Piramide {char f[20]; xf[10], x2[10]; int N main() strcpy(f," "); // 10 espacios strcpy(x2,"XX"); strcpy(xf,"X"); strcatf, x2); printf("%s\n",f); strse(f,X); strcpy(f,f+1); printf("%s\n",f); get(; El programa tiene una serie de errores de sintaxis y lgicos. Primero corrija los errores de sintaxis sin recurrir a la ayuda del compilador. Esto es, lea el programa y corrija los nueve errores de sintaxis que tiene. A pesar de corregir los errores de sintaxis el programa no funcionar. Analice el programa tal como est escrito, sin los errores de sintaxis por supuesto, y dibuje lo que el programa hace, sin usar la computadora, simplemente con papel y lpiz. 63

El

Arte

de

Programar

Ahora modifique el programa para lograr el resultado buscado. Piense como hace Ud. para lograr el dibujo logrado y luego escriba el programa, para una dificultad como la aqu presentada debiera funcionar bien despus de una corrida de ajuste, si Ud. antes de conseguir el resultado correcto debe correr dos veces el programa, pngase un regular y si lo tuvo que correr tres veces, reprob, pero no se sienta mal recin estamos empezando y yo todava no le he mostrado como se analiza, define y formula un problema. Problema 2.2 Los procesadores de textos son programas que permiten la escritura de diferentes documentos, facilitando las tareas tpicas de la actividad: reemplazar prrafos, corregir errores, etc. etc. El siguiente programa muestra una alternativa que podra usarse para mostrar en pantalla una frase dividida en dos para indicar un punto dnde debiera introducirse un cambio. Por ejemplo:

Haba una vez cierto muchachuelo que sola visitar...

Podra transformarse en:

Haba una vez cierto muchachuelo que sola visitar...

64

El

Arte

de

Programar

Complete el programa con todo lo necesario para lograr tal cometido. Corrija si los hubiere los errores que encuentren en el tramo de programa dado. programa partidor; char *position tope, base, relleno, patron; main(){ relleno= ; tope = Haba una vez cierto muchachuelo que sola visitar...; patron = cierto; posicion=strstr(patron,tope); base = strcpy(tope,posicion-length(tope)); ..... ..... Problema 2.3 Vamos a terminar el programa que sigue para que modifique la forma en que escribimos los nombres de las personas. Asumimos que los nombres tienen al menos dos nombres y un apellido, y que del ltimo de los nombres solo se pone la letra inicial y un punto. El programa cambia la forma: Julin Carlos D. Garca por Garca, Julin Carlos D. Complete el programa, corrija los errores que hayan y deje la forma final en la variable destino

65

El

Arte

de

Programar

programa alreves; char fuente, destino, patron; char *posicion; main() strcpy( fuente, Mara C. Gomez);//puede ser cualquier nombre patron = .; posicion = strstr(patron,fuente); destino = fuente; .... .... Problema 2.4 Conteste usando sus propias palabras en forma breve las siguientes preguntas: Qu es una funcin? Explique tres razones por las que uno debiera usar funciones en casi todos los programas. Qu es un parmetro y cmo se lo usa? Qu es una variable y cmo se la usa? A qu se le llama tipo? Qu 3 tipos hemos usado en este captulo? Cmo y para qu hemos usados expresiones aritmticas?

66

El Problema 2.5

Arte

de

Programar

La siguiente declaracin de variables figura en el encabezamiento de un programa: int I, J; char Letra1, Letra2; char Fa, Fb; I = -1; J= I; J=3; I= length(Fa); I=1234; Letra1=1; Letra1=Q; Letra2=Fa[J]; Letra2= 27; Letra1=Letra2; Fa=cualquier frase; Fa=5; Fb=Letra2; Fa=I; Fb=Fa; Fb=Fa; Fb=strcat(Fb,Fa); Fa=R; Indique que es lo que est mal en aquellos que Ud. as los considere.

67

El

Arte

de

Programar

68

El

Arte

de

Programar

3 EL ENTORNO VISUAL
Ahora que hemos avanzado sobre las tcnicas de programacin podemos intentar comprender algo ms del entorno que estamos usando para incorporar de esta manera nuevas herramientas que nos permitirn proponer problemas ms interesantes. LAS INTERFACES GRAFICAS Es probable que Ud. a esta altura se este diciendo, todo esto es muy divertido pero que tiene que ver con programar una computadora realmente. Lo que ha hecho hasta ahora, si es que lo ha hecho, es escribir programas que no tienen nada diferente a los que permiten que use la computadora de la manera que lo hace. Pero, dir Ud., alguna diferencia debe haber. Bueno lo admito hay una diferencia, los programas que ha escrito no son mas largos que unas decenas de lneas, mientras que los programas que normalmente usa ocupan decenas y hasta centenas de miles de instrucciones. Ese es el caso de los programas que le permiten manejarse con el ratn y las representaciones grficas (llamadas iconos) que aparecen en la pantalla. Existe un teorema llamado Teorema de la programacin estructurada, que sostiene que todo problema de computacin puede ser resuelto usando Sentencias de asignacin, sentencias de comparacin y sentencias de repeticin. Ud ha aprendido a usar las primeras, las sentencias de comparacin y los lazos de repeticin los veremos en los proximos captulos. Pero como ver el trabajo a realizar es del mismo tipo, lo que hace que la escritura de los programas sea una tarea lenta muy proclive al error, con el agravante de que a cada una de ellas hay que escribirla completa con cada uno de sus detalles. Ahora bien, si cada vez que realizamos un programa que preste alguna utilidad debisemos escribirlos totalmente desde cero, las prestaciones que las computadoras ofrecen sera mucho menor de lo que actualmente son.

69

El

Arte

de

Programar

Por ello han ido apareciendo herramientas tiles para ayudar en la tarea de escribir programas. Ademas el objetivo fundamental de todo programa es que sea amistoso para el usuario. El ambiente Windows es, a no dudarlo, el que mejor ha materializado estos objetivos. En realidad la forma correcta de referirse a esto es hablar de IGU interfases grficas de usuario Conocidas por su sigla en Ingls ( ya hemos hablado de esto verdad? ) GUI. Las interfaces graficas son particularmente amistosas y agradables y los proveedores de software de produccin se preocupan de presentar productos que permitan aprovechar al mximo dichas caracteristicas.La pantalla que aparece cuando ponemos a BUILDER en funcionamiento es caracterstica de los llamados entornos de programacin visual. OBJETOS Y SUS PROPIEDADES Una vez ms permitame recordarle que nuestro objetivo es aprender a resolver problemas usando la computadora y en esa tarea es conveniente, con el  objeto de plantearnos problemas ms interesantes, que incursionemos un poco sobre la interface grfica que nos permite usar BUILDER. Si mira con atencin la pantalla de BUILDER observara que el gran espacio que tiene arriba a la izquierda la palabra Form1 tiene la forma de, y la apariencia de uno de esos tableros que es posible encontrar en las ferreterias. Estos tienen muchisimos agujeros que permiten colocar ganchos de los cuales se pueden colgar herramientas u otros objetos. Y esto es as porque Form1 simula exactamente eso. Es un tablero sobre el que vamos a colocar objetos que nos servirn para distintos propsitos. En particular sobre esta superficie de apariencia perforada es posible extender un lienzo (canvas en ingles) y en este lienzo podremos escribir y dibujar, pero recordemos a mi amigo el del elefante y vamos de a un paso por vez. Coloquemos un objeto en la forma, para ello elijamos uno desde el muestrario. Este se encuentra inmediatamente sobre la forma y bajo la solapa que dice Standard

70

El

Arte

de

Programar

El objeto que vamos a elegir primero es un cuadro de edicin en el muestrario figura como un rectangulo en blanco en los que se destacan los caracteres ab y cuando Ud. lo recorre con el ratn aparece un cartel que dice Edit. Este objeto, que tambien recibe el nombre de componente, permite exhibir texto dentro de l. Para colocarlo en la Forma simplemente apretamos el botn derecho del ratn cuando estamos sobre l, esta maniobra nos permite adquirir el componente, soltamos el botn y nos movemos sobre la forma al lugar en que deseamos colgar el objeto y volvemos a apretar el botn derecho, al soltarlo queda el cuadro de edicin en la forma. El cuadro tiene escrito dentro de l la palabra Edit1 y tiene 8 botones cuadrados negros. Si ahora pulsa el botn fuera de la superficie del cuadro desaparecen los cuadrados negros. Si pulsa de nuevo el botn dentro del rea del cuadro aparecen los cuadrados negros. Es interesante ver lo que ocurre en la ventana de la izquierda, la que tiene el nombre Object Inspector  , mientras hace lo indicado anteriormente, esto es pulsar, el botn del ratn sucesivamente dentro del cuadro y fuera del cuadro. La ventana del inspector como la vamos a llamar de aqu en adelante, cambia la leyenda que est inmediatamente debajo de dnde dice Object Inspector de Edit1:TEdit a Form1:TForm1, adems cambian todas las propiedades mostradas bajo la solapa Properties si como debe ser esta es la solapa que ha sido elegida, sino, lo que estar cambiando ser los Events que es la otra alternativa posible. Ocupmonos por ahora de la propiedades . Todo objeto tiene propiedades y los componentes de BUILDER no son la excepcin, en realidad los componentes son elegidos con propiedades que los hacen adecuados al uso que le queremos dar Qu propiedades tiene el cuadro de edicin ? Bueno entre otras tiene un nombre (name, en ingles) tiene un ancho(width), un alto(height), un texto (text), etc. etc En la

71

El

Arte

de

Programar

ventana del inspector podemos encontrar estas propiedades y cambiarlas a gusto. Modifique las propiedades de nombre y de texto colocndose con el ratn y pulsando el botn izquierdo frente al nombre en Ingls de cada propiedad a cambiar, luego de haber elegido el cuadro por haber pulsado el botn izquierdo dentro de l. Nombre el cuadro como Cuadro, original, verdad? y en texto escriba lo que usted desee. Ver que en la ventana del inspector dnde antes deca Edit1:TEdit ahora aparece Cuadro:TEdit lo que nos informa que el inspector esta mostrando las propiedades y los eventos, dependiendo de la solapa elegida, de un componente de nombre Cuadro y de tipo TEdit Cuando pulse el botn fuera del cuadro el inspector mostrar las propiedades y eventos del nuevo objeto, en este caso Form1 que es un componente del tipo TForm. Porque se pone la T adelante de cada componente no tiene ningna importancia para nuestra tarea, simplemente vamos a aceptar que se llaman de esta manera. Interesante este tema de los objetos verdad?. Si a Ud. le siguen interesando las computadoras despus de esta experiencia tal vez nos encontremos pronto trabajando sobre objetos mucho ms en detalle. Por ahora fijmonos en cmo usarlos. Decamos recin que las propiedades de los objetos se fijan en funcin del uso que el objeto va a tener para que se usa una ventana de edicin?.....       "! ! # # # $ para editar. Durante mucho tiempo he usado la palabra editar sin buscarla en el diccionario pero ahora que pretendo explicarle qu significa fu y mir y esto es lo que encontr:

%'& ( & )0&21 3 4 56"3 7 1 8 ( & )93 @ &BA 7 ) &DCFE G 8 & @"H E21 &28 CPI") E @"H & 5
De manera que de eso se trata, vamos a usar la ventana de edicin para sacar a la luz informacin desde la computadora y vamos a entregarle informacin a la computadora. Por lo tanto las propiedades del cuadro de edicin tiene que ver con la escritura y lectura de datos.

72

El

Arte

de

Programar

Hasta ahora en nuestro simple mundo de MSDOS nos habamos arreglado con printf, gets, y las variables de tipo integer , string y char. El cuadro de edicin es un objeto que nos va a permitir ingresar datos en la computadora y tambin leer datos. Los datos en general estn representados mayoritariamente por letras y nmeros y estos pueden ser escritos por nosotros, cuando ingresamos datos, o por el programa cuando sale informacin en el cuadro de edicin. Pero cmo se almacena ese dato en la memoria de la mquina es fuertemente dependiente del tipo de datos que se trate. Por ejemplo si el dato son letras (tipo de datos char) cada letra se guardar en un byte. Si son string ser un conjunto de bytes el que ser ocupado por el string. Mientras que si lo que queremos incorporar son nmeros, depender del tipo de nmero como va a ser almacenado. Pero todo esto debe ser hecho a travs de uno solo de los atributos del cuadro de texto que es text. Digmoslo as: el objeto cuadro de texto(TEdit) se usa para ingresar o mostrar texto en la pantalla del computador, ese texto lo guarda bajo el nombre Q R S Q en dnde? en la memoria de la mquina. Pero entonces es una variable! SI!. De qu tipo? String!!!. Y este es el objeto de esta separata: permitirle ver la necesidad que vamos a tener de manipular los datos que ingresamos a la mquina o que queremos mostrar en la pantalla para adecuarlo a la circunstancias. Si ingresamos o mostramos una variable del tipo string no hay ninguna modificacin a hacer pero si ingresamos o queremos mostrar otro tipo de datos deberemos convertirlo de string a lo que sea y de lo que sea a string, y eso cmo se hace ?, .... Menos averigua Dios y perdona.

73

El

Arte

de

Programar

Sin embargo como lo vamos a tener que usar, tarde o temprano se va a tener que enterar. Finalmente y antes de avanzar con otro tema asegrese que puede visualizar las propiedades del objeto que hemos estado viendo, para ello cuando pulse el botn fuera del cuadro el inspector mostrar las propiedades y eventos del nuevo objeto, en este caso Form1 que es un componente del tipo TForm. Por qu se pone la T adelante de cada componente no tiene ninguna importancia para nuestra tarea, simplemente vamos a aceptar que se llaman de esta manera. Bien, estamos en condiciones, ahora que conocemos que existen componentes (objetos) de incorporarlos en nuestras prcticas y a medida que lo hagamos aprenderemos de sus propiedades y de otras caractersticas que todava no ha sido necesario citar.

74

El

Arte

de

Programar

LA PROGRAMACION BAJO BUILDER Vamos a continuar nuestro trabajo pero aprovechando ahora todo lo que BUILDER nos ofrece. Esto significa que vamos a usar los componentes y lo que con estos se puede hacer. Ahora bien si como decamos antes, estas herramientas han sido realizadas mediante cientos o miles de instruciones, habr que incorporar esas instrucciones en nuestros programas. Pero si en realidad nuestros programas estn formados por decenas de instrucciones parece que tiene ms sentido que sean estos los que se incorporen en los programas de BUILDER. Bien efectivamente esto es lo que ocurre. Vemoslo. Para ello pongamos en nuestra forma de la manera que ya sabemos, un botn. Lo encontramos en el mismo muestrario de Edit pero bajo el nombre Button Ahora vamos a atender a una caracteristica diferente de los componentes. Para ello pulse dos veces seguidas sobre el botn una vez que lo ha colocado en la forma. Ver aparecer una ventana con lo siguiente:

void __fastcall TForm1::Button1Click(TObject *Sender)


{ } Ud. ya sabe leer esto, esta frente a una funcin que tiene como nombre
void __fastcall TForm1::Button1Click

75

El

Arte

de

Programar

un parmetro llamado Sender que es del tipo puntero a TObject. no hay nada en el cuerpo del procedimiento tan slo las llaves { }. Observe que a la derecha de la ventana la corredera le indica que esa ventana tiene ms que mostrar en la parte superior. Si amplia la ventana y la recorre hacia arriba se va a encontrar con lo siguiente:

//--------------------------------------------------------------#include <vcl.h> #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------#pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------Otro elefante!.
Permitame que lo ponga en estos trminos. As es como BUILDER escribe los programas. Ud. no necesita conocer el detalle de nada de esto para poder seguir adelante. Le prometo que poco a poco vamos a ir descubriendo algunas de las caracteristicas que por ahora le son desconocidas. Lo que realmente importa es que BUILDER escribe la mayor parte del programa, dejandole a Ud. que escriba su parte. Si ahora pulsa como antes el icono en forma de triangulo de color verde, el programa se compilar y ejecutar.

76

El
Hgalo!.

Arte

de

Programar

Qu pas?. Nada. Bueno en realidad aparece la ventana de Form1 con el boton Button1 el que si me pongo con el ratn sobre l y pulso el botn derecho se unde pero no pasa nada ms. Esta bien, asi tiene que ser porque no escribimos nada en la funcin que se ejecutar cuando Button1CLick. Para volver al ambiente de desarrollo debemos pulsar la X arriba a la derecha de Form1 o el icono inmediatamente a la derecha de la palabra Form1. Una vez en el ambiente de desarrollo pulse el botn izquierdo del ratn sobre la parte grisacea de Form1 que se insinua sobre la ventana de Unit1 Si esto no es posible en el men superior busque View luego Forms y elija Form1 Volvamos a apretar el boton dos veces, pero antes agreguemos un cuadro de texto al que llamaremos Cuadro y escribamos lo siguiente como procedimiento del Button1Click. - (el simbolo -> es el guin seguido del signo de mayor) -

Cuadro->Text = "Texto que aparecer en la ventana";


Esto debe ir por supuesto entre las llaves { y } de la funcin
void __fastcall TForm1::Button1Click

Que buen momento para:

Que hacer cuando nada funciona.


Si todo esta bajo control compile y ejecute y ver que al apretar el botn aparece el texto en el cuadro. Revisemos lo hecho: BUILDER nos provee de una serie de componentes Estos componentes pueden ser usados en nuestros programas

77

El

Arte

de

Programar

Por cada Form BUILDER arma una Unit Esta unidad tiene todo lo necesario para su correcto compilado y ejecucin incluido las declaraciones y cdigo que necesitan los componentes insertados por nosotros Los componentes tienen propiedades y eventos asociados . Las propiedades pueden ser modificadas por programa y los eventos pueden desencadenar acciones A la luz del resumen anterior revisemos lo que hace el ltimo programa que hemos escrito y ejecutado. Para ello a continuacin listamos el contenido de Unit1

//--------------------------------------------------------------#include <vcl.h> #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------#pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------78

El

Arte

de

Programar

void __fastcall TForm1::Button1Click(TObject *Sender) { Cuadro->Text = "Texto que aparecer en la ventana"; } //--------------------------------------------------------------Observe que la propiedad esta precedida por el nombre del componente seguido de una flecha, la que como explicamos antes se arma con el guin y el signo de mayor. Este simbolo indica la pertenencia de la propiedad al objeto en cuestin Si observa con atencin ver que el texto es mayor que el tamao del cuadro, habr que ajustar el tamao del cuadro al tamao del texto. Vuelva al ambiente de desarrollo elija el cuadro apretando el botn izquierdo del ratn dentro de l y luego apretando de nuevo el mismo botn sobre el cuadrado negro que aparece sin soltarlo desplace el ratn hacia la derecha y ver como aumenta el tamao del cuadro. Si quiere puede modificar el tipo y el color de la letra que esta usando, para ello vaya al inspector, ubique Font apriete el cuadradito con los tres puntos y se abrir un men en el que podr elegir las caractersticas que Ud. prefiera. En castellano ? Asi es, si su Sistema Operativo Windows esta en castellano, pues la ayuda vendr en castellano. Si a Ud. le gusta variar colores, tipos y tamaos ha llegado el momento de divertirse. Veamos mientras tanto si lo que aprendimos nos sirve. Que tal si repetimos nuestro programa diagonal en este ambiente visual. Recordemos que en la pantalla de DOS

79

El

Arte

de

Programar

utilizbamos printf() para nuestros escritos, las cosas no son as en el ambiente windows. Las formas admiten una serie de objetos en los que podemos escribir. La ventana de edicin que hemos estado analizando es uno, otro es el objeto memo. Vamos a utilizar ahora el objeto Label. El icono de label es el Que tiene la letra A en el centro. Por razones que vamos a explicar necesitamos varios labels para ello vamos a pulsar la tecla SHIFT y mientras esta tecla esta apretada pulsemos el botn izquierdo del ratn sobre el icono, luego vamos a pulsar sucesivamente el mismo botn sobre la forma. En cada oportunidad vamos a correr la nueva etiqueta de manera que quede debajo y a la izquierda de la anterior. Lo que estamos haciendo es preparando los lugares donde vamos a colocar cada una de las letras que componen la palabra que pretendemos reescribir en forma diagonal. El siguiente programa permite escribir la palabra DIAGONAL colocando una letra en cada lnea.

//--------------------------------------------------------------#include <vcl.h> #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------#pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) 80

El

Arte

de

Programar

{ } //--------------------------------------------------------------void __fastcall TForm1::Button1Click(TObject *Sender) { char frase1[]="DIAGONAL"; Label1->Caption = frase1; Label2->Caption = frase1[0]; Label3->Caption = frase1[1]; Label4->Caption = frase1[2]; Label5->Caption = frase1[3]; Label6->Caption = frase1[4]; Label7->Caption = frase1[5]; Label8->Caption = frase1[6]; Label9->Caption = frase1[7]; } //--------------------------------------------------------------Si Ud. cree que esto no es prctico estamos de acuerdo, los componentes de Windows no fueron pensados para problemas del tipo que nosotros nos hemos propuesto plantear, sino para ser utilizados en tareas prcticas que aplicaremos ms adelante. Una vez ms lo decimos, nuestro objetivo actual es aprender a resolver problemas y empezamos por los ms simples aunque no sean muy ingeniosos. Veamos algunos otros ejemplos, pero recuerde a cada momento

Que hacer cuando nada funciona.


El siguiente programa tiene dos botones y

81

El

Arte

de

Programar

dos cuadros de texto, el pulsado del boton izquierdo cambia el texto del cuadro izquierdo al derecho y el boton derecho hace lo contrario. //--------------------------------------------------------------#include <vcl.h> #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------#pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; char frase1[]="Este es el texto de la izquierda"; char frase2[]="Este es el texto de la derecha"; int largo; //--------------------------------------------------------------__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------void __fastcall TForm1::Button1Click(TObject *Sender) { Edit2->Text = frase2; Edit1->Text = frase1; } //--------------------------------------------------------------void __fastcall TForm1::FormCreate(TObject *Sender) { Edit1->Text = frase1; Edit2->Text = frase2; largo = strlen(frase1); 82

El

Arte

de

Programar

Edit1->Width = largo*6; Edit2->Width = largo*6; } //--------------------------------------------------------------void __fastcall TForm1::Button2Click(TObject *Sender) { Edit2->Text = frase1; Edit1->Text = frase2; } //--------------------------------------------------------------Para escribir este ejercicio pulse dos veces el botn derecho del ratn sobre la forma y le aparecer el procedimiento TForm1.FormCreate listo para que Ud. pueda escribir en el lo que necesite, en este caso hemos puesto todo lo necesario para escribir en los cuadros de texto. Adems hemos calculado el ancho width 42 que debe tener cada cuadro para poder contener el texto ms largo. Observe que hemos declarado las variables frases y la variable largo antes que cualquiera de las funciones justo debajo de la declaracin de FORM1 Previo a ello Ud. habr incorporado en la forma los dos cuadros de texto y los dos botones, el valor 6 lo hemos elegido para el tipo de letra Time New Romans tamao 12 si Ud. esta trabajando con otro tipo o tamao deber ajustar este valor. Los cuadros de textos son comodos para mostrar texto pero tambin para ingresar texto. Sobre los cuadros de textos pulse dos veces el botn izquierdo del ratn se abrir un procedimiento llamado 83

El

Arte

de

Programar

void __fastcall TForm1::Edit1Change(TObject *Sender)

para el caso del primer cuadro de texto colocado sobre la forma. Cada vez que nos posicionemos en el cuadro de texto y escribamos con el teclado el texto aparecer en el cuadro. pero adems se ejecutar la funcin El siguiente listado pertenece al ejercicio que estamos proponiendo En el figuran las funciones
void __fastcall TForm1::Edit1Change(TObject *Sender)

y
void __fastcall TForm1::Edit2Change(TObject *Sender)

que se activan T para la escritura cuando pulsamos dos veces sobre los cuadros de textos y adems el procedimiento correspondiente al pulsado de un botn.

84

El

Arte

de

Programar

Para armar este ejercicio elija dos cuadros de texto y un botn, luego escriba para cada una de las funciones los textos que se detallan a continuacin. Observe cuando lo ejecute que a medida que va escribiendo, el ancho del cuadro sigue el tamao del texto. Vamos a detenernos un momento a discutir char *cp1 = new char[ Edit1->Text.Length() + 1 ]; strcpy( cp1, Edit1->Text.c_str() ); mediante la primer sentencia lo que hacemos es mediante new reservar un espacio en memoria para guardar un texto capaz de soportar el texto que incorporemos en Edit1. La forma es hacemos el puntero a char cp1 declarado como char *cp1 igual al valor devuelto por el operador new tipo de la variable a guardar en memoria En este caso char[] y de largo igual al largo del texto de Edit1 +1 La segunda sentencia copia el contenido actual del cuadro de texto a este espacio de memoria., mediante la complicada expresin Edit1->Text.c_str() expresin que prometo solenmente explicar en ejercicios venideros. En resumen mediante estas dos sentencias podemos guardar en una variable para su posterior uso el contenido del cuadro de texto

85

El

Arte

de

Programar

Esto mismo se repite para el otro cuadro de texto. Estamos entonces en condiciones de manipular los textos contenidos en los cuadros a nuestra conveniencia. La tercer sentencia que figura en cada funcin de cambio permite ajustar el ancho de cada cuadro a la longitud del texto escrito. Recuerde que los nmeros por los que multiplica dependen del tipo de letra que Uds. estn usando. Finalmente en el procedimiento del botn usamos nuestras habilidades recin aprendidas para almacenar los textos en las variables cp3 y cp4 para su posterior intercambio entre cuadros al pulsar el botn. //--------------------------------------------------------------#include <vcl.h> #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------#pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------86

El

Arte

de

Programar

//--------------------------------------------------------------void __fastcall TForm1::Edit1Change(TObject *Sender) { char *cp1 = new char[ Edit1->Text.Length() + 1 ]; strcpy( cp1, Edit1->Text.c_str() ); Edit1->Width = strlen(cp1)*2 ; } //--------------------------------------------------------------void __fastcall TForm1::Edit2Change(TObject *Sender) { char *cp2 = new char[ Edit2->Text.Length() + 1 ]; strcpy( cp2, Edit2->Text.c_str() ); Edit2->Width = strlen(cp2)*2 ; } //-------------------------------------------------------------void __fastcall TForm1::Button1Click(TObject *Sender) { char *cp3 = new char[ Edit2->Text.Length() + 1 ]; char *cp4 = new char[ Edit1->Text.Length() + 1 ]; strcpy(cp3,Edit1->Text.c_str()); strcpy(cp4,Edit2->Text.c_str()); Edit1->Text = cp4; Edit2->Text = cp3; } //--------------------------------------------------------------

87

El

Arte

de

Programar

A continuacin le proponemos una serie de ejercicios para que resuelva. Estos ejercicios y los del capitulo anterior los resolveremos juntos en el capitulo 4 donde desarrollaremos un mtodo para aplicar a la resolucin de problemas en general. Mientras tanto use su ingenio para tratar de aplicar lo aprendido.Compare dificultades y parecidos y no titubee en copiar todo aquello que le parece que puede ser til.

88

El

Arte

de

Programar

EJERCICIOS Ejercicios 3.1


Repita el problema 3.2 pero modifique el tamao de la letra a 14, reduzca las frases a a la izquierda y a la derecha para que no tenga problemas de espacio.

Ejercicios 3.2
Declare dos variables string guarde en una una frase de tres palabras y en la otra una sola palabra. Ingrese dos cuadros de textos y un botn. Cuando se pulse el botn, la palabra deber insertarse entre la segunda y la primer palabra de la frase multipalabra

Ejercicios 3.3
Use 3 cuadros de textos y un botn. En los dos primeros ingrese dos frases que concatenara para ponerlas en el tercer cuadro cuando pulse el botn

Ejercicios 3.4
Use tres cuadros de textos y dos botones. Defina de manera diferente las propiedades de tamao de letra de dos de los cuadros. Luego pulsando cada uno de los botones transfiera las propiedades del primero o el segundo cuadro al tercero.

Ejercicios 3.5
Ingresar una frase en un cuadro de texto e ir eliminando la ltima palabra cada vez que se pulsa un botn.

89

El

Arte

de

Programar

90

El

Arte

de

Programar

4 BUCLES y COMPARACIONES
Hemos dicho que las computadoras son mquinas que cumplen tareas muy elementales pero que son tiles gracias a que permiten la ejecucin de tareas rutinarias sin equivocarse y realizar trabajos que al hombre le llevaran un tiempo muy superior a su existencia. La clave que permite que la computadora pueda hacer todo esto radica en que la actividad que desarrolla, la ejecucin secuencial de comandos, puede ser controlada y en caso necesario derivada a cumplir una secuencia diferente. As es posible entonces repetir una misma secuencia un nmero arbitrario de veces o elegir de acuerdo a un resultado una secuencia u otra. Es aqu dnde est el poder de la computadora. La posibilidad de decidir de acuerdo a un resultado parcial el camino a seguir, as por ejemplo evaluando un contador de eventos podemos saber si tal tarea debe seguir realizndose o debe suspenderse. Pero de dnde saca los datos para hacer la comparacin?. Obviamente del programa. y quin escribi el programa? Ud. Si la computadora para cuando no debe, o equivoca la secuencia correcta, es consecuencia directa de la comparacin que hizo, descartando la posibilidad de que la computadora haga mal los clculos; posible, pero en este caso los errores seran ms groseros y fciles de detectar, descartando decamos el error de clculo, la falla es porque el programa est equivocado. Vamos a estudiar en este capitulo, los bucles, estas son sentencias que permiten repetir un comando o secuencia de comandos un nmero determinado de veces y las sentencias condicionales, las que permiten ejecutar una sentencia u otra frente a una determinada situacin.

91

El
BUCLES

Arte

de

Programar

Veremos tres tipos de bucles que permite el lenguaje son ellos WHILE, DO WHILE y FOR.

La sentencia while Recuerda el programa 2.2 que escribia DIAGONAL? Comprelo con el siguiente modelo equipado con WHILE. Programa 4.1 char *letra,frase[8]="DIAGONAL"; int i = 0; main() { while (i < 8) { letra = frase[i]; i=i++; printf("%*c\n",i,letra); } gets(); } Empecemos por los parecidos, el parecido ms notable aparte del resultado, son las tres sentencias que habamos anunciado, slo es diferente la sentencia que le asigna valores a letra ya que ahora el valor que se cargar en letra ser el carcter que ocupe la posicin i en el string frase.

92

El

Arte

de

Programar

Las diferencia ms notable es el tamao del cdigo y las ventajas que presenta son innumerables, entre otras, la facilidad con que puedo modificar la palabra que deseo escribir, tc, tc. Analicemos ahora en detalle el programa principal: las tres sentencias que estn encerradas por las llaves {} ms internas forman un cuerpo, en este caso este cuerpo lo llamaremos una sentencia compuesta, la que se ejecutar while (mientras, en ingls) se cumpla la condicin de que i sea < (menor) que la longitud del string frase (strlen(frase)). Al comienzo del programa le hemos dado valores a las variables i y frase de manera que al comenzar WHILE i vale 0 que es menor que la longitud de frase por lo tanto se ejecuta lo que esta en el cuerpo de la sentencia compuesta. Se carga frase[0], la D, en letra, se incrementa i y lo escribimos en la pantalla con un espacio adelante. Un parrafo aparte merece la forma en la que hemos escrito i = i +1 el operador ++ es una de las caracterticas de C y como Ud. ya ha descubierto incremeta en 1 el valor de la variable sobre la que acta A continuacin volvemos a comparar i con la longitud de frase y por ser menor i volvemos a recorrer las tres sentencias pero ahora el valor de i es 2 y as sucesivamente hasta que no se cumpla la condicin. La clave de la repeticin o no de los comandos en el cuerpo de la sentencia WHILE es la evaluacin de la expresin encerrada entre parentesis que procede a la palabra reservada while. La evaluacin de esta expresin da como resultado un nuevo tipo de dato llamado booleano1.
1Por George Boole quin propusiera una lgebra que facilita el manejo de expresiones lgicas.

93

El

Arte

de

Programar

El tipo de dato booleano tiene slo dos valores CIERTO (true) o FALSO(false). De manera que si la evaluacin de la expresin es cierta, se cumple, se ingresa al cuerpo de la sentencia, sino la sentencia no se ejecuta y se continua con la primer sentencia que sigue a WHILE. Vamos a usar pr ahora la caracteristica que nos permite C de considerar el valor 0 como falso y 1 o mas como cierto

while (expresin) sentencia En el caso de tener que ejecutar ms de una sentencia dentro del bucle se deben reunir bajo un bloque mediante las llaves {}
while (expresion) { sentencia 1 sentencia 2 . . sentencia N }

. Los siguientes dos ejemplos muestran esto no sin cierto dramatismo. El primer ejemplo usa directamente el valor 0 por lo tanto es de esperar que la sentencia dentro de WHILE no se ejecute. Efectivamente si corre el programa aparece la pantalla de DOS sin nada escrito y esperando de acuerdo a la instruccin que se ejecut gets() que se pulse la tecla ENTER para continuar.

94

El

Arte

de

Programar

main() { while (0) ; gets(); } main() { while (1) ; gets(); } En el segundo ejemplo, SIEMPRE se va repetir la sentencia de escritura porque el valor es 1, de manera que Ud. ver al ejecutar el programa que este se repite, y, aqu est el drama que anunciamos, el teclado no responde. El bucle se repite una y otra vez sin solucin de continuidad. Bien, puede suspender la ejecucin pulsando la tecla indicada como Ctrl y mientras la mantiene apretada pulsar la letra c, o puede suspender la ejecucin de esta tarea cerrando de la manera usual la ventana de windows y aceptando el cartel de advertencia que aparece. Este segundo ejemplo es un caso extremo del llamado bucle infinito, una situacin no deseada y en la que se cae fcilmente si no se pone cuidado en la formulacin de la expresin de condicin o si como es demasiado habitual olvidamos modificar la variable que permite alcanzar la condicin de FALSO en el interior del bucle. Veamos esto detenidamente debido a su importancia; para que el bucle termine es necesario que la variable que va a permitir la condicin de FALSO se modifique en el interior del bucle y que alguna vez por lo menos, tome el valor de terminacin, es el caso de i en el ejercicio DIAGONAL. Veremos cuando avancemos en el uso de Builder como lenguaje visual que la recuperacin de un bucle infinito muchas veces deber hacerse deteniendo el equipo

95

El

Arte

de

Programar

Observe que al no tratarse de una sentencia compuesta la que debe ejecutarse con WHILE no hay llaves pero no se debe omitir el ; corra los programas y note los mensajes que le enva el compilador en un caso y otro (me refiero con y sin ;). En programacin es til disponer de diagramas que permiten visualizar rpidamente la secuencia de un programa. El ms viejo y en general no en uso es el diagrama de flujo, sin embargo la representacin de las sentencias que estamos estudiando en este captulo se hace con diagramas de flujo porque ilustran muy bien la bifurcacin que introduce el alcanzar el valor que hace FALSA la condicin, por eso lo incorporamos en la pgina siguiente. Lo ltimo que diremos con respecto a WHILE es pedirle que analice el siguiente programa y deduzca antes de correrlo que hace y que luego escriba otro que repita lo que hace el programa 2.4.

Programa 4.2 char frase[40]; int L,N; main(){ printf("%s\n","Ingrese una frase"); gets(frase); N=0; L=strlen(frase); while (N < L) { printf("%c%c",frase[N],'-'); N=N++; } gets(); } 96

El

Arte

de

Programar

Expresin ?
SI

NO

Sentencia

La sentencia while

97

El

Arte

de

Programar

La sentencia if Alguna vez se ha preguntado como sabe Ud. que un nmero es par o impar. No se enoje no dudo de que si, pero busco centrar su atencin sobre el hecho que para conocer esto es necesario dividir el nmero por dos y ver si hay o no resto. Esto del resto es tan importante en el mundo de las computadoras que hasta tenemos un operador especial para realizar una divisin y enterarnos si hubo o no resto. El operador de marras en C llamado modulo est representado por el simbolo %. El siguiente ejercicio muestra justamente usando el operador modulo los dos tipos de sentencias de comparacin if y if ... else Programa 4.3 char letra[30]; comparador(){ if (strlen(letra)%2 == 0) printf("%s","La longitud de la palabra es par"); else printf("%s","La longitud de la palabra es impar"); } main(){ printf("Ingresa una palabra:\n"); gets(letra); if (strlen(letra)!= 0) comparador(); gets(); }

98

El

Arte

de

Programar

Expresin > 0
SI

NO

Sentencia

Sentencia if

SI

Expresin > 0

NO

Sentencia 1

Sentencia 2

Sentencia if ... else


99

El

Arte

de

Programar

Del ejemplo y de los diagramas se puede inferir que la sentencia if se usa para aquellos casos en que la ejecucin de una sentencia tiene condicionada su ejecucin al cumplimiento de una determinada condicin evaluada por la expresin entre parentesis. Mientras que if ... else se usa para celebrar la ejecucin de una de dos sentencias de acuerdo al cumplimiento o no de una condicin. if ( <condicin> ) < sentencia>; if ( <condicin> ) <sentencia1>; else <statement2>;

U Para entender los ltimos ejercicios que mostraremos en este captulo es necesario que le explique lo siguiente:
Sintaxis de una expresin Booleana Como se muestra a continuacin, son seis los smbolos posibles para comparar dos expresiones simples y obtener como resultado Falso o Cierto. Las dos expresiones simples que se comparan deben ser del mismo tipo en los ejemplos por el momento int o char: == Igual

!= No igual < Menor que > Mayor que <= Menor o igual que >= Mayor o igual que
100

El

Arte

de

Programar

En los dos ltimos es esencial que el signo = aparezca despus del corchete oblicuo. Se puede combinar dos o ms expresiones booleanas mediantes los conectivos lgicos (OR) || y (AND) &&. Por ejemplo si X=1, W=2, Y=3, Z=4 la expresin : (X > 0) || (Y > 10) Evala como cierto porque X es mayor que cero a pesar de que Y no es mayor que 10 . La expresin ser Cierto cada vez que cualquiera o ambas de las expresiones vinculadas con || sea cierta, en el nico caso que evaluar como falsa es cuando ambas expresiones sean falsas. En forma similar: ((X W) < 0) && ((Z X ) > 0) Evala como cierto porque ambas expresiones vinculadas por el operador && lo son. Si cualquiera de las expresiones fuese falsa la expresin compuesta evaluara como falsa. Volveremos sobre este tema porque es fundamental. El siguiente muestra el uso de las expresiones booleanas Programa 4.4

char *ptr,*nespacios,letra[2],frase[80];
/*Definimos una funcin que elimina la primer palabra mediante el simple expediente de apuntar el comienzo del string un caracter mas de dnde esta el espacio*/

101

El

Arte

de

Programar

recortador(char *p){
/*El siguiente bucle while disminuye el puntero hasta encontrar un espacio y si no hay ms espacios sigue hasta el principio de la frase*/

while ((*p != ) && (p!=frase)) p; *p=\0'; //elimina la palabra que sigue al espacio } main() { strcpy(frase,que interesante el tema tratado); while (strlen(frase)!= 0){//mientras hay caracteres printf(%s\n,frase);//imprime el contenido de frase ptr = frase + strlen(frase);//prepara el puntero al final de frase recortador(ptr); } gets(); }

102

El

Arte

de

Programar

La sentencia for La sentencia while, y su compaera la sentencia do while que estudiaremos ms adelante pueden usarse en cualquier tipo de bucle que se nos presente. La sentencia for se incorpor para un tipo de bucle que ocurre tan frecuentemente que justifica el tener una sentencia especial que simplifique su control. Muy a menudodiseando un programa uno necesita una forma simple de poder hacer las siguientes dos cosas: Repetir una sentencia un determinado nmero de veces Que una determinada variable se incremente (o disminuya en una unidad ) en cada repeticin

Por ejemplo Ud. quiere que una determinada variable k tome todos los valores de la siguiente progresin uniforme: 1,2,3,4,5,6,7,8,9,10 y para cada valor se ejecute una sentencia la sintaxis del bucle for es: for (k = 0; k < 10; k++) sentencia y si esta fuese compuesta el comando debiera ser igual, solo que deben aparecer los limitadores de cuerpo{} En muchos de los problemas con strings deseamos controlar cada carcter que lo forma para saber si cumple una determinada condicin. Por ejemplo si deseamos contar el nmero de vocales que figuran en el string en tal caso podemos crear una variable entera k que tome todos los valores desde 1 hasta strlen(string) y cada vez incrementamos un contador si el carcter es una vocal en caso contrario no. Los dos ejemplos que siguen ilustran el uso de la sentencia for

103

El

Arte

de

Programar

Programa 4.5

//programa cuenta_vocales; char vocales[11],frase[80]; int k,cuenta; main(){ strcpy(vocales,"aeiouAEIOU"); printf("%s\n","Por favor ingrese una frase y luego pulse ENTER:"); gets(frase); cuenta = 0; for (k = 0; k < strlen(frase); k++) if (strchr(vocales,frase[k]) != 0) cuenta++; printf("%s %d ","La cantidad de vocales en la frase es: ",cuenta); gets(); } Programa 4.6 //programa alreves; char palabra[30]; int k; main() { printf("%s\n","Por favor ingrese una palabra y luego pulse ENTER"); gets(palabra); for (k = strlen(palabra); k >= 0; k--) printf("%c",palabra[k]); gets(); } 104

El

Arte

de

Programar

Resumiendo y en forma general for (expresion 1; expresion 2; expresion 3)


sentencia;

Inicialmente se ejecuta expresion 1 con esto se nicializa


algn parmetro que controla la variable del bucle

expresion 2 es una condicin que debe ser cierta para que se


ejecute la sentencia.

expresion 3 se utiliza para modificar el valor del parmetro El bucle se repite mientras expresion 2 no sea cero (falso)
Adems

Si sentenciaI es compuesta se encierra entre { } exprensin 1 y expresin 3 se pueden omitir Si se omite expresion 2 se asumir el valor permanente
de 1 (cierto) y el bucle se V ejecutara de forma indefinida

En la prxima pgina podr encontrar el diagrama de flujo de esta sentencia.


Pero antes de analizar el bucle do while permitame desarrollar un tema muy importante para lo que Ud. est aprendiendo. Si no se la ha formulado ya pronto se preguntar como sabe la computadora cuando se trata del nmero 65 o de la letra A . Preste atencin estoy a punto de explicarselo con fina dedicacin. No lo sabe. Y no podr saberlo nunca, no tiene como, hemos convenido que la mquina no tien ms inteligencia que la que puede tener la piedra del mineral de silicio de dnde se saca gran parte de la materia que la constituye. Es Ud. o en todo caso el compilador con la informacin que Ud. le da el que sabe si este 65 debe ser interpretado como nmero o como letra.

105

El

Arte

de

Programar

Expresin 1

Expresin 2 > 0
SI

NO

Sentencia

Expresin 2

La sentencia for

106

El

Arte

de

Programar

La computadora slo maneja nmeros en realidad en su interior slo procesa ceros y unos. No es mi intencin agobiarlo ahora con los detalles de porque y como la computadora se las arregla con los ceros y los unos pero si de contarle que las letras, para la computadora, son nmeros. Un cdigo es una representacin de ciertos smbolos mediante la combinacin de otros. As por ejemplo el cdigo ASCII (se pronuncia (asquii)) representa los caracteres alfanumricos mediante nmeros, la A es el 65, la B el 66. Dejo a su inteligencia la deduccin de cuales son los nmeros que representan a las otras letras. Si no lo hizo el siguiente programa los listar para Ud. Lo aprendido hasta ahora debe permitirle leer el programa sin dificultad al slo efecto de estar seguro permtame que lo acompae. Primero revisemos la los argumentos de printf() y descubriremos que el formato es : %3d = %c\t A este formato le corresponde el siguiente listado de argumentos: k,k Le recuerdo que en la pgina 36 habamos trabajado con cierto detalle sobre esto. Si revisamos el formato descubriremos que n debe ser el argumento para %3d y esto significa que la variable k debe imprimirse como nmero usando no ms de 3 lugares a continuacin se imprimir luego de un espacio el signo = y otro espacio %c y nuevamente el argumento para este especificador de formato es k.

107

El

Arte

de

Programar

int k; main() { for (k = 1; k < 256; k++) printf("%3d=%c",k,k); gets(); } Y esto? Es la confirmacin de lo dicho. Un variable es un lugar de memoria con un nombre y una capacidad de almacenamiento en Bytes recuerda? 8 bits. La tabla que el programa imprime simplemente nos esta diciendo, que por ejemplo, el nmero 65 tambin es la letra A. Cul es el valor correcto?. Los dos, el programa en cuestin escrito por Ud. mediante las funciones y operadores que use van a determinar com se consideren. Volveremos sobre esto luego. Le W sugiero si quiere ver en detalle algunos de los nmeros bajos que elija un valor menor para expresin 2 por ejemplo 40. Algunos caracteres parecieran no tener significado. El 7 es la campanilla y no tienecaracter que lo represente el 10 es nueva lnea (Ya se haba dado cuenta verdad) y el 13 es el retorno de carro (El ENTER si lo prefiere). Si Ud. es de lo nuestro estoy seguro que ya prob algo como lo siguiente. Programa 4.8 int k; main() { for (k = 1; k < 5; k++) printf("%c",10); gets(); } 108

El

Arte

de

Programar

La sentencia do-while La forma general de la sentencia do-while es la siguiente

do
sentencia;

while (expresin)
sentencia se ejecutar mientras expresin sea cierta sentencia siempre se ejecuta al menos una vez (diferente a
while.)

(distinta de cero)

Si sentenciaI es compuesta se encierra entre { } Es parecida a la sentencia while solo que el control de la expresin que determina la repeticin o no del bucle se hace despus de ejecutar las sentencias que representan las acciones a repetir. Esto significa que la sentencia do-while permite la ejecucin de las sentencias involucradas en el bucle al menos una vez. Mientras que en la sentencia while puede ocurrir que nunca se ejecute el bucle, si al evaluarse la primera vez la expresin de control da como resultado false.
Programa 4.9 char f[30]; int l,n; main(){ printf("Escriba una palabra o frase seguida de ENTER:\n"); gets(f); n = 0; l = strlen(f); do { printf("%c\n",f[n]); n++; } while (n<l); gets(); }

109

El

Arte

de

Programar

Sin embargo el caso ms comn es la evaluacin de la expresin al principio de manera que la mayor cantidad de casos se resuelven mediante la sentencia while.
Le recomendamos una cuidadosa revisin del apndice A para una mejor comprensin de las variables boleanas y su uso en los distintos bucles en particular bajo el uso de de la sentencia de comparacin if.

110

El

Arte

de

Programar

5 EL ARTE DE RESOLVER PROBLEMAS

Estamos en condiciones finalmente de comenzar a aplicar tcnicas que nos permitan sistematizar la solucin de problemas. Para ello vamos a tomar algunos ejercicios ya hechos y propondremos algunos nuevos, muchos de ellos gracias a la invalorable colaboracin del Ingeniero Pablo Moliterno. Vamos a someter cada problema a un proceso que incluye:
Identificacin. Definicin Estrategia. Solucin. Optimizacin de la solucin.

En general reconocemos la presencia de un problema cuando la situacin deseada difiere de la situacin actual. identificar el problema permite justamente establecer las dos situacines en forma expresa mientras que definirlo permite formularlo, decir que es lo que hay que hacer. A partir de la definicin podemos generar la estrategia que nos llevar a su solucin, esto es, alcanzar la situacin deseada. No hay una nica solucin y es conveniente revisar algunas de las encontradas para mejorar la eficiencia esto es proceder a la optimizacin.

111

El

Arte

de

Programar

Muchos de los problemas que vamos a resolver tiene una formulacin expresa, es decir la causa que separa la situacin de problema resuelto, de la situacin problema planteado, esta explicita, sin embargo en general puede que esta formulacin identifique el problema pero no lo defina correctamente. Definir correctamente un problema permite encontrar la estrategia que lleve a su solucin por el camino ms corto o por el ms eficiente. De hecho veremos que la optimizacin es mucha veces el probar soluciones alternativas sugeridas por definiciones diferentes a un mismo problema. Vamos a explicar todo lo expuestos mediante ejemplos suficientementes comentados a lo largo de la solucin. Supongamos que queremos que en la pantalla aparezca escrita una frase varias veces y cada vez que se escribe se hace sin la ltima palabra de la ltima vez que fue escrita Por ejemplo: Esta es una frase suficientemente completa para este ejemplo Esta es una frase suficientemente completa para este Esta es una frase suficientemente completa para Esta es una frase suficientemente completa Esta es una frase suficientemente Esta es una frase Esta es una Esta

112

El

Arte

de

Programar

El primer paso es identificar el problema Para ello veamos si podemos reconocer una situacin deseada y una actual. No parece sencillo de expresar a pesar de que nos parece que es obvio lo que hay que hacer.
Sin embargo si nos forzamos a descomponer el problema en partes podemos reconocer analizando las dos primeras frases escritas, una situacin actual: la frase escrita.Y una situacin deseada: la frase escrita sin la ltima palabra. Tenemos un problema identificado que es una parte del problema inicial. Es decir el problema inicial es un problema compuesto, que admite la descomposicin en un problema ms simple que es la impresin de la primer frase sin la ltima palabra. Esto repetido una y otra vez hasta que no haya mas palabras en la frase, constituye el problema compuesto. Si encontramos la solucin para las dos primeras frases. Encontramos la solucin para el problema compuesto repitiendo la que encontramos para las dos frases hasta que no haya mas palabras en la frase. Esta es una de las estrategias ms poderosa para resolver problemas, descomponerlos en partes ms simples. Claramente entonces nuestro problema es detectar y eliminar la ltima palabra. El hecho de imprimir la frase es considerado de solucin trivial y por lo tanto no requiere de ninguna elaboracin.

El siguiente paso es definir el problema. lo vamos a hacer as: 113

El

Arte

de

Programar

Dada una frase que contiene varias palabras, escribirla una y otra vez dejando en cada nueva oportunidad, de escribir la ltima palabra escrita en la oportunidad anterior hasta que no haya ms palabras.

Definido el problema se trata ahora de encontrar la solucin. Para nosotros es fcil identificar la ltima palabra y omitir su impresin, pero para un programa de computadora el problema puede no ser tan simple. Y nuestra estrategia para resolver el problema deber ceirse a lo que puede hacer la mquina por eso es que fu necesario practicar algunas tcnicas de programacin antes de encarar un mtodo sistematizado de resolucin de problemas mediante computadoras. Ahora sabemos por ejemplo que podemos identificar la presencia de un espacio en un string. Es ms, sabemos que una frase ser considerada en la mquina como un string. Sabemos tambin que podemos recorrer el string caracter por caracter, de atrs para adelante y de adelante para atrs. De manera que nuestra estrategia ser recorrer el string (la frase ) de atrs para adelante caracter por caracter y al encontrar un espacio borraremos desde esa posicin hasta el final todos los caracteres y a continuacin imprimiremos la frase. Esto soluciona el problema simple pero el problema compuesto requiere de la repeticin de esta solucin mientras hayan palabras en la frase. 114

El

Arte

de

Programar

Hay una ltima cosa que analizar antes de proponer un programa que resuelva lo planteado. y es que ocurre si la frase es de una sola palabra. O dicho de otra manera no hay espacios. En ese caso se debe eliminar el string completo e imprimir una linea en blanco o a los efectos del que observa en la pantalla. El siguiente programa es el resultado directo de todo lo dicho: Programa 5.1 int i; char frase[80]; recortador() { frase[i]='\0'; i--; printf("%s\n",frase); } main(){ strcpy(frase,"Esta es una frase bastante completa para este ejemplo"); i= strlen(frase); printf("%s\n",frase); while (i > 1) { if (frase[i]==' ') recortador(); 115

El else i--;} gets(); }

Arte

de

Programar

Recorramos juntos la solucin encontrada. El bucle while permitir recorrer el string desde el final al principio para ello inicializamos la variable de control con el valor de strlen(frase). En cada instancia si el caracter es un espacio llamamos a recortador que es la funcin que elimina la ltima palabra else (sino) disminuimos i en una unidad y volvemos a recorrer el bucle. Vamos a aplicar nuestras habilidades recin adquiridas para revisar cada uno de los problemas dejados al final de los captulos 2 y 3 para que Ud. los resolviera. Problema 5.2 resolver el Problema 2.1 El listado que sigue tiene removidos los errores sintcticos y de la lectura del mismo est claro que semejante algoritmo jams podr dibujar el tringulo de Xs. Programa Piramide ; char f[20], xf[10], x2[10]; int N ; main(){ strcpy(f," "); // 10 espacios strcpy(x2,"XX"); strcpy(xf,"X"); strcat(f, x2); 116

El

Arte

de

Programar

printf("%s\n",f); strset(f,'X'); strcpy(f,f+1); printf("%s\n",f); gets(); } Siguiendo nuestras recomendaciones para resolver problemas debemos primero identificarlo. Aqui se necesita que el programa haga lo que se supone que debe hacer y no lo que esta haciendo. Recordemos de paso que la figura eran 4 lineas de Xs presentando 1,3,5 y 7 de ellas dejando centradas las de la lnea superior sobre la que le sigue. Sin embargo al ejecutar el programa resultante se obtienen 2 lneas de X. Una en la primera, y 11 en la segunda El trabajo propuesto, leer el cdigo para entender que es lo que hace el programa sin correrlo en la computadora es el ejercicio ms importante para desarrollar la habilidad de pensar y para conseguir depurar el programa de errores por eso nadie lo hace. Se llama en la jerga de computacin La prueba de escritorio y vamos a hacerla a continuacin en la esperanza que Ud. adquiera un sano hbito si realmente quiere disfrutar la escritura de programas de computacin. El proceso incluye la lectura de cada lnea y anotando que es lo que esta hace. Aqu resulta evidente que las tres primeras lneas inicializan las 3 variables string, la cuarta concatena los 10 espacios con las 2 Xs y la quinta imprime el resultado. Luego se obliga a poner en cada posicin de este 117

El

Arte

de

Programar

string de 11 elementos una X y se procede a imprimir este resultado. El valor de N nunca ha sido inicializado ni ha sido usada. Es posible tratar de entender cual era la intencin del programador y volver sobre el programa para tratar de que funcione bien. O lo que es ms recomendable, identificamos problema lo definimos y lo solucionamos con nuestro mtodo. El programa sin los errores de sintxis sera el siguiente. De nuevo estamos ante un problema compuesto ya que esta claro que cada vez que imprimimos una nueva lnea imprimimos 2n-1 Xs siendo n el nmero de lnea que imprimimos. Si Ud todava no hizo la cuenta fijese que imprimimos 1,3,5,7 Xs Puesto en otras palabras cada vez que imprimimos una lnea le ponemos 2 Xs ms, una antes y otra despus de las Xs impresas en la lnea anterior. De manera que el problema a resolver es: imprimir dos X ms en cada mueva lnea una antes y otra despus Guau! Y eso como se hace? Fcil le agregamos las dos Xs y luego ante de imprimir tiramos hacia atrs un lugar la siguiente lnea Y eso como se hace? As. programa Piramide 118

El

Arte

de

Programar

char f[20], xf[10], x2[10]; int N = 1; main(){ strcpy(f," "); // Preparamos los10 espacios strcpy(x2,"XX");// Preparamos las 2X a agregar
// Preparamos e imprimimos la primer lnea

strcpy(xf,"X"); strcat(f, xf); printf("%s\n",f);


// Y ahora repetimos hasta teminar

while (N < 4){ strcat(f,x2); strcpy(f,f+1); printf("%s\n",f); N++;} gets(); } Problema 5.3 resolver el Problema 2.2 La solucin sugerida aunque mal resuelta propone la bsqueda de un string dentro de otro, pero al igual que el anterior vamos a partir de cero e identificaremos el problema en primer trmino. Tener una frase impresa claramente separada en dos tramos, ocupando cada tramo una lnea diferente sin perder la ubicacin relativa respecto de la frase original.

119

El

Arte

de

Programar

Esto lleva a la siguiente definicin Dividir una frase en dos tramos a partir de una de las palabras e imprimir los dos tramos manteniendo en ambos casos la longitud de la frase y la posicin relativa de los caracteres significativos. La estrategia se plantea a partir de una dinmica que consiste en ir proponiendo posibles aplicaciones de tareas que sabemos la computadora puede realizar facilmente: Por ejemplo duplicar la frase pareciera que sera un buen paso para posteriormente identificar la palabra pivote en cada copia y adoptar en cada caso la tarea que lleve a imprimir lo que se desea en cada una. La primer frase, aquella que imprime las primeras palabras es de solucin casi trivial, escribir un null en el espacio que precede a la palabra pivote. En la segunda copia la tarea es ms compleja ya que hay que llenar de espacios las letras de la ahora, primera copia y dejar el resto sin alterar. Pareciera entonces que la solucin para esto ltimo pasa por llenar la primera copia de espacios y luego concatenar a esta copia la segunda copia a partir del puntero de la palabra pivote. Si Ud. esta perdido o cansado de tratar de entenderme, !Que bueno Yo estoy seguro que debiera ser as. Voy a confiar en que la revisin que hace la Ing. Arnoldo de mi textos garantice la correcin de lo explicado. Pero el comentario de, !que bueno, es porque ha caido en la cuenta que debe haber una mejor forma de hacer esto con lo cual le van a encantar Diagramas Estructurados , tema del prximo captulo y ah va a aprender a detallar las tareas a realizar en forma ordenada y a producir el ajuste de un diagrama mediante el refinamiento progresivo.

120

El

Arte

de

Programar

Mientras tanto critiquime esta solucin: char *ptr, frase1[80], frase2[80], pivote[15]; main(){
// Concretamos la frase a dividir y la imprimimos

strcpy(frase1,"Habia una vez cierto muchachuelo que solia visitar..."); printf(frase1); printf("\n");
//Armamos el pivote y encontramos el puntero

strcpy(pivote,"muchachuelo");// ptr = strstr(frase1,pivote); strcpy(frase2,ptr); //copiamos la parte final de la frase1


//acotamos la primer frase y la imprimimos

frase1[ptr-frase1]='\0'; printf("%s\n",frase1);
// preparamos la segunda frase a partir de llenar de espacios a frase1

strset(frase1,' '); strcat(frase1,frase2);// Armamos la frase y la imprimimos printf("%s\n",frase1); gets(); } Problema 5.4 resolver Problema 2.3 identificacin: escribir un nombre comenzando por el apellido y terminando por el nombre despes de una coma. definicin: escribir un nombre comenzando por el apellido ubicado despes del punto seguido por los nombres que constituyen la primera parte despes de una 121

El coma;

Arte

de

Programar

estrategia: ubicar el punto en el string fijar el puntero copiar el apellido concatenar una coma y luego la primera parte del string que separamos en el momento de encontrar el punto. solucin: char fuente[80], destino[80],patron[2]; char *posicion; main(){ strcpy( fuente,"Maria C. Gomez");//puede ser cualquier nombre strcpy(patron,"."); posicion = strstr(fuente,patron); fuente[posicion-fuente]='\0'; strcpy(destino,posicion+2); strcat(destino,", "); strcat(destino,fuente); printf(destino); gets(); }

122

El

Arte

de

Programar

6 DIAGRAMAS ESTRUCTURADOS

Un diagrama estructurado es una grfica similar a un rbol genealgico. En ciencias de la computacin se conocen justamente como rboles. El rbol tiene una sola raz, de ella nacen ramas, algunas de las cuales se subdividen a su vez en otras ramas. Al final de cada rama hay una hoja. A los puntos de ramificacin y a las hojas se le llaman nodos. Las hojas son nodos terminales toda vez que ellas estan al final de un cierto recorrido desde la raz a lo largo de un determinado sistema de ramas. El rbol presenta su raz en el tope del diagrama lo que si bien viola la leyes naturales no molesta para el uso que nosotros le queremos dar. Esta es una observacin no muy importante pero puede ayudar a no confundirse al principio. Hay solamente un recorrido que lleva desde la raz a una nica hoja y viceversa. No existen atajos que lleven de una hoja a otra. Los nodos hojas pueden aparecer en cualquier nivel. Esta estructura es til para representar un algoritmo. Recordemos que el algoritmo es el listado de acciones que nos llevaran a la situacin deseada. Esto es vamos a solucionar el problema aplicando una a una las acciones indicadas en el algoritmo. 123

El

Arte

de

Programar

El diagrama estructurado es en cierta forma un medio para aplicar el mtodo que propusimos en el capitulo anterior para resolver problemas. Vamos a mostrar el uso de los diagramas estructurados resolviendo los prximos problemas formulando los algoritmos mediante estos diagramas. Para ello debemos decir que el orden de acuerdo al cual se realizan las acciones indicadas en los nodos hojas es de izquierda a derecha. Y dado que las acciones a cumplir sern las que son posibles para la econocer computadora, deberemos ser capaces de r nodos hojas que indiquen la eleccin entre acciones a seguir (sentencia condicional), la repeticin de una determinada accin (bucles) y la particular necesidad del lenguaje que estamos usando de agrupar sentencias simples en una sentencia compuesta.

INICIO

BUCLE

COMPARAR

COMPUESTA SIMPLE

124

El

Arte

de

Programar

Un ltimo comentario, la realizacin del diagrama es un proceso que acompaa a la bsqueda de la solucin y por ello es un proceso que requiere de sucesivos refinamientos, cada uno dar lugar a un nuevo diagrama mas elaborado que el anterior. Esto se conoce como Refinamiento progresivo Estamos en condiciones de comenzar, para ello permtame definir las herramientas y el ambiente a usar. Como hemos dicho aprovecharemos los recursos que nos ofrece la interfase grfica. En particular en este caso usaremos uno de los objetos. El Canvas

La traduccin de canvas es lienzo. Este es el nombre que le damos al recubrimiento de la placa representada por form, en este lienzo se puede, pintar, dibujar, escribir etc, etc. a partir de un punto que llamaremos posicin actual o punto de accin. Nosotros vamos a usar por ahora dos funciones. MoveTo() y LineTo() ambos requieren de dos argumentos, el par de coordenadas que indican a que punto del lienzo me estoy moviendo en el caso de MoveTo() y el punto del lienzo hacia donde voy a trazar una linea partiendo de la actual ubicacin, en el caso de LineTo().

125

El

Arte

de

Programar

El sistema de coordenadas que sirve para referenciar la accin a ejecutar en el canvas tiene su origen en la parte superior izquierda. El eje x se extiende en forma positiva hacia la derecha y el y hacia abajo, las coordenadas del origen son obviamente (0,0). (0,0) X

El siguiente listado muestra el uso de estas dos sentencias void __fastcall TForm1::Button1Click(TObject *Sender) { Canvas->MoveTo(50,100); Canvas->LineTo(100,100); Canvas->MoveTo(100,100); Canvas->LineTo(100,150); } Preste atencin que en el listado anterior solamente hemos mostrado el procedimiento que es ejecutado al pulsar el botn. Observe en particular que cada sentencia es precedida por la palabra canvas un guion y el signo mayor. Esto es imprescindible cada vez que llamemos a una 126

El

Arte

de

Programar

sentencia que forma parte de un objeto. Es importante destacar que mientras moveto() realmente traslada el punto de accin al par XY lineto() dibuja la linea entre el par de coordenadas dado en la sentencia y la actual ubicacin del punto de accin. La figura que aparece en la pantalla es similar a la siguiente.

Problema 6.1. Escribir un procedimiento que permita dibujar un cuadrado X sobre el lienzo dado la longitud de su lado. El problema esta perfectamente definido sin embargo vamos a utilizar nuestras herramientas de anlisis para revisar el problema y tratar de encontrar soluciones adecuadas. Por lo pronto el problema admite ser descompuesto en partes. Usando un diagrama estructurado aparecera la siguiente grfica que puede parecer trivial, pero que sin embargo nos ayudar a encontrar la mejor solucin
cuadrado

dibujar lado 1

dibujar lado 2 dibujar lado 3

dibujar lado 4

127

El

Arte

de

Programar

Desarrollemos ahora cada una de las tareas del primer nivel empezando por Dibujar el lado 1

dibujar lado1

Posicionarse en el inicio

Trazar la lnea Dibujar la lnea

Calcular coordenadas del otro extremo

En cada nueva etapa que se va alcanzando es conveniente comparar la tarea que se debe realizar con la que hace la computadora cuando se encuentra que ambas coinciden, paramos. Este es el caso de Dibujar la lnea, el comando LineTo() con las coordenadas que hemos calculado en Calcular coordenadas del otro extremo cumple la tarea. En el caso de Posicionarse en el inicio con MoveTo() lo hacemos Analicemos ahora el clculo de coordenadas, en este punto debemos recordar algunos

128

El

Arte

de

Programar

conceptos de trigonometra. En efecto la siguiente grfica ilustra como es posible a partir del ngulo que forma el lado con la vertical calcular las coordenadas del vrtice opuesto al comienzo del primer lado.

X (X,Y) Y X Y Y es fcilmente visible que las nuevas coordenadas salen de : X1 = X + L * sin Y1 = Y + L * cos Correspondera ahora continuar con el lado 2 y as sucesivamente. Sin embargo el diagrama y nuestra intuicin nos esta mostrando que hay un proceso repetitivo de manera que analicemos un poco ms esto. En efecto en el caso de todos los lados el proceso es el mismo Debiramos buscar una variable que nos permitiera contar el nmero de veces que debemos repetir el proceso, proceso, esta sin duda, puede ser un contador de 1 hasta n con lo que pareciera inclusive que con for solucionaramos el problema. 129 L

(X1,Y1)

El

Arte

de

Programar

Debemos revisar ahora qu parmetro vara de iteracin a iteracin, y si prestamos atencin, nuestro parmetro variable es el ngulo que se incrementar cada vez en el valor de 2 dividido 4. entonces nuestro diagrama final es:
Cuadrado

Desde n=1 hasta 4

Posicionarse en el inicio

Trazar la lnea

Calcular coordenadas del otro extremo

Dibujar la lnea

El programa que sigue cumple con el algoritmo, Dejamos al lector el anlisis de las expresiones usadas para el clculo de las coordenadas. Excepto ceil que aparece en las expresiones. Este es el operador que nos transforma los valores reales que nos entregan las funciones trigonomtricas en valores enteros que necesitan las funciones MoveTo() y LineTo(). Ud. perpicaz debe adems haber descubierto a camuflado como M_PI
// #include <math.h> #include <vcl.h> #pragma hdrstop #pragma hdrstop #include Unit1.h // #pragma package(smart_init) #pragma resource *.dfm TForm1 *Form1;

130

El

Arte

de

Programar

// __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } // void __fastcall TForm1::FormMouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { /* first call FillRect to paint the surface of the form. this removes any previously drawn lines (and anything else!) */ Canvas->FillRect(ClientRect); Canvas->MoveTo(0, 0); Canvas->LineTo(X, Y); } // void __fastcall TForm1::Button1Click(TObject *Sender) { int x,y,l,i; x = 100; y = 100;//coordenadas del comienzo l = 200;//longitud del lado; for (int i = 0; i < 4; i++) { Canvas->MoveTo(x,y); //posicionarse en el inicio x = x + ceil(sin(2*M_PI*i/4));//calculo de las coordenadas y = y + ceil(l * cos(2*M_PI*i/4));//del otro extremo Canvas->LineTo(x,y);// dibujar la linea } } //

Se acostumbra a diferenciar los distintos niveles mediante nmeros y letras en forma alternada pero vamos a dejar esto para explicarlo a medida que en los prximos captulos apliquemos lo que hemos aprendido.

131

El

Arte

de

Programar

132

El

Arte

de

Programar

7 Arreglos
Existe un tipo de datos que es diferente a los vistos hasta ahora y que se presenta a menudo en muchos problemas de la vida real. Tal vez la forma ms simple que adopta este tipo de dato es la de una secuencia de objetos segn un cierto orden. Para cada objeto no slo es necesario describirlo sino que adems debemos precisar el orden que ocupa en la secuencia (primero, segundo, etc. etc.). Para cada dato se debe decir que es y en donde se ubica con referencia a los otros datos que lo acompaan en la secuencia. La respuesta a que es, es la misma para cada uno de ellos. Es decir todos los datos son del mismo tipo. La respuesta a dnde esta? es en general un conjunto de nmeros que permite ubicar su posicin con referencia a los otros. El nombre que se le da a este tipo de datos es el de Arreglo y en el caso particular que solamente haga falta Y un nmero para ubicarlo hablamos de vectores. Ya hemos usado vectores en este libro. Lo hicimos cuando hablamos de string. Para poder referenciar una letra del string usbamos el nombre del string y un nmero para indicar su posicin con referencia a las otras letras as frase[1] era la primer letra del string frase y frase[4] la cuarta. De manera que los strings son vectores. La cardinalidad del vector es el entero que denota la cantidad de objetos del mismo tipo que lo constituyen . Por lo tanto para cada objeto de un vector de cardinalidad n hay un tipo, el mismo para cada uno de ellos y un nmero de 1 a n, su indice, que indica su posicin. En trminos generales podemos decir entonces que cada vez que necesitamos elegir un determinado item de un grupo de elementos del mismo tipo

133

El

Arte

de

Programar

usaremos un arreglo. Si el orden basta con que sea lineal tendremos un vector y bastara solamente un ndice para indicar su posicin. Si la posicin de los items sigue un disposicin segn un plano o un espacio necesitaremos dos, tres,... n ndices y estaremos frente a arreglos de dos, tres ,... n dimensiones. Los Arreglos y el Hardware En el capitulo que hicimos referencia a los punteros dijimos que cada tipo de variable tena una forma diferente de ser almacenada en memoria. Que el nombre dado a la variable era el nombre de la locacin de memoria que almacenaba el dato y que esta locacin de memoria sera de un byte, dos bytes etc. etc. En el caso particular de un arreglo el nombre dado al arreglo ser el nombre dado a un conjunto de locaciones de memoria agrupadas de acuerdo al tipo de datos de los componentes del arreglo y numeradas de acuerdo a la posicin de cada uno de ellos. As por ejemplo un string ocupara un rea de memoria donde cada letra ocupar un byte y cada uno de los bytes se podr encontrar en la memoria sumandole a la direccin del primer byte el ndice. Un vector de n enteros ocupar un rea de memoria en la que cada entero ocupar a su vez dos bytes, de manera que la direccin de memoria de cada nmero ser la del arreglo ms dos veces el ndice y as sucesivamente. Declaracin de tipo y uso de los arreglos Builder acepta como declaracin de tipo para los arreglos la misma que hemos visto para los strings, por supuesto ya que como hemos dicho un string es un arreglo de una dimensin: int Miarreglo[100];

134

El

Arte

de

Programar

Para un arreglo de 100 enteros. Para almacenar un arreglo de 10x10 enteros la declaracion es: int tuarreglo [10][10];

Veamos como se usan los arreglos: Para ello recordemos un problema que fue dejado para que Ud. resolviera en el captulo 2 despes del problema 2.15. Recuerda? Haba que agregar un espacio cada vez que apareca uno. El problema que Ud. enfrent si lo trat de hacer es que no tena forma de guardar las posiciones de los espacios, para luego incorporar el doble espacio. El siguiente programa le da solucin al problema si bien de manera no muy ortodoxa.
/*Ahora recortador ubica el primer espacio. ` Deja solo la primer palabra en la variable original. Salva el resto en una nueva variable y luego las concatena e insertador agrega un espacio en la posicin del nuevo espacio*/

char *ptr,*nespacios,letra[2],frase1[80],frase2[80],frase3[80],frase4[80];
recortador(){ nespacios = strstr(frase1,letra);//encuentra el primer espacio en la frase inic. ptr = nespacios+1; //apunta ptr un caracter mas all del espacio strcpy(frase2,ptr); //guarda el resto de la frase original en frase2 frase1[nespacios-frase1]='\0';//limita frase1 a la primer palabra strcat(frase1,frase2); //concatena frase1 y frase2 } insertador(int i){ strcpy(frase4,nespacios);//guarda el resto de la frase incluido el espacio frase3[nespacios-frase1+i]='\0'; strcat(frase3,letra); //le agrega un espacio a frase3 strcat(frase3,frase4); //concatena frase1 y frase2 printf("%s\n",frase3); }// y muestra el resultado

135

El

Arte

de

Programar

main(){strcpy(frase1,"que interesante el tema tratado"); strcpy(letra," "); strcpy(frase3,frase1); printf("%s\n",frase1); recortador(); insertador(1); recortador(); insertador(3); recortador(); insertador(5); recortador(); insertador(7); gets(); }

El recurso de aprovechar en el procedimeinto insertador la ubicacin del espacio permite resolver el problema. Sin embargo mediante una variable estructurada, que me permita para cada posicin de un espacio guardarla en forma ordenada la solucin es como se ve a continuacin mucho ms elegante.

Definiendo el problema: debemos detectar la posicin de los espacios y en cada lugar insertar otro espacio. La deteccin de los espacios la podemos hacer eliminandolos uno a uno y registrando en cada caso la posicin justamente usando un vector. El ndice nos marcara el primer espacio, el segundo. tc., tc. y el valor sera la posicin del espacio en la frase original. Pero ya que tenemos las herramientas usmoslas. Los diagramas estructurados siguientes muestran la evolucin del refinamiento progresivo.

136

El

Arte

de

Programar

Programa dosespacios

Detectar espacios 1

2 Colocar dos espacios

1 Detectar espacios Mientras no se alcance el fin de la frase

1a

1a1

ubicar un espacio

anotar la posicin 1a2

buscar el prximo 1a3

2 Colocar dos espacios Mientras correspondan espacios

2a

2a1

Inserte dos espacios en cada posicin y tenga en cuenta el espacio adicional

137

El

Arte

de

Programar

Los nmeros y las letras permiten manejar los diferentes niveles en forma cmoda si necesitamos visualizar el rbol completo.

1 1a

2 2a

1a1

1a2

1a3

2a1

Hasta dnde debe llegar nuestro refinamiento?. Como ya dijimos antes, hasta que lo que se debe hacer con la computadora sea evidente. La lectura de nuestro rbol sugiere que tanto la tarea 1 como la 2 pueden realizarce mediante sendas funciones. En ese caso se indica en el rbol mediante un doble rectngulo con el nombre del procedimiento dentro de l, as en nuestro caso. Dobleespacio

Detector_esp

Colocador_esp

Ahora podemos desarrollar el diagrama para cada procedimiento. Y bajo el titulo Dobleespacio podremos desarrollar el diagrama para la funcin main(). Para detectar los espacios, la estrategia ser recorrer el string desde el primer caracter hasta el final. guardando en cada oportunidad que aparezca un espacio, la posicin del mismo. 138

El

Arte

de

Programar

1 Detector_esp

1a while( i < strlen())

1a1

if ( string[i]() == )

1a2

i++

1a1a

posiciones[j] = i

j++

i++

Colocador_esp
for (k=0; k < j; k++)

2a

{strcpy(frase2,frase1 + posiciones[k]+(k+1));

strcat(frase1," ");

printf("%s\n",frase1);}

2a1

2a3
frase1[posiciones[k] +k]='\0';

2a5
strcat(frase1 ,frase2);

2a2

2a4

El programa principal se puede ahora a partir de las funciones definidas presentar.en un grafos del tipo que estamos manejando. 139

El

Arte

de

Programar

Dobleespacio

main(){ char *ptr,frase2[80]; char frase1[80]= "Que interesante el tema tratado"; j=0; i=0; char letra=' '; printf("%s\n",frase1); int k,j,i,posiciones[30];

Detector_esp

Colocador_esp

gets();}

Finalmente el programa tal cual lo pondremos en el editor char *ptr,frase2[80]; char letra=' '; char frase1[80]="Que interesante el tema tratado"; int k,j,i,posiciones[30]; void Detector_esp(void); void Colocador_esp(void); main(){ j=0; i=0; printf("%s\n",frase1); Detector_esp(); 140

El

Arte

de

Programar

Colocador_esp(); gets();} void Detector_esp(){ while (i <= strlen(frase1)) { if (frase1[i]==' ') {posiciones[j] = i; j++; i++ ;} i++;}} void Colocador_esp(){ for (k=0; k < j; k++){ strcpy(frase2,frase1+posiciones[k]+(k+1)); frase1[posiciones[k]+k]='\0'; strcat(frase1," "); strcat(frase1,frase2); printf("%s\n",frase1);}} Para programas del tipo usado como ejemplo puede que todo esto parezca una exageracin de detalles. Es probable, pero desarrollar buenos hbitos en cuanto a autodisciplinarse en esto de la elaboracin de programas de computacin es una buena prctica.

141

El

Arte

de

Programar

142

El

Arte

de

Programar

8 MAS SOBRE FUNCIONES Y VARIABLES Bien finalmente hemos creado un conocimiento que nos va a permitir movernos con ms comodidad alrededor de la resolucin de problemas usando BUILDER

143

Вам также может понравиться