Algoritmos y Estructura de Datos - USM

824
1 Profesor Leopoldo Silva Bijit 17-07-2009 Estructuras de Datos y Algoritmos. Usando lenguaje C. Sinopsis. El texto está orientado a un segundo curso de programación en planes de estudios de ingenieros eléctricos, electrónicos, telemáticos y de ciencias de computación. Se asume que en un curso previo de programación de computadores, se han dominado las reglas para la construcción de: expresiones, condiciones, alternativas y repeticiones; también la correcta forma de diseñar funciones pasando los parámetros con los tipos adecuados, y la elección de las variables locales y globales; así también la forma de comunicar los resultados de las funciones; también se asume como prerrequisito el empleo de las bibliotecas de entrada- salida y las matemáticas. Por el lado de los datos se asume que se conocen los tipos básicos de datos, tanto en su forma de definir variables como en las de su manipulación. El texto desarrolla en profundidad los mecanismos recursivos de agrupación de los tipos básicos de datos en estructuras y arreglos, con los cuales se puede seguir elaborando estructuras tan complejas como sea necesario; también mediante la vinculación, empleando cursores o punteros, se pueden establecer relaciones entre componentes de la estructura de datos. Mediante la agrupación y vinculación se describen estructuras abstractas de datos como: listas, árboles, conjuntos, grafos. Usando estas estructuras abstractas de datos pueden modelarse los datos de sistemas reales más complejos, como: sistemas operativos, la información que viaja en los paquetes de datos de una red, o complejas relaciones entre componentes de datos en un sistema de bases de datos, por mencionar algunos ejemplos. El texto centra su atención en el diseño de algoritmos para realizar las acciones básicas de: Ordenar, buscar, seleccionar y calcular, empleando diferentes estructuras de datos. Por ejemplo, se pueden ordenar los elementos de una lista o de un arreglo; se puede buscar un valor en un árbol, en una lista o en un arreglo. La elección adecuada de la estructura de datos y del algoritmo empleado permite obtener un diseño eficiente, tanto en recursos ocupados como en el tiempo de ejecución. Parte importante del curso estará centrada en lograr una medida de la eficiencia de cada algoritmo y su comportamiento a medida que aumenta el número de elementos que constituyen los datos; es decir, de su complejidad.

Transcript of Algoritmos y Estructura de Datos - USM

1 Profesor Leopoldo Silva Bijit17-07-2009 Estructuras de Datos y Algoritmos.Usando lenguaje C. Sinopsis. El texto est orientado a un segundo curso de programacin en planes de estudios de ingenieros elctricos, electrnicos, telemticos y de ciencias de computacin.Se asume que en un curso previo de programacin de computadores, se han dominado las reglas paralaconstruccinde:expresiones,condiciones,alternativasyrepeticiones;tambinla correctaformadedisearfuncionespasandolosparmetrosconlostiposadecuados,yla eleccin de las variables locales y globales; as tambin la forma de comunicar los resultados de lasfunciones;tambinseasumecomoprerrequisitoelempleodelasbibliotecasdeentrada-salida y las matemticas. Por el lado de los datos se asume que se conocen los tipos bsicos de datos, tanto en su forma de definir variables como en las de su manipulacin. Eltextodesarrollaenprofundidadlosmecanismosrecursivosdeagrupacindelostipos bsicos de datos en estructuras y arreglos, con los cuales se puede seguir elaborando estructuras tancomplejascomoseanecesario;tambinmediantelavinculacin,empleandocursoreso punteros, se pueden establecer relaciones entre componentes de la estructura de datos. Mediantelaagrupacinyvinculacinsedescribenestructurasabstractasdedatoscomo: listas, rboles, conjuntos, grafos. Usando estas estructuras abstractas de datos pueden modelarse los datos de sistemas reales ms complejos, como: sistemas operativos, la informacin que viaja enlospaquetes dedatosdeuna red,ocomplejas relacionesentrecomponentes dedatos enun sistema de bases de datos, por mencionar algunos ejemplos. Eltextocentrasuatencineneldiseodealgoritmospararealizarlasaccionesbsicasde: Ordenar,buscar,seleccionarycalcular,empleandodiferentesestructurasdedatos.Por ejemplo, se pueden ordenar los elementos de una lista o de un arreglo; se puede buscar un valor en un rbol, en una lista o en un arreglo. Laeleccinadecuadadelaestructuradedatosydelalgoritmoempleadopermiteobtenerun diseo eficiente, tanto en recursos ocupados como en el tiempo de ejecucin.Parte importante delcursoestarcentradaenlograrunamedidadelaeficienciadecadaalgoritmoysu comportamientoamedidaqueaumentaelnmerodeelementosqueconstituyenlosdatos;es decir, de su complejidad. 2 Estructuras de Datos y AlgoritmosProfesor Leopoldo Silva Bijit17-07-2009 Estos algoritmos eficientes tienen importantes aplicaciones: en el diseo de sistemas operativos, en la programacin de sistemas y de aplicaciones en red, en la elaboracin de sistemas de bases de datos, en la construccin de compiladores y aplicaciones multimediales, por nombrar las ms importantes. La formacin de un ingeniero debe contemplar un balance adecuado entre la teora y la prctica. Por un lado se requiere disponer de un marco conceptual que permita pensar y reflexionar sobre un determinado problema; por otro, la capacidad de aplicar las ideas a situaciones reales. Enestecurso,lacapacidadderealizacinlaentenderemoscomoelconjuntodedisear estructurasdedatosyalgoritmoseficientes,medianteellenguajedeprogramacinC;la depuracin de programas, la verificacin de su funcionamiento correcto, a travs de someterlos adatosdepruebaescogidosconvenientemente.Todoslostemasdesarrolladoseneltexto, contienen las definiciones de las estructuras de datos y las funciones que las manipulan, junto a un programa principal que efecta un test de las funciones.Contenidos. El texto est organizado en 5 secciones, 25 captulos y 3 apndices, con numerosos problemas resueltos y ejercicios propuestos. LaseccindeConceptosbsicos,eselncleodelcurso,ycontienelasideasprincipalesdel texto. LaseccinBuscar,ilustraalgoritmosmsevolucionadosdebsqueda.Deloscualespueden seleccionarse algunos captulos para exponer en clases, otros pueden plantearse como proyectos haserdesarrolladosengruposdetrabajo. Se incluyenlosalgoritmosclsicosdeterministas y tambin los aleatorizados y amortizados. El algoritmo Treaps, ilustra el diseo de algoritmos en basealosdesarrolladosenConceptosbsicos,mostrandoquestosconstituyenelementosde diseo. LaseccinSeleccionarmuestraalgoritmosmselaboradosdeseleccin.Algunosdeellos ilustran el uso de listas doblemente enlazadas desarrolladas en Conceptos bsicos. EnlaseccinCalcularsehanseleccionadodostemasquesondeintersenelectrnica.Se muestran los principales algoritmos empleados en los simuladores analgicos, y se desarrolla la transformada rpida de Fourier. Los Apndices contienen algunos conceptos formales sobre lenguajes, una exposicin bsica del lenguaje C,y una breve descripcin de anlisis lxico, con el objeto de facilitar el llenado de las estructurascondatosprovenientesdearchivosdetexto.Locualpuedeemplearseparaprobar las funciones con una cantidad realista de datos. Prlogo y Contenidos3 Profesor Leopoldo Silva Bijit17-07-2009 Conceptos bsicos. Captulo 1Introduccin.Captulo 2Diseo de estructuras de datos. Captulo 3Administracin de la memoria.Captulo 4Complejidad temporal. Captulo 5Listas, stacks, colas.Captulo 6rboles binarios de bsqueda.Captulo 7Tablas de hash. Captulo 8Colas de prioridad.Captulo 9Ordenar.Captulo 10Grafos.Buscar. Captulo 11rboles Binarios Balanceados. AVL. Captulo 12rboles ColoreadosCaptulo 13rboles desplegados(splay trees) Captulo 14rboles enhebrados. Threaded Trees Captulo 15rboles AA Captulo 16Treaps Captulo 25Skip list Captulo 17B-Trees Seleccionar. Captulo 18Pagodas Captulo 19Leftist Captulo 20SkewheapCaptulo 21rboles binomiales Captulo 22Pairing heaps Calcular. Captulo 23Algoritmos numricos Captulo 24Transformada rpida de Fourier 4 Estructuras de Datos y AlgoritmosProfesor Leopoldo Silva Bijit17-07-2009 Apndices. Apndice 1Descripcin formal de lenguajes. Apndice 2Programacin en C. Apndice 3Analizadores lxicos. 1 Profesor Leopoldo Silva Bijit26-05-2008 Captulo 1. Introduccin a las Estructuras de Datos y Algoritmos. 1.1. Estructura de los datos. Lainformacinserepresentamediantebits.Losbitsseorganizanenbytesypalabrasde memoria, mediante las cuales se representan los tipos bsicos de datos. Mediante los mecanismos de agrupacin en estructuras y arreglos se pueden seguir elaborando estructuras ms complejas; mediante la vinculacin, empleando cursores o punteros, se pueden establecer relaciones entre componentes de la estructura de datos. Con estos elementos pueden describirse estructuras abstractas de datos como: listas, rboles, conjuntos,grafos.Usandoestructurasabstractasdedatossepuedenmodelarlosdatosde sistemas ms complejos, como: sistemas operativos, la informacin que viaja en los paquetes de datos de una red, o complejas relaciones entre componentes de datos en un sistema de bases de datos, por mencionar algunos ejemplos. Las relaciones de los elementos de datos, en sus diferentes niveles, pueden conceptualizarse en el siguiente diagrama: Bases de datos Paquetes en Redes Datos en Sistemas operativos Listas, stacks, colas Grafos rboles, conjuntos, heaps Datos en el stack Datos en el heap Creacin de nuevos tipos punteros Ingresar y desplegar datos Arreglos, estructuras char, unsigned char float, double int , unsigned int, long Byte, palabra bit Figura 1.1. Estructuras de datos. 2Estructuras de Datos y AlgoritmosProfesor Leopoldo Silva Bijit26-05-2008 Los dos niveles inferiores son cubiertos en asignaturas sobre sistemas digitales. Los dos niveles siguientes deberan cubrirse en un curso bsico de programacin. Los cuatro niveles inferiores tambin son tratados en cursos de estructuras de computadores, en el cual se elaboran las estructuras de datos del lenguaje de alto nivel, mediante los mecanismos deestructuracindedatosydireccionamientosassembler;losqueasuvezsonexplicadosen trminosdelosmodosdedireccionamientodelasinstruccionesdemquina;enestenivel tambinsedescribeelusodelosdiferentesregistrosysegmentosdememoria,yla configuracin detallada de los frames en el stack. Los niveles quinto y sexto son el tema de este texto.1.2. Estructura de las acciones. Algoritmos. Ensuformamsprimitivalaagrupacindecompuertaspermiteeldesarrollodeacciones combinacionales, entre ellas: la unidad aritmtica y lgica, unidades de corrimiento, extensores, muxes.Conlaayudadeelementosdememoriayconducidasporunreloj,sepuedenelaborar mquinas secuenciales que efecten las acciones de contar, desplazar, multiplicar y dividir, as tambinelgenerarlasaccionesdecontrolquegobiernanlastransferenciasentrelosrecursos bsicos de un procesador.Esto se cubre en un curso de Sistemas Digitales. Luegodeestaestructuracin,lasaccionesrealizadaselectrnicamentepuedenserabstradas comoinstruccionesdemquina.Mediantelaayudadecompiladoresesposibletraducirlas acciones o sentencias del lenguaje de alto nivel en instrucciones de mquina. En el nivel de los lenguajesdeprogramacin,sedisponedeoperadoresquepermitenconstruirexpresionesy condiciones; agregando las acciones que implementan las funciones combinacionales se pueden abstraerlasaccionesentrminosdealternativas,condicionalesyswitches;lacapacidadde implementarmquinasdeestadospermitelarealizacindeiteracionesyrepeticiones.Las organizaciones y arquitecturas se estudian en un curso de estructuras de computadores. Sistemas de Bases de datos Aplicaciones en Redes Sistemas operativos Seleccionar Calcular Buscar, ordenar Proyectos, mdulos bibliotecas funciones Expresiones, condiciones Iteraciones, recursin Alternativas, condicionales Instrucciones de mquina Funciones combinacionales Mquinas secuenciales ALU, muxes, Buses, Control Memorias primitivas, compuertas Figura 1.2. Estructura de acciones. Introduccin3 Profesor Leopoldo Silva Bijit26-05-2008 Elsiguienteniveleseldeuncursodeprogramacin,elquedeberacubrir:lasreglasparala construccin de expresiones, condiciones, alternativas y repeticiones; tambin la correcta forma dedisearfuncionespasandolosparmetrosconlostiposadecuados,ylaeleccindelas variables locales y globales; as tambin la forma de comunicar los resultados de las funciones.En un curso bsico de programacin tambin se domina el empleo de las bibliotecas de entrada-salida y las matemticas. Eltemacubiertoenestetextocentrasuatencineneldiseodealgoritmospararealizarlas accionesbsicasde:Ordenar,buscar,seleccionarycalcular,empleandodiferentes estructuras de datos. Por ejemplo, se pueden ordenar los elementos de una lista o de un arreglo; se puede buscar un valor en un rbol, en una lista o en un arreglo. Laeleccinadecuadadelaestructuradedatosydelalgoritmoempleadopermiteobtenerun diseo eficiente, tanto en recursos ocupados como en el tiempo de ejecucin.Parte importante delcursoestarcentradaenlograrunamedidadelaeficienciadecadaalgoritmoysu comportamientoamedidaqueaumentaelnmerodeelementosqueconstituyenlosdatos;es decir, de su complejidad. Estos algoritmos eficientes tienen importantes aplicaciones: en el diseo de sistemas operativos, en la programacin de sistemas y de aplicaciones en red, en la elaboracin de sistemas de bases de datos, en la construccin de compiladores y aplicaciones multimediales, por nombrar las ms importantes. 1.3. Lenguajes. En los diferentes niveles de datos y acciones se emplean diferentes lenguajes. En los niveles fsicos, se emplean Lenguajes de Descripcin de Hardware (HDL). Para describir losprocesadoresseemplealenguajeassembler,cadaprocesadortieneunlenguajeassembler propio.Enlenguajesdealtonivelhaexistidounarpidaevolucin.Muchosdelosquefueronms universalmente usados han pasado a la historia: Fortran, Algol, APL, Pascal, Modula, Basic. Losprimeroslenguajesofrecanalprogramadorlaposibilidaddeefectuarsaltos.Elprimer avanceevolutivofundamentadofueimpedirqueelprogramadorpudieseemplearlossaltos,y queaceptaseformasestructuradasdeorganizarlasacciones.Esdecirqueconstruyera algoritmos organizando las acciones en secuencias, alternativas o iteraciones. Elsiguientemodeloconceptualfueeldesarrollomodularenelcualsedefinanestructurasde datosy las funciones que las manipulaban; es decir la concepcin de tipos abstractos de datos. Los lenguajes como Pascal, C y otros tienen la posibilidad de programacin de tipos abstractos. El lenguaje C evolucion rpidamente para convertirse en uno de los ms usados. Su principio dediseoesquecompileeficientementeyquepermitausarlosrecursosdehardwaredelos procesadores. Por esta razn se lo seguir empleando en cursos de estructuras de computadores yeneldiseodemicrocontroladores.Sinembargosuscapacidadesdemanejodememoria 4Estructuras de Datos y AlgoritmosProfesor Leopoldo Silva Bijit26-05-2008 dinmica y el empleo de punteros, que son sus principales ventajas, son sus principales fuentes de errores en la elaboracin de grandes programas. Elmodeloactualeseldiseoylaprogramacinorientadaaobjetos,enelcualseimpideal programadoremplearpunteros,yelmanejodelamemoriadinmicaesresponsabilidaddel lenguajeynodelprogramador.Losdatosylasaccionesconformanelobjeto,noestn separadas. Existen varios de estos lenguajes, Java es uno de los que ms se ha difundido. Seguramenteconlosaosaparecernnuevosymejoreslenguajes,perolosprincipales conceptos que aprendamos en este texto seguramente perseverarn, ya que son bsicos. 1.4. Genialidades. Losmsimportantesalgoritmosqueestudiaremosempleanideasgenialesybrillantes.Desde quesondescubiertosselosempiezaausarenlasaplicaciones,debidoasusventajas.Sin embargo exponer ideas: a veces sofisticadas, otras decididamente rebuscadas, en algunos casos aparentementesimplistas,yquehanresueltograndesproblemassonpartedeladificultadde este curso. No se estudian cuestiones sencillas, la mayor parte de ellas son muy elaboradas, y algunas veces difciles de captar en su profundidad. Debido a lo anterior, no se espera que despus de estudiar este texto se est en condiciones de inventar algoritmos que pasen a la historia, pero si conocer las principales estructuras abstractas deusogeneral,susposiblesaplicaciones,ylosmejoresalgoritmosconocidosparaesas estructuras. 1.5. Teora y prctica. La formacin de un ingeniero debe contemplar un balance adecuado entre la teora y la prctica. Por un lado se requiere disponer de un marco conceptual que permita pensar y reflexionar sobre un determinado problema; por otro, la capacidad de aplicar las ideas a situaciones reales. Enelcasoparticulardeestecurso,lacapacidadderealizacinlaentenderemoscomoel conjuntodedisearestructurasdedatosyalgoritmoseficientes,medianteellenguajede programacinC; ladepuracindeprogramas,laverificacindesufuncionamiento correcto, a travs de someterlos a datos de prueba escogidos convenientemente.1.6. Definiciones. 1.6.1. Algoritmo. Secuencia finita de operaciones, organizadas para realizar una tarea determinada. Cadaoperacindebetenerunsignificadoprecisoydebeserrealizadaenunlapsofinitode tiempoyconunesfuerzofinito.Unalgoritmodebeterminardespusdeejecutarunnmero finito de instrucciones. Introduccin5 Profesor Leopoldo Silva Bijit26-05-2008 Algoritmosdiferentespuedencompletarlamismatareaconlaejecucindeunconjuntode instrucciones diferentes, en ms o menos tiempo, y empleando ms o menos memoria. Es decir, pueden tener complejidad y costo diferentes. Se pueden analizar algoritmos, en forma abstracta, es decir sin emplear un determinado lenguaje de programacin; el anlisis se centra en los principios fundamentales del algoritmo y no en una implementacinenparticular.Enestoscasospuedeemplearseparasudescripcinun pseudocdigo. Existen mtodos cuantitativos para determinar los recursos espaciales y temporales que requiere un algoritmo. En particular se estudiarn mtodos para calcular la complejidad temporal de un algoritmo. 1.6.2. Heurstica. Un algoritmo que produce soluciones razonablemente rpidas y buenas, pero no necesariamente la solucin ptima. 1.6.3. Estructuras de datos. La forma en que se organizan los datos para ser usados. Es una coleccin de variables, posiblemente de diferentes tipos de datos, conectadas de un modo determinado. Una estructura de datos bien organizada debe permitir realizar un conjunto de acciones sobre los datosdetalformademinimizarelusodelosrecursosyeltiempoempleadoparaefectuarla operacin. 1.7. Algoritmos clsicos. Sedescribenalgunosalgoritmos,consideradosclsicos,parailustrarelcaminoquedebe recorrerse desde su diseo hasta traducirlo a un lenguaje de programacin. En opinin del Profesor Dijkstra, las computadoras manipulan smbolos y producen resultados; y un programa, que describe un algoritmo, es un manipulador abstracto de smbolos. Visto de este modo un algoritmo es una frmula de algn sistema formal; sin embargodebido a queestasfrmulasresultanmuchomslargasyelaboradasquelasusuales,nosuele reconocrselas como tales. En primer lugar debe describirse lo que se desea realizar en lenguaje natural, desgraciadamente estopuedeproducirmsdealgunaambigedad.Luegodebemodelarsematemticamentela situacinqueinteresadescribir;esdecir,apoyadoenconceptosmatemticosylgicosse describelafuncinofrmulaquedeberealizarse,empleandounpseudolenguaje;queesms precisoyformalqueellenguajecomn.Unavezobtenidaunarepresentacinformalsela traduce empleando un lenguaje de programacin. 6Estructuras de Datos y AlgoritmosProfesor Leopoldo Silva Bijit26-05-2008 Noessencilloderivarelalgoritmodesdeunprogramaqueloimplementa.Locualpuede observarse intentando leer programas, sin disponer antes de la descripcin del algoritmo. Sin embargo el paso de la descripcin en pseudocdigo a un lenguaje de programacin suele ser unaactividaddemenorcomplejidad;adems,estopermitesucodificacinendiferentes lenguajes de programacin. 1.7.1. Algoritmo de Euclides. Euclidesfueunmatemticogriegoquevivialrededordelao300a.C.unadesus contribuciones esel algoritmoparaobtener el mximo comn divisor dedos nmerosenteros, lo cual sera la descripcin en lenguaje natural, del problema que se desea resolver. Luego intentamos modelar matemticamente la situacin. Si x e y son enteros, no ambos ceros, su mximo comn divisor, que anotaremos mcd(x,y), es el mayor entero que los divide a ambos exactamente; es decir, sin resto. Ejemplo:mcd(7, 11)= 1 mcd(16, 28)= 4 Puede comprobarse que: mcd( x, 0) =|x| mcd( x, y) = mcd(y, x) mcd(-x, y) = mcd(x, y) Delocualsedesprendequeesdeintersobtenerunalgoritmoparaelmcddeenterosno negativos,elconocimientomatemticoquesenecesita,pararesolveresteproblemaesel siguiente: Si los nmeros son x e y: a) Si x es igual a y; entonces x ( y) es el resultado. b) Si se reemplaza el nmero mayor por la diferencia del mayor menos el menor, no cambia el mximo comn divisor. Lo anterior puede plantearse en trminos matemticos, segn: a) mcd(x, x) = x b) Si x > y se tiene mcd(x, y) = mcd(x-y, y) Entoncesparaenterosmayoresquecero,tenemoselsiguientealgoritmo,descritoenlenguaje natural: Mientras los nmeros sean diferentes: Deje el menor, y forme otro restando el menor al mayor. Lo cual puede plantearse, empleando el lenguaje C: Introduccin7 Profesor Leopoldo Silva Bijit26-05-2008 while (x!=y) if (x>y) x=x-y; else y=y-x; Comoveremos,atravsdelossiguientesejemplos,existennumerosasformasdedescribirun algoritmo. Otra forma de describir el Algoritmo de Euclides es la siguiente:

do { while (x>y) x=x-y; while (y>x) y=y-x; } while (x!=y); // x es el mcd

Veremos otra forma del algoritmo.Debido a que puede comprobarse que: mcd(x, y) = mcd(y, x mod y) Laexpresinmuestracmoreducirunodelosnmeros,manteniendoenelprimerlugaral mayor. La transformacin debe repetirse hasta que el menor de los nmeros sea igual a cero.El cambio de posicin de los nmeros requiere una variable temporal que denominaremos resto. Entonces una variante del algoritmo de Euclides es la siguiente: while (y!=0){ resto = x % y; x=y; y=resto; } // x es el mcd

La siguiente funcin iterativa resume las ideas anteriores: int mcd(int x, int y) { int resto; if (x==0) return (y); if (y==0) return (x); while (y!=0){ resto=x-y*(x/y); //resto=x % y; x=y; y=resto; } return (x); } Debido a puede definirse en forma recursiva la funcin mximo comn divisor, segn: 8Estructuras de Datos y AlgoritmosProfesor Leopoldo Silva Bijit26-05-2008 mcd( x, 0) =|x|, mcd(x, y) = mcd(y, x mod y) Se puede describir el algoritmo de Euclides, en forma recursiva: int mcd(int x, int y){ if (y == 0) return x; return mcd(y, x % y); } 1.7.2. Algoritmo el colador de Erasttenes. Erasttenesfueunmatemticogriego(275-194A.C.)quedesarrollunalgoritmoquese conocecomolacribadeErasttenes(sieveeningls),quepermitedeterminarlosnmeros primosmenoresqueunnmerodado.Elnombrederivadeuncoladorenquesecolocan todos los nmeros, y slo deja pasar los nmeros primos. Para desarrollar el modelo matemtico que permita elaborar el algoritmo, pueden emplearse las siguientes definiciones de un nmero primo:

Un nmero primo es un entero positivo que no es el producto de dos enteros positivos menores. Un nmero primo es un entero positivo que tiene exactamente dos factores enteros positivos: 1 y s mismo. Entonces el algoritmo, puede describirse informalmente, segn:Se crea arreglo de nmeros booleanos con el tamao de los nmeros que se desea probar si son o no primos y se los marca como primos. El ndice del arreglo est asociado al nmero entero. Semarcaelelementoconndice1comonoprimo.Yaquenoexistendosenterosdiferentes menores que 1. Se recorre el arreglo, en forma ascendente, dejando el siguiente nmero, previamente marcado como primo al inicio, como primo; y todos los mltiplos de ste, se marcan como no primos. Puede comprobarse que el primer mltiplo a eliminar es el cuadrado del nmero. Elsiguienteprogramailustraelalgoritmo,sehaagregadolafuncinmostrarparaefectuarun listado de los nmeros primos. Se listan los primos menores que la constante n. #include #define n 40 #define primo 1 #define noprimo 0 int a[n]; Introduccin9 Profesor Leopoldo Silva Bijit26-05-2008 void mostrar(void) { int i; for (i= 2; ii1) return(q); q = q->next;} return (NULL); } return(NULL); } int main(void) {pnodo tt; crealista(); printf(" %d \n", ( *(busca(lista1)) ).i1); printf(" %d \n", busca(lista2)->i2); if( (tt=busca2(lista1, 3, lista2)) !=NULL)printf("%d\n", tt->i2); return(0); } a) Explicar, empleando un diagrama, el paso por referencia de Push. b) Diagrama de la estructura despus de ejecutar crealista(); c) Explicar accin realizada por busca. d) Explicar accin realizada por busca2. e) Determinar qu imprime el programa. Solucin. a) En la funcin crealista, se tiene un ejemplo de uso de Push.Consideremos el llamado: Push(&lista1, 0, 1). En la definicin de Push, el primer argumento es un puntero a puntero a nodo. Definicin de Estructuras de Datos en C. 17 Profesor Leopoldo Silva Bijit26-05-2008 Dentro de la funcin, la ocurrencia de *ref, denota a la variable, cuya direccin es pasada en la invocacin a la funcin, en el caso del ejemplo referencia a variable global lista1. Si*ref,aparecealaderecha,formandopartedeunaexpresin,suvaloreselalmacenadoen lista1; si aparece a la izquierda, se escribe en la variable lista. Luego de la invocacin a la funcin, se tiene el siguiente esquema para las variables.

Figura P2.1. Ntesequelosargumentossonvariables almacenadas enel stack, iniciadas con losvaloresde losparmetrosdelainvocacin.Lavariablelocalnewnodo,alnoestarinicializadaensu definicinapuntaacualquierlado.Raznporlacual,convienedefinirlaseinicializarlas simultneamente. Despus de un llamado exitoso a getnodo(); es decir, malloc asign una estructura en el heap, un diagrama de la situacin es el siguiente: Figura P2.2. Elrestode lafuncin,escribeen loscamposdelaestructura creada en el heap. Y adems, en ltimo trmino, sobreescribe en la variable global lista1 (en el ejemplo que se analiza). Lista1 newnodo? ref dato1 = 0 dato2 = 1 DatosStack Lista1 newnodo heap ref dato1 = 0 dato2 = 1 DatosStack i1 = ? i2 = ? next = ? 18 Estructuras de Datos y AlgoritmosProfesor Leopoldo Silva Bijit26-05-2008 Figura P2.3 AlsalirdePush,desaparecenlasvariablesautomticas,ubicadasenelstack,ylasituacin queda: Figura P2.4 Si se hubiera pasado solamente un puntero a nodo como referencia, se tendra el diseo: void Push2(pnodo ref, int dato1, int dato2){ pnodo newnodo; if ( (newnodo=getnodo()) == NULL)exit(1); newnodo->i1 = dato1; newnodo->i2 = dato2; newnodo->next = ref; ref = newnodo;} Y un ejemplo de uso, sera: Push2(lista1, 0, 1); Lo cual no es equivalente al diseo anterior. Puede comprobarse efectuando un diagrama. Las listas con cabecera ( header ) permiten diseos alternativos. Lista1 newnodo heap ref dato1 = 0 dato2 = 1 DatosStack i1 = 0 i2 = 1 next Lista1 heapDatosStack i1 = 0 i2 = 1 nextDefinicin de Estructuras de Datos en C. 19 Profesor Leopoldo Silva Bijit26-05-2008 b) Despus de crealista, el espacio queda: Figura P2.5. c)Ala funcin busca,se lepasa ladireccin del primer nodo dela lista. Si la lista es vaca, retornaunpunteronulo.Sinoesvaca,conpprecorrelalista,dejandoqqapuntadoalnodo corriente y con pp al prximo.Cuando se llega con pp, al final de la lista, qq apunta al ltimo nodo de la lista. d)Lafuncinbusca2intentaencontrarelvalorjenelcampoi1delnodoapuntadoporel argumento p. Si la lista es vaca retornaun puntero nulo; en caso de encontrar el valor j, busca a partirdelnodoapuntadoporq,elvalordelcampoi1queseaigualalvalordelcampoi2del nodo donde qued apuntando p. Si lo encuentra, retorna un puntero al nodo que cumple la condicin anterior; en caso contrario, retorna un puntero nulo. La invocacin: busca2(lista1, 3, lista2), despus del primer while, deja p apuntando al segundo nodo de la lista1, el segundo while deja q apuntando al cuarto nodo de la lista2; ya que busca en sta el valor 4 en el campo i1. El diseo de la funcin incurre en un error frecuente, en este tipo de problemas. Qu ocurre si el valor j no se encuentra en ningn campo i1 de la lista apuntada por p?. Cuandoptomevalornulo,intentarleerp->i1enlasprimerasdireccionesdememoria,las cuales suelen pertenecera un segmento del sistemaoperativo. Lo ms seguro quelaejecucin del proceso aborte debido a un error de segmentacin. Se podra corregir, cambiando: while( p->i1 !=j ) p = p->next; por: while ((p != NULL)&&( p->i1 !=j )) p = p->next; Lo cual funciona debido a que el and opera con cortocircuito. e) En primer trmino imprime el campo i1 del ltimo nodo de la lista1. Luego el campo i2 del ltimo nodo de la lista2. Lista1 heapDatos i1 = 0 i2 = 1 nexti1=4 i2 = 5 nexti1 = 3 i2 = 4 nexti1 = 2 i2 = 3 nexti1 = 1 i2 = 2 nextLista2 i1 = 5 i2 = -1 nexti1 =1 i2 = 3 nexti1 = 2 i2 = 2 nexti1 = 3 i2 = 1 nexti1 = 4 i2 = 0 next20 Estructuras de Datos y AlgoritmosProfesor Leopoldo Silva Bijit26-05-2008 Finalmente el campo i2 de la lista 2, cuyo campo i1 es 4; ya que en la lista1, el campo i2 es 4, cuando el campo i1 es 3. Imprimira: 0 -1 0 P2.2. Escribir una funcin:int btoi(char *str, int *pvalor) que convierta un string binario pasado en str (Ej. "110101") a un entero a ser retornado en pvalor (Ej. 53). La funcin retorna 0 si no hay error y retorna-1 si el string binario tiene un carcter que no es '0' o '1'.Nota: 1101 (en binario) = 1x23+1x22+0x21+1x20 = 8 + 4 + 1 = 13 en decimal /* Uso de la funcion */ #include #include #include int btoi(char *str, int *pvalor); main() { int valor=0; char str[10]; strcpy(str, "110101"); if( !btoi(str, &valor) ) printf("string binario: %s, int:%d\n", str, valor); } Solucin. int btoi(char *str, int *pvalor) { int i=0, largo=0, temp=0; largo = strlen(str) - 1;//ndice del dgito menos significativo while(i =0) { if (*(str + i) == '1') { temp += pot; printf(" %d%d \n",temp, pot);} else if (*(str + i) == '0') ; else return -1;//no es 1 0 i--;pot*=2; } *pvalor = temp; return 0; } P2.3. Se tiene la siguiente funcin: char *f1(char *s, int c) { while( *s ){ if( *s == (char) c ) return (char *) s; s++; } return (char *) 0; } a) Explicar los cast que se emplean y su necesidad. b) Qu realiza la funcin. c) Si se tiene char *string="12345678";explicar que despliega: printf("%s\n", f1(string, '3')) ; Solucin. El cast (char) c se emplea, debido a que el segundo argumentode la funcin es de tipo entero, paraconvertirloacarcteryefectuarlacomparacinconuncarcterdelstring.Noes necesario,yaquepordefecto,losvaloresdetipocarctersonpromovidosautomticamentea enteros con signo. Por ejemplo se puede pasar equivalentemente el valor 65 0x45 A.Esto permite pasar caracteres de control que no son imprimibles, como argumentos.La comparacin tambin se poda haber explicado segn:( (int) *s == c ).Es preferible usar cast, de tal modo de comparar valores de igual tipo. El cast en return (char *) s;no es necesario, ya que s es de tipo puntero a char. El cast return (char *) 0; es necesario para retornar un puntero nulo a carcter. 22 Estructuras de Datos y AlgoritmosProfesor Leopoldo Silva Bijit26-05-2008 b)Revisayencuentralaprimeraocurrenciadelcarcter(char)c,enelstringapuntadopors; retornadounpunteroalcarcterdesqueesiguala(char)c.Sielstringesnulo,retornaun puntero nulo a carcter; tambin si no encuentra (char) c en el string. c) Despliega el string: 345678, seguido de un terminador de lnea, ya que el llamadof1(string, '3') retorna un puntero al string345678". P2.4. Se tiene la siguiente funcin: int f2(char *s1, char *s2) { while( *s1++ == *s2 ) if( *s2++ == '\0' ) return(1); return(0); } a) Explicar que realiza la funcin. Indicando las condiciones en las que retorna un cero o un uno b) Dar un ejemplo de uso. Definiendo las variables que sean necesarias. Solucin. a)Comparadosstrings.Retorna1 slo si los stringsson iguales. Reconoce la igualdad dedos stringsnulos.Retornacero,silosstringssondiferentes.Siloscaracteres,enlamisma posicin, de s1 y s2 son iguales va recorriendo ambos strings. Si los primeros caracteres de los strings fuesen iguales, retorna un cero si string s1 es ms corto que el string s2 (ya que no se cumple la condicin del while); lo mismo sucede si string 1 es ms largo que el string s2. b) char *s1="12345678"; char *s2="12345"; if ( f2(s1,s2)==0) printf("no son iguales\n"); else printf("son iguales\n"); P2.5. Se tiene la estructura para un nodo,con clave de tipo entera y tres punteros a nodo. a) Definir los tipos: nodo y pnodo (puntero a nodo). b) Disear, empleando malloc, la funcin con prototipo: pnodo creanodo(int clave);que solicita espacio e inicializa el nodo con punteros nulos y la clave del nodo con el valor del argumento. c)Sisetienelasiguientedefinicin:pnodopn;dibujarundiagramaconlosdatos,luegode ejecutada la secuencia: pn=creanodo(5); pn->p3=pn; clave p2p3p1 Definicin de Estructuras de Datos en C. 23 Profesor Leopoldo Silva Bijit26-05-2008 pn->p1=creanodo(3); pn->p1->p3=pn; pn->p2=creanodo(8); pn->p2->p3=pn->p1; d) Escribir el segmento que forma el siguiente diagrama: Figura P2.6. Solucin. a)typedef struct moldenodo {int clave; struct moldenodo *p1; struct moldenodo *p2; struct moldenodo *p3; }nodo , *pnodo; b)pnodo creanodo(int clave) { pnodo p; if ((p = (pnodo) malloc(sizeof(nodo))) == NULL) { printf ("Memoria insuficiente para crear nodo\n"); exit(1); } p->clave=clave;p->p2=NULL;p->p1=NULL;p->p3=NULL; return(p); } c) Los diagramas se ilustran despus de ejecutada la instruccin.pn=creanodo(5); pn

6p2 p3 p1

4p2 p3 p124 Estructuras de Datos y AlgoritmosProfesor Leopoldo Silva Bijit26-05-2008 Figura P2.7. pn->p3=pn; Figura P2.8. pn->p1=creanodo(3); Figura P2.9. pn->p1->p3=pn; Figura P2.10. pn 5 pn 5 pn 5 3 pn 5 3 Definicin de Estructuras de Datos en C. 25 Profesor Leopoldo Silva Bijit26-05-2008 pn->p2=creanodo(8); Figura P2.11. pn->p2->p3=pn->p1; Figura P2.12. c) pn= creanodo(6); pn->p2=pn; pn->p3=pn; pn->p1=creanodo(4); pn->p1->p1=pn->p1; pn->p1->p3=pn; pn->p1->p2=pn; pn 5 3 8 pn 5 3 8 26 Estructuras de Datos y AlgoritmosProfesor Leopoldo Silva Bijit26-05-2008 Figura P2.13. P2.6. Se tiene el siguiente programa. #include typedef struct nn { int x; struct nn * p; struct nn * q; int y; }t, *pt; t w, z; ptpx=&w; void main(void) {px->p=&z;w.q = px->p; px->q->q=px; z.p = w.p; w.x = z.x = 2; (*px).y = 8; (*(w.q)).y =9; px=(pt) malloc(sizeof(t)); px->p=px->q = (pt ) 0; px->x=px->y=12; } Efectuar un diagrama de los datos despus de ejecutar las instrucciones de main. Solucin. Antes de main, el espacio de variables puede visualizarse segn: pn

6p2 p3 p1

4p2 p3 p1Definicin de Estructuras de Datos en C. 27 Profesor Leopoldo Silva Bijit26-05-2008 Figura P2.13. Figura P2.14. x p y q w px x p y q z x p y q w px x p y q z px->p =&z w.q=px->p; 28 Estructuras de Datos y AlgoritmosProfesor Leopoldo Silva Bijit26-05-2008 Figura P2.15. Figura P2.16. x p y q w px x p y q z z.p=w.p px->q->q=px x2 p y 8 q w px x2 p y 9 q z w.x=z.x=2 (*px).y=8; (*(w.q)).y=9 Definicin de Estructuras de Datos en C. 29 Profesor Leopoldo Silva Bijit26-05-2008 Figura P2.17. Ejercicios propuestos. E1. Determinar qu imprimen los siguientessegmentos: a )printf(\n%o %x %d, 17, 017, 0x17) ; b) n = 3 ;printf(-05d %5d, n, n) ; c) x = 1234E-2 ;printf(%6.3f, x) ; d) j =2;if ( ( '1' -1 ) ==--j ) printf("verdad");else printf("falso"); E2. Colocar parntesis y evaluar las expresiones siguientes: Si es preciso puede indicar los resultados de expresionesintermedias. a)a != b&&c + 1==!c + 2 con a1)a=2 ; b=3 ; c = 1; a2)a=3 ; b=2 ; c=2 ;b) 1 + 2 * ( n += 8)/ 4 conn=3 ;c)a < b ?a < b ?a+1 :a+2 : a+3 con a=2 ; b= 3 ; E3. Se tiene el siguiente programa: Qu efecta la funcin, indicar tipo de parmetros. x2 p y 8 q w px x2 p y 9 q z px =(pt)malloc(sizeof(t)); x12 p y 12 q px ->p=px->q=(pt)0; px ->x=px->y=12; 30 Estructuras de Datos y AlgoritmosProfesor Leopoldo Silva Bijit26-05-2008 Escribir el prototipo y dnde debe ubicarse en el programa. Qu escribe el programa principal. void main() {int i=11, j ; j = funcion( i++, 5) ; printf(\n%d %d, j, i); j = funcion( j+i, j-3) ; printf(\n%d%d, j, i); } int funcion( int x, int y) { int s,t ; for( s=0 ; x != 0 ;x--)for ( t=0 ; t != y ; s++,t++) ; return( s ) ; } E4. Escribir programa. a) Que genere los primeros 20 nmeros de la secuencia: 1, 4, 7, 10, 14,.... b) Que genere b elementos de la secuencia a partir del a-simo. Leer a y b. E5. Indicar que escribe el programa.#include int func(int *, float *, char); void show(); float f1=1, f2=2.2; int i1=2, i2; void main() { i2 = func(&i1, &f2, '1'); show(); i1 = func(&i2, &f1, '2'); show(); for(;;); } void show() { printf("\ni1= %d i2=%d" ,i1,i2); printf("\nf1= %f f2= %f",f1, f2); } int func(int *i, float *f,char ch) { *f = (float)(*i+2); *i = (int)(*f)+2;printf("\n%c ", ch); return(*i+2); } E6. Indicarqu imprime el programa. #include Definicin de Estructuras de Datos en C. 31 Profesor Leopoldo Silva Bijit26-05-2008 int a[5]; int i; void arreglo(int j){ for(i=0;i1); i = (i&0x7fff); } void prt(int i) {int j; for (j=15; j>=0; j--)(1p.x ); printf(%d\n , *(pi-1)) ; pi = &m2.a[0]; printf(%d \n, *(pi+1)); } E10. Determinar la salida. #include int f2(int x, int y, int z) {int i; for(i=0; i=1;(*q)>>=1;if(k) *q=(*q)|0x8000; else *q=(*q)&0x7fff;s=m; } E14. Describir un multirbolMedianteunarreglodelistasdeloshijosdecadanodo. Elarreglo debetener unaentrada por cada nodo, adems considerar que la raz pueda se cualquier nodo. Definicin de Estructuras de Datos en C. 35 Profesor Leopoldo Silva Bijit26-05-2008 ndice general. CAPTULO 2. ............................................................................................................................................ 1 DEFINICIN DE ESTRUCTURAS DE DATOS EN C......................................................................... 1 2.1. TIPOS PRIMITIVOS. ............................................................................................................................. 1 2.2. MECANISMOS DE ESTRUCTURACIN. ................................................................................................. 1 2.2.1. Grupos bsicos. ......................................................................................................................... 1 2.2.2. Vnculos. .................................................................................................................................... 2 2.3. EJEMPLOS BASADOS EN ARREGLOS. ................................................................................................... 3 2.3.1. Acceso a componentes del arreglo. ........................................................................................... 3 Definicin de matrices. .................................................................................................................................... 4 Definicin de arreglo de arreglos. .................................................................................................................... 5 Arreglo de punteros a renglones. ..................................................................................................................... 5 Arreglo de punteros a caracteres. ..................................................................................................................... 6 2.3.2. Lista simplemente enlazada en base a cursores. ....................................................................... 6 2.4. EJEMPLOS BASADOS EN ESTRUCTURAS. ............................................................................................. 7 2.4.1. Estructura para fecha. ............................................................................................................... 7 2.4.2. Lista simplemente enlazada en base a punteros. ....................................................................... 9 2.5. ESTRUCTURAS MS COMPLEJAS. ...................................................................................................... 10 2.5.1. Arreglo de listas. ..................................................................................................................... 10 2.5.2. Arreglo de estructuras. ............................................................................................................ 11 2.5.3. Multirboles. ........................................................................................................................... 11 2.5.3.1. Descripcin mediante punteros. ........................................................................................................ 12 2.5.3.2. Descripcin mediante arreglos de cursores. ...................................................................................... 12 2.5.3.3. Descripcin por arreglo de padres. .................................................................................................... 13 2.6. UN EJEMPLO REAL DE ESTRUCTURAS. .............................................................................................. 14 PROBLEMAS RESUELTOS. ........................................................................................................................ 15 P2.1. Se tiene el siguiente programa: ............................................................................................... 15 P2.2. Escribir una funcin: ............................................................................................................... 20 P2.3. Se tiene la siguiente funcin: ................................................................................................... 21 P2.4. Se tiene la siguiente funcin: ................................................................................................... 22 P2.5. Se tiene la estructura para un nodo, ........................................................................................ 22 P2.6. Se tiene el siguiente programa. ................................................................................................ 26 EJERCICIOS PROPUESTOS. ....................................................................................................................... 29 E1. Determinar qu imprimen los siguientessegmentos: ................................................................ 29 E2. Colocar parntesis y evaluar las expresiones siguientes: ........................................................... 29 E3. Se tiene el siguiente programa: .................................................................................................. 29 E4. Escribir programa. ..................................................................................................................... 30 E5. Indicar que escribe el programa. ................................................................................................ 30 E6. Indicarqu imprime el programa. ............................................................................................. 30 E7. Indicar qu imprime el programa. .............................................................................................. 31 E8. Indicar qu imprime el programa. .............................................................................................. 31 E9. Indicar qu escribe el programa. ................................................................................................ 32 E10. Determinar la salida. ................................................................................................................ 32 E11. Determinar la salida. ................................................................................................................ 33 E12. Determinar la salida. ................................................................................................................ 33 E13. Explicar que realizan las funciones. ......................................................................................... 34 E14. Describir un multirbol ............................................................................................................ 34 36 Estructuras de Datos y AlgoritmosProfesor Leopoldo Silva Bijit26-05-2008 NDICE GENERAL. .................................................................................................................................... 35 NDICE DE FIGURAS. ................................................................................................................................ 36 ndice de figuras. FIGURA 2.1. AGRUPACIONES DE DATOS. ........................................................................................................ 2 FIGURA 2.2.VNCULOS ENTRE COMPONENTES DE DATOS. ............................................................................ 2 FIGURA 2.2.A. MATRIZ DE CARACTERES ...................................................................................................... 4 FIGURA 2.2.B. ARREGLO DE PUNTEROS A ARREGLOSDE CARACTERES ........................................................ 5 FIGURA 2.3. LISTA SIMPLEMENTE ENLAZADA. ............................................................................................... 7 FIGURA 2.4. LISTA SIMPLEMENTE ENLAZADA, MEDIANTE PUNTEROS. ........................................................... 9 FIGURA 2.5. ARREGLO DE LISTAS. ............................................................................................................... 10 FIGURA 2.6. MULTIRBOL. .......................................................................................................................... 11 FIGURA 2.7. PRIMER DESCENDIENTE IZQUIERDO, HERMANO DERECHO. ....................................................... 12 FIGURA 2.8. MULTIRBOL MEDIANTE ARREGLO DE CURSORES. .................................................................. 13 FIGURA 2.9. MULTIRBOL MEDIANTE ARREGLO DE PADRES. ....................................................................... 14 FIGURA 2.10 ARREGLO DE PADRES. ............................................................................................................. 14 FIGURA P2.1. ............................................................................................................................................... 17 FIGURA P2.2. ............................................................................................................................................... 17 FIGURA P2.3 ................................................................................................................................................ 18 FIGURA P2.4 ................................................................................................................................................ 18 FIGURA P2.5. ............................................................................................................................................... 19 FIGURA P2.6. ............................................................................................................................................... 23 FIGURA P2.7. ............................................................................................................................................... 24 FIGURA P2.8. ............................................................................................................................................... 24 FIGURA P2.9. ............................................................................................................................................... 24 FIGURA P2.10. ............................................................................................................................................. 24 FIGURA P2.11. ............................................................................................................................................. 25 FIGURA P2.12. ............................................................................................................................................. 25 FIGURA P2.13. ............................................................................................................................................. 26 FIGURA P2.13. ............................................................................................................................................. 27 FIGURA P2.14. ............................................................................................................................................. 27 FIGURA P2.15. ............................................................................................................................................. 28 FIGURA P2.16. ............................................................................................................................................. 28 FIGURA P2.17. ............................................................................................................................................. 29 1 Profesor Leopoldo Silva Bijit26-05-2008 Captulo 3 Administracin de la memoria en C. Los datos se almacenan en uno de los tres segmentos de memoria que el programador dispone. La zona esttica para datos, que permite almacenar variables globales durante la ejecucin de un programa. Elstackquepermitealmacenarlosargumentosyvariableslocalesdurantelaejecucindelas funciones. Elheapquepermitealmacenarvariablesadquiridas dinmicamentedurante la ejecucin deun programa. esttica heap stack Direcciones bajasDirecciones altas Figura 3.1. Segmentos de memoria. Los segmentos son provistos por el sistema operativo. 3.1. Manejo esttico de la memoria. La zona esttica para datos, permite almacenar variables globales y estticas. Siseencuentraunavariabledefinidafueradelasfunciones,selaconsideraglobal;el compiladorleasignaunespaciodeterminadoygeneralareferenciaparaaccesarlaenlazona esttica.Eltamaodelasvariablesnopuedecambiarsedurantelaejecucindelprograma,es asignado en forma esttica. El tiempo de vida de las variables de la zona esttica es la duracin del programa. Estas variables son visibles para todas las funciones que estn definidas despus de ellas. 2 Estructuras de Datos y AlgoritmosProfesor Leopoldo Silva Bijit26-05-2008 Si se precede con la palabra static a una variable local a una funcin, sta tambin es ubicada en lazonaesttica,yexistedurantelaejecucindelprograma;nodesaparecealterminarla ejecucin de la funcin, y conserva su valor, entre llamados a la funcin. 3.2. Manejo automtico de la memoria en C. 3.2.1. Asignacin, Referencias y tiempo de vida. Elcompiladorasignaunespaciodeterminadoparalasvariablesygeneralasreferenciaspara accesar a las variables del stack y de la zona esttica. El tamao de las variables de estas zonas no puede cambiarse durante la ejecucin del programa, es asignado en forma esttica. El tiempo de vida de las variables de la zona esttica es la duracin del programa; las variables denominadas automticas, o en la zona del stack, existen durante la ejecucin de la funcin que las referencia. Los argumentos y variables locales, son asignados y desasignados en forma dinmica durante la ejecucin de las funciones; pero en forma automtica, el programador no tiene responsabilidad en ese proceso. Estaorganizacinpermitedireccionareficientementevariablesquesernusadas frecuentemente;alavezposibilitaahorrarespaciodedireccionamientoyaquesepuede reutilizar el espacio de memoria dedicado a la funcin cuando sta termina; y tambin posibilita el diseo de funciones recursivas y reentrantes, asociando un espacio diferente para las variables por cada invocacin de la funcin.

Es importante notar que varias funciones pueden emplear los mismos nombres para las variables localesyargumentosyestonoprovocaconfusin;existeindependenciatemporaldelas variables de una funcin. Si se emplea una global, con igual nombre que una local, dentro de la funcin se ve la local; y fuera existe la global. Porlamismarazn,nopuedencomunicarselosvaloresdevariableslocalesdeunafuncina otra. Cuando un programa se carga en la memoria, desde el disco, slo se traen la zona de cdigos y losdatosdelazonaesttica.Laszonasdestackyheap,soncreadasenmemoriaantesdela ejecucin del programa. 3.2.2. Argumentos y variables locales. Cadafuncinalserinvocadacreaunframeo registrodeactivacinenelstack,enel cualse almacenanlosvaloresdelosargumentosydelasvariableslocales.Losvaloresdelos argumentossonescritosenmemoria,antesdedarinicioalcdigoasociadoalafuncin.Es responsabilidad de la funcin escribir valores iniciales a las variables locales, antes de que stas sean utilizadas; es decir, que aparezcan en expresiones en donde se leen estas variables. Manejo de la memoria en C.3 Profesor Leopoldo Silva Bijit26-05-2008 Ejemplo 3.1. Funcin con dos argumentos de tipo valor, con dos locales, retorno de entero. Lasiguientedefinicindefuncin,tieneargumentos,variableslocalesyunretornodetipo entero. int funcin1(int arg1, int arg2) { int local1; int local2=5; /* no puede usarse local1 para lectura, por ejemplo: local2=local1+2; es un error*/ local1=arg1 + arg2 + local2; return ( local1+ 3); }A continuacin un ejemplo de uso de la funcin. Si una variable x, se define fuera de las funciones, se la considera global y se le asigna espacio en la zona esttica. Si en el texto escrito, su definicin aparece antes de la funcin1, se dice que es visible por sta, o que est dentro del alcance de la funcin. int x=7; /*En este punto an no existen las variables: local1, local2, arg1 y arg2.*/ x = funcin1(4, 8); /*Desde aqu en adelante no existe espacio asociado a los argumentos y variables locales de la funcin 1 */ El diagrama de la Figura 3.1, ilustra el espacio de memoria asignado a las variables, despus de invocada la funcin y justo despus de la definicin de la variables local2. La variable local1, no est iniciada y puede contener cualquier valor. Figura 3.1a. Stack despus de invocar a la funcin Al salir de la funcin, el espacio de memoria asignado a las variables, puede visualizarse segn: local1 local2 arg1 arg2 Frame de funcin1 5 4 8 x Stack 7 Zona esttica 4 Estructuras de Datos y AlgoritmosProfesor Leopoldo Silva Bijit26-05-2008 Figura 3.2. Stack al salir de la funcin. 3.2.3. Visin lgica del stack. Losdiagramasanterioresdescribenlgicamenteelespacioasignadoenlamemoriaparalas variables estticas y automticas.Cada compilador implementa fsicamente la creacin de estos espaciosdemaneradiferente;enelframedelafuncinsesuelenalmacenar:ladireccinde retorno,losvaloresdelosregistrosquelafuncinnodebealterar;ademsdelespaciopara localesyargumentos.Adicionalmentecadacompiladorestablececonveniosparapasarlos valoresyobtenerelretornodelafuncin,enalgunoscasoslohaceatravsderegistros,en otras a travs del stack. El uso detallado del stack segn lo requiere un programador assembler es cubierto en cursos de estructuras de computadores. Sedescribeaquunavisualizacinlgicadelsegmentodelstack,queeslaquerequiereun programador en lenguajes de alto nivel. Ejemplo 3.2. Riesgos de la desaparicin del frame. La siguiente funcin plocal retorna un puntero a una variable local, lo cual es un gran error, ya que al salir de la funcin, deja de existir la local; y el puntero retornado apunta a una direccin del stack que no est asignada. int* plocal(void){ int local; // **** return(&local); // retorna puntero a local } La funcin que invoca a plocal posiblemente produzca una falla seria del programa, o generar un error de difcil depuracin. Tampocopuedetomarseladireccindeunavariablelocal,declaradadetiporegistro.Yaque los registros no tienen asociada una direccin de la memoria.El calificar una variable local o a unargumentodetiporegister,esunaindicacinparaqueelcompiladorintenteemplear registros en su manipulacin, con ventajas temporales de acceso. x Stack 20 Zona esttica Manejo de la memoria en C.5 Profesor Leopoldo Silva Bijit26-05-2008 3.2.4. Copia de argumentos. Puedellamarseaunafuncinconlosvaloresdelosargumentosovariableslocales(oms generalmente mediante una expresin de stas) de otra funcin. Sin embargo la funcin que es llamada, crea una copia de los valores de sus argumentos, en su propio frame.Lo cual garantiza laindependenciadefuncionamiento delasfunciones, yaqueunafuncin quees invocadapor otra, puede cambiar sus argumentos sin alterar los argumentos de la que la invoc. A su vez esta organizacin implica crear la copia, lo cual puede ser muy costoso en tiempo si el tipodelargumentotieneun grantamaoenbytes. Parasolucionar el problemadelacopia,se puedepasarunareferenciaaunargumentodegrandesdimensiones,estoselograpasandoel valor de un puntero (se copia el valor del puntero, el cual ocupa normalmente el tamao de un entero). Esto se ver en pasos de argumentos por referencia. Ejemplo 3.3. Una funcin f que invoca a otra funcin g.Setienenlassiguientesdefinicionesdelasfunciones.Ntesequelosnombresdelos argumentos y una de las locales tienen iguales nombres. int g(int a, int b) { int c; printf("Al entrar en g:a = %d b = %d\n", a, b); a = a + b;/*cambia argumento a */ c = a + 4; printf("Antes de salir de g:a = %d b = %dc = %d \n", a, b, c); return( c ); } int f(int a, int b) { int c; int d=5; c = a+b+d; printf("Antesdeg: a = %d b = %dc = %d d = %d \n", a, b, c, d); d = g( a, b+c ); /*se copian los valores en el frame de g*/ a = a + d; b = b + a; printf("Despus de g: a = %d b = %dc = %d d = %d \n", a, b, c, d); return( d + 2); } Si consideramos x definida en la zona esttica, el siguiente segmento: x=3; x=f(5,6); printf(" x = %d \n", x); Genera la siguiente salida. Antesdeg: a = 5 b = 6c = 16 d = 5Al entrar en g:a = 5 b = 22 6 Estructuras de Datos y AlgoritmosProfesor Leopoldo Silva Bijit26-05-2008 Antes de salir de g:a = 27 b = 22c = 31Despus de g: a = 36 b = 42c = 16 d = 31 x = 33 Se ilustran los frames, con el estado de las variables, despus de los printf. Antes de invocar a g, se tiene el esquema de la Figura 3.3: local1 c local2 d arg1 a arg2 b Frame de f 16 5 5 6 x Stack 3 Zona esttica Figura 3.3. Stack antes de invocar a la funcin g. Al entrar en g, se copian valores en los argumentos. Los frames se apilan hacia arriba, lo cual se muestra en la Figura 3.4. local1 c arg1 b arg2 a Frame de g ? 22 5 x Stack 3 Zona esttica local1 c local2 d arg1 a arg2 b Frame de f 16 5 5 6 Frame activo Figura 3.4. Al entrar en la funcin g. Manejo de la memoria en C.7 Profesor Leopoldo Silva Bijit26-05-2008 Antes de salir de la funcin g: local1 c arg1 b arg2 a Frame de g 31 22 27 x Stack 3 Zona esttica local1 c local2 d arg1 a arg2 b Frame de f 16 5 5 6 Frame activo Figura 3.5. Stack justo antes de salir de la funcin g. Al salir de la funcin g, ya no est disponible el frame de g, y el frame activo es el de la funcin f: local1 c local2 d arg1 a arg2 b Frame de f 16 31 36 42 x Stack 3 Zona esttica Figura 3.6. Stack al salir de la funcin g. Al salir de la funcin f, se desvanece su frame, como se ilustra en la Figura 3.7: 8 Estructuras de Datos y AlgoritmosProfesor Leopoldo Silva Bijit26-05-2008 x Stack 33 Zona esttica Figura 3.7. Stack al salir de la funcin f. Ejemplo 3.4. La misma funcin anterior invocada dos veces. Veamos un caso en el cual se ejecuta dos veces la misma funcin1, del Ejemplo 3.1. int x=4; x = funcin1(4, funcin1(2,3)) + x; Se ilustra un diagrama del espacio, cuando ha terminado la ejecucin de la asignacin a local1, dentro de la ejecucin de la funcin, pero antes de salir por primera vez de sta. Los frames se apilan hacia arriba, en la grfica. Se ha marcado como activo, el frame de la segunda invocacin a la funcin1. Siunafuncininvocaaotra,enestecasoinvocaalamismafuncin,mantienesuslocalesy argumentos. Dichas variables existen hasta el trmino de la ejecucin de la funcin. local1 local2 arg1 arg2 Frame de segunda invocacin a funcin1 10 5 2 3 x Stack 4 Zona esttica local1 local2 arg1 arg2 Frame de funcin1 ? ? 4 ? Frame activo Figura 3.8. Stack despus de la segunda invocacin a f. Manejo de la memoria en C.9 Profesor Leopoldo Silva Bijit26-05-2008 Una vez que retorna, por primera vez de la funcin, se tiene el valor 13 de arg2, de la primera invocacin,ydesapareceelframequesecreenlasegundainvocacin.Seilustralazona despus de la asignacin a local1. local1 local2 arg1 arg2 Frame de funcin1 22 5 4 13 x Stack 4 Zona esttica Figura 3.9. Al salir de la segunda invocacin. Finalmente queda x con valor 29, y no est disponible el frame de la funcin en el stack. 3.2.4. Recursin. Laorganizacindelasvariablesautomticas,atravsdeunstack,permiteeldesarrollode algoritmos recursivos. Se define recursin como un proceso en el cual una funcin se llama a smisma repetidamente, hasta que se cumpla determinada condicin. Un algoritmo recursivo puede usarse para computaciones repetitivas, en las cuales cada accin se plantea en trminos de resultados previos. Dos condiciones deben tenerse en cuenta en estos diseos: Una es que cada llamado a la funcin conduzca a acercarse a la solucin del problema; la otra, es que se tenga un criterio para detener el proceso. En general los diseos recursivos requieren ms espacio de memoria y ocupan mayor tiempo en ejecutarse.Sinembargogenerandiseossimplescuandolasestructurasdedatosquedan naturalmente definidas en trminos recursivos. Es el caso de los rboles yde algunas funciones matemticas. Larecursinesunmtodopararesolverproblemasenformajerrquica(top-down),separte reduciendo el problema final (top) en partes ms simples, hasta llegar a un caso (bottom), en el cual se conoce la solucin; y se devuelve ascendiendo hasta el tope, calculando con los valores que se van obteniendo. Cada vez que se activa una invocacin de una funcin recursiva, se crea espacioparasusvariablesautomticasenunframe;esdecircadaunatienesuspropias variables. El cambio de las locales de una invocacin no afecta a las locales de otra invocacin queestpendiente(quetengaansuframeenelstack).Lasdiferentesencarnacionesdelas funciones se comunican los resultados a travs de los retornos. 10 Estructuras de Datos y AlgoritmosProfesor Leopoldo Silva Bijit26-05-2008 En un procedimiento iterativo, tambin denominado bottom-up, se parte de la base conocida y se construye la solucin paso a paso, hasta llegar al caso final. Msadelanteveremosunaestructurabsicadedatos,denominadastackdeusuario(no confundirconelstackquemanejalasvariablesautomticas).Sepuededemostrarqueun algoritmorecursivosiempresepuedeplantearenformaiterativaconlaayudadelstackde usuario.Yunprogramaiterativo,querequieradeunstackdeusuario,sepuedeplantearen forma recursiva (sin stack). Siexisteunaformarecursivaderesolverunproblema,entoncesexistetambinunaforma iterativa de hacerlo; y viceversa. Consideremoslafuncinmatemticafactorial,quetradicionalmenteestdefinidaenforma recursiva (a travs de s misma). factorial( 0 ) = 1 factorial( n ) = n * factorial( n-1 ) La condicin para detener la recursin, el caso base, es que factorial de cero es uno. Tambin se puede detener con factorial(1) = 1. Ejemplo 3.5. Diseo recursivo. El siguiente diseo recursivo, condiciona la re-invocacin de la funcin cuando se llega al caso base: unsigned int factorial( unsigned int n) { if ( n==0) return (1); else return n*factorial(n-1); } El diseo est restringido a valores de n positivos y pequeos; yaque existe un mximo entero representable, y la funcin factorial crece rpidamente. Si se invoca: factorial(4), se producen cinco frames en el stack.Elltimoframeesproducidoporlainvocacin defactorial(0), hasta ese momento ningunade lasfuncionesharetornado(todasestnejecutandolaaccinasociadaalelse,peronopueden retornar ya que requieren para calcular el producto, el valor de retorno de la funcin).Existencincoargumentos,denombren,convaloresdiferentes.Laejecucin,delcasobase (n=0), no invoca nuevamente a la funcin, ya que sta est condicionada, y retorna el valor 1; lo cualdesactivaelframeconn=0,ypasaacompletarlaejecucindelllamadofactorial(1)que estaba pendiente. En este momento: conoce n, que es uno, y el valor retornado por factorial(0), que tambin es uno; entonces retorna 1, y elimina el frame.Sigue la ejecucin de factorial(2) del mismo modo, hasta eliminar el ltimo frame, retornando el valor 24. Manejo de la memoria en C.11 Profesor Leopoldo Silva Bijit26-05-2008 Ejemplo 3.6. Diseo iterativo. Similar clculo se puede realizar en forma iterativa. unsigned int factorial(unsigned int n){int i; unsigned int producto = 1; for (i = 1; i right != NULL)T = T->right; /* Iterativo. Siempre por la derecha */ return(T); } La funcin considera que se la podra invocar con un argumento apuntando a un rbol vaco, en ese caso se decide retornar un puntero con valor nulo, que indica un rbol (o subrbol vaco). Teniendoencuentalapropiedaddelrbolbinario,bastadescenderporlavaderecha,hasta encontrar un nodo sin descendiente u hoja. Un ejemplo de uso: pn = busca_max(raiz); En el caso del ejemplo, retornara un puntero al nodo con valor 8. Otro ejemplo de uso: pn = busca_max(raiz->left); Retornara un puntero al nodo con valor 1. Ejemplo 3.10 Manipulacin de strings. Veremos la forma de tratar funciones que manipulen arreglos o strings. Antes de desarrollar el ejemplo repasaremos la estructura de datos asociada a un string. Definicin de string. a) Arreglo de caracteres. La siguiente definicin reserva espacio para un string como un arreglo de caracteres. La definicindeunstringcomo arreglodecaracteres, debe incluir un espacio parael carcter fin de string (el carcter NULL, con valor cero). Quizs es mejor definir el terminador de string como null (o eos:end of string), para evitar confusiones con el valor de un puntero nulo. Manejo de la memoria en C.17 Profesor Leopoldo Silva Bijit26-05-2008 char str[6];/*crea arreglo de chars con espacio para 6 caracteres. ndice vara entre 0 y 5*/ str[5] = NULL;//coloca el fin de string. str \0 Figura 3.11. Representacin en memoria de un string. Conladefinicinanteriorelstringalmacenadoenelarreglopuedetenerunlargomximode cinco caracteres. El nombre del arreglo str, es un puntero constante que apunta al primer carcter del string, por serconstantenoselepuedeasignarnuevosvaloresomodificar.Lasdireccionesdememoria deben considerarse consecutivas; en la direccin ms alta se almacena el fin de string. b) Puntero a carcter. Ladefinicindeunstringcomounpunteroacarcter,puedeserinicializadaasignndoleuna constantedetipostring.Laquesedefinecomounasecuenciadeceroomscaracteresentre comillas dobles; el compilador agrega el carcter \0 automticamente al final.Si dentro del string se desea emplear la comilla doble debe precedrsela por un \. En caso de escribir, en el texto de un programa, un string de varias lneas, la secuencia de un \ y el retorno de carro (que es invisible en la pantalla) no se consideran parte del string. char * str1 = "123456789"; /* tiene 10 caracteres, incluido el NULL que termina el string.*/ Un argumento de tipo puntero a carcter puede ser reemplazado en una lista de parmetros, en ladefinicindeunafuncinporunarreglo decaracteres sin especificar el tamao.En el caso delejemploanterior,podraescribirse:charstr1[].Laeleccinentreestasalternativassuele realizarsesegnseaeltratamientoqueserealicedentrodelafuncin;esdecir,silas expresiones se elaboran en base a punteros o si se emplea manipulacin de arreglos. En la variable str1 se almacena la direccin de la memoria en donde se almacena el primer byte del string, el cual en este caso es el nmero 1, con equivalente hexadecimal 0x31. Ntese que str ocupa el espacio con que fue definido el arreglo, mientras que str1 es un puntero. 18 Estructuras de Datos y AlgoritmosProfesor Leopoldo Silva Bijit26-05-2008 str1 1 2 3 4 5 6 7 8 9 \0 Figura 3.12. Puntero a carcter y el string vinculado. c)Strcpy. Copia el stringfuente en el string destino.Se detiene la copia despus de haber copiado el carcter nulo del fin del string. Retorna la direccin del string destino. char *strcpy(char * destino, register const char * fuente) { register char * cp= destino; while(*cp++ = *fuente++) continue; return destino; } Losargumentosyvalorderetornosonpunterosacarcter.Locualevitalacopiadelos argumentos.Acontinuacinsedanexplicacionesdediversosaspectosdelasintaxisdel lenguaje. fuentecp destino Figura 3.13. Copia de string. Eldiagramailustralospunterosfuenteycp,despus dehaberserealizadolacopiadelprimer carcter. Se muestra el movimiento de copia y el de los punteros. Cuando el contenido de *fuente es el carcter NULL, primero lo copia y la expresin resultante delaasignacintomavalorcero,quetienevalorfalsoparalacondicin,terminandoellazo while. Copiando correctamente un string nulo. Manejo de la memoria en C.19 Profesor Leopoldo Silva Bijit26-05-2008 Lainstruccincontinuepuedeaparecerenelbloquedeaccionesdeunwhile,doofor.Su ejecucinllevaareevaluarlacondicindecontinuacindelbloquederepeticinmsinterno (encasodebloquesanidados).Enelcasodelafuncinanteriorpodrahaberseomitidola instruccin continue; ya que un punto y coma se considera una accin nula. Eloperadordepostincrementooperasobreunleftvalue(querecuerdaunvalorquepuede colocarse a la izquierda de una asignacin). Un lvalue es un identificador o expresin que est relacionado con un objeto que puede ser accesado y cambiado en la memoria. Elusodeestosoperadoresenexpresionesproduceunefectolateral,enelsentidoquese efectandosacciones.Primeroseusaelvalordelobjetoenlaexpresinyluegostees incrementado en uno. Eloperadordeindireccin(el*)yeloperador++tienenlamismaprecedencia,entoncesse resuelve cul operador recibe primero el operando mediante su asociatividad, que en el caso de los operadores unarios es de derecha a izquierda.Es decir *fuente++ se interpreta segn: ( * (fuente++) ) . La expresintomael valordelpunterofuentey lo indirecciona,posteriormente incrementaen uno al puntero. Enlaexpresin(*fuente)++,medianteelusodeparntesissecambialaasociatividad,la expresin toma el valor del objeto apuntado por fuente, y luego incrementa en uno el valor del objeto, no del puntero. Puede evitarse la accin doble relacionada con los operadores de pre y postincremento, usando stosenexpresionesqueslocontengandichosoperadores.Enelcasodelaaccinde repeticin: while(*cp++ = *fuente++) continue;

Puede codificarse:while( *cp = *fuente) {cp++, fuente++}; Sinembargolosprogramadoresnosuelenemplearestaforma.Adicionalmentenoproducen igualresultado,yaqueenlaprimeraformalospunterosquedanapuntandounaposicinms alldeloscaracteresdefindestring;lasegundaformadejalospunterosapuntandoalos terminadores de los strings. Ambas formas satisfacen los requerimientos de srtcpy.

La primera forma slo tendra ventajas si el procesador tiene mecanismos de direccionamientos autoincrementados, y si el compilador emplea dichos mecanismos al compilar la primera forma. Cuando en la lista de parmetros de una funcin aparece la palabra reservada const precediendo a una variable de tipo puntero, el compilador advierte un error si la funcin modifica la variable a la que el puntero apunta. Adems cuando se dispone de diferentes tipos de memorias (RAM, EEPROMoFLASH)localizalasconstantes enROMoFLASH.Sisedeseaquequede enun segmento de RAM, se precede con volatile, en lugar de const. 20 Estructuras de Datos y AlgoritmosProfesor Leopoldo Silva Bijit26-05-2008 Nosevalidasielespacioacontinuacindedestinopuedealmacenarelstringfuentesin sobreescribir en el espacio asignado a otras variables.Este es un serio problema del lenguaje, y se lo ha empleado para introducir cdigo malicioso en aplicaciones que no validen el rebalse de buffers. Esta funcin tiene su prototipo definido en Un ejemplo de uso. #include #include char string[10];/*crea string con espacio para 10 caracteres*/ char * str1 = "abcdefghi"; /* tiene 10 caracteres, incluido el NULL que termina el string.*/ int main(void) { strcpy(string, str1); printf("%s\n", string); printf(str1); //sin string de formato return 0; }

Notequeenlainvocacin se pasan losnombres delosstrings,quesonconsiderados punteros constantes. En lugar de string, se podra haber escrito:&string[0]. No se ocupa el retorno de la funcin, en este caso se usa como procedimiento no como funcin. Arreglosdegrandesdimensionesnoconvienedefinirlosdentrodelafuncin,yaquepodran producir un rebalse del stack; es preferible definirlos en zona esttica o en el heap. Tradicionalmentesemencionaqueeldiseodestrcpypuedeserdifcildeentender.Se muestran a continuacin, dos diseos basados en arreglos; y su evolucin a cdigos basados en punteros. void strcpy1(char destino[], const char fuente[]) {int i = 0; while (1) { destino[i] = fuente[i]; if (destino[i] == '\0') break; // copi fin de string i++; } } Debido a que en el lenguaje C, la asignacin es una expresin, y por lo tanto tiene un valor, se puede escribir: Manejo de la memoria en C.21 Profesor Leopoldo Silva Bijit26-05-2008 void strcpy2(char destino[], const char fuente[]){int i = 0; while ((destino[i] = fuente[i]) != '\0') i++; } // Moviendo los punteros. Resolviendo precedencia por asociatividad.void strcpy3(char *destino, const char *fuente) { while ((*destino++ = *fuente++) != '\0') ; //Trae el valor, luego incrementa puntero. } // Finalmente el fin de string '\0' equivale a valor lgico falso void strcpy4(char *destino, const char *fuente) {while (*destino++ = *fuente++) ; } Las versiones 3 y 4, reflejan en sus argumentos que el diseo est basado en punteros. Laltimaversin,strcpy4puedeserdifcildeentender.Empleandouncompiladorque optimice el cdigo assembler en velocidad, entrega costos similares para los cuatro diseos. ElassembleresparaelmicrocontroladorMSP430,elquedisponedeinstruccionescon autoincrementos. strcpy1o2:mov.b @R14+, 0x0(R12);M[R12] = M[R14]; R14++; mov.b @R12+, R15;R15 = M[R12]; R12++; tst.bR15;test de R15; jne strcpy1o2;Si R15 no es igual a cero repite bloque ret ;Si R15 es cero retorna strcpy3o4:mov.b @R14+, R15; R15= M[R14]; R14++; mov.b R15, 0x0(R12); M[R12] = R15 inc.wR12; R12++; tst.bR15 jnestrcpy3o4 ret En este caso la versin mediante arreglos emplea una instruccin menos que las versiones con punteros.Ladecisindecualeselmejorcdigoresultardelacomparacindelosciclosde relojquetardalaejecucindelasinstruccionesdelbloquerepetitivo,yaquecadainstruccin puede durar diferentes ciclos de reloj. La invocacin a las funciones se logra pasando los argumentos va registros R12 y R14. 22 Estructuras de Datos y AlgoritmosProfesor Leopoldo Silva Bijit26-05-2008 mov.w#str1, R10; direccin de str1 (destino) en R10 mov.w#str2, R11 ; direccin de str2 (fuente) en R11 mov.w @R11,R14; R14 = M[R11] = contenido str2 mov.w @R10,R12; R12 = M[R10] = contenido str1 callstrcpy La moraleja de esto es escribir cdigo del cual se tenga seguridad de lo que realiza. Y dejar a los compiladores optimizantes el resto. 3.3. Manejo dinmico de la memoria en C. 3.3.1. Asignacin, Referencias y tiempo de vida. Elcompiladorasignaunespaciodeterminadoparalasvariablesygeneralasreferenciaspara accesaralasvariablesdelstackydelazonaesttica.Eltamaodelasvariablesnopuede cambiarse durante la ejecucin del programa, es asignado en forma esttica. El tiempo de vida de las variables de la zona esttica es la duracin del programa; las variables denominadas automticas, o en la zona del stack, existen durante la ejecucin de la funcin que las referencia. Los frames en el stack, son asignados y desasignados en forma dinmica durante laejecucindelasfunciones;peroenformaautomtica,elprogramadornotiene responsabilidad en ese proceso. Enelheapelprogramadordebesolicitarlaasignacindeespacio,establecerlasreferencias entreelespacioasignadoylasvariablesenlasotraszonas,liberarelespacio,desasignarlas referencias. Cualquier equivocacin lleva a errores, en tiempo de ejecucin, difciles de depurar. Este mecanismo permite al programador tener un mayor control de la memoria, tanto en tamao comoentiempodevida,peroalmismotiempoledalaresponsabilidaddeadministrarla correctamente. Un arreglo en la zona esttica debe ser definido con un tamao determinado, el cualnopuedecambiardurantelaejecucindelprograma,sinembargoenelheapsepuede solicitar un arreglo del tamao que se desee, siempre que no exceda el tamao mximo asignado al heap. Escribirprogramasquemanejenelheapesnotablementemsdifcil,porestaraznlenguajes msmodernosefectanautomticamentelaprogramacindelheap,ynolepermitenal programador realizar esta tarea.Algunos errores de programas que manejan el heap, compilan correctamente, sin embargo al ejecutarlos se producen errores difciles de depurar. 3.3.2. Funciones para el manejo del heap. Enestnlosprototiposdelasfuncionesdebibliotecaqueasignanydesasignan bloques de memoria. Describiremos las dos fundamentales. Manejo de la memoria en C.23 Profesor Leopoldo Silva Bijit26-05-2008 3.3.2.1. void * malloc(size_t tamao) Solicita un bloque contiguo de memoria del segmento heap, del tamao especificado en bytes, y retornaunpunterodetipogenrico,elcualpuedesermoldeado(cast)acualquiertipo determinado,aliniciodelbloque;retornaNULLsinoexistenbloquesdeltamaosolicitado dentro del heap. El programador debe asignar el valor retornado a una variable de tipo puntero, estableciendo la referencia; dicho puntero debe existir en alguna de las otras zonas de memoria.La nica forma de establecer la referencia es mediante un puntero, que inicialmente debe apuntar a NULL. Elcontenidodelbloquedebeserinicializadoantes deserusado,yaqueinicialmentecontiene los valores que estaban previamente almacenados en el bloque del heap. Suele emplearse el operadorsizeof(tipo o nombre_de_variable) que retorna un valor entero sin signo con el nmero de bytes con que se representa el tipo o la variable, para calcular el tamao del bloque que debe solicitarse. 3.3.2.2. void free(void * puntero) Freeliberaelbloqueapuntadoporpunteroylodevuelvealheap.Elvalordelpunterodebe haber sido obtenido a travs de malloc; produce errores difciles de depurarinvocar a freecon un puntero no devuelto por malloc. Despusdeejecutarfree,elprogramadornopuedevolverareferenciardatosatravsdeese puntero;deberaasignarleNULL,paraprevenirerrores.Tampocopuedeliberarseunbloque ms de una vez. Esimportanteliberar elbloquecuandoelprogramanosigautilizandolosdatosquealmacen en el bloque, de esta forma puede volver a utilizarse dicho espacio. En caso de no hacerlo, van quedando bloques inutilizables en el heap, lo cual origina en el largo plazola fragmentacin y finalmente el rebalse de ste. Eladministradordelheap,queesinvocadoatravsdelasfuncionesanteriores,mantienesus propias estructuras de datos en las cuales registra los bloques que estn ocupados y los que estn disponibles,ytambineltamaodelosbloques.Tambininteractaconelsistemaoperativo para solicitar memoria adicional en caso de crecimiento del heap. Ejemplo 3.11. Arreglo dinmico de enteros. Elsiguienteejemploempleaunafuncinparacrear,usaryliberarunarreglodinmicode enteros de tamao determinado por el argumento size de la funcin. 24 Estructuras de Datos y AlgoritmosProfesor Leopoldo Silva Bijit26-05-2008 void UsaArregloDinmico(unsigned int size) { int * Arreglo; int i; /*Usar el arreglo antes de asignarlo, provoca errores */ if ( (Arreglo = (int *) malloc(size * sizeof(int)) ) == NULL) { printf ("Memoria insuficiente para Arreglo\n"); exit(1); } /* Se puede usar el Arreglo. Pero sus valores no estn iniciados.*/ for(i=0; ivalor=dato; pn->left=NULL; pn->right=NULL; } return(pn); } void LiberaNodo( pnodo pn) { free( pn); //Libera el espacio } El siguiente segmento ilustra el uso de las funciones. pnodo root=NULL;/* el espacio de la variable root existe desde su definicin. root=CreaNodo(5);//se pega el nodo a la raz LiberaNodo(root); 28 Estructuras de Datos y AlgoritmosProfesor Leopoldo Silva Bijit26-05-2008 ndice general. CAPTULO 3 .............................................................................................................................................. 1 ADMINISTRACIN DE LA MEMORIA EN C. .................................................................................... 1 3.1. MANEJO ESTTICO DE LA MEMORIA. .................................................................................................. 1 3.2. MANEJO AUTOMTICO DE LA MEMORIA EN C. .................................................................................... 2 3.2.1. Asignacin, Referencias y tiempo de vida. ................................................................................. 2 3.2.2. Argumentos y variables locales. ................................................................................................ 2 Ejemplo 3.1. Funcin con dos argumentos de tipo valor, con dos locales, retorno de entero. ......................... 3 3.2.3. Visin lgica del stack. .............................................................................................................. 4 Ejemplo 3.2. Riesgos de la desaparicin del frame. ......................................................................................... 4 3.2.4. Copia de argumentos. ................................................................................................................ 5 Ejemplo 3.3. Una funcin f que invoca a otra funcin g. ................................................................................. 5 Ejemplo 3.4. La misma funcin anterior invocada dos veces........................................................................... 8 3.2.4. Recursin. .................................................................................................................................. 9 Ejemplo 3.5. Diseo recursivo. ...................................................................................................................... 10 Ejemplo 3.6. Diseo iterativo. ........................................................................................................................ 11 3.2.6. Parmetros pasados por referencia y valor nico de retorno. ................................................ 11 Ejemplo 3.7. Comunicacin del valor retornado por una funcin. ................................................................. 11 Ejemplo 3.8. Se desea disear funcin que retorne dos resultados. ............................................................... 12 Paso por referencia. ................................................................................................................................... 12 Retorno de estructura. ............................................................................................................................... 13 Retorno en arreglo. .................................................................................................................................... 14 3.2.6. Evitacin de la copia de argumentos que ocupan muchos bytes. ............................................ 15 Ejemplo 3.9. rbol binario. ............................................................................................................................ 15 Ejemplo 3.10 Manipulacin de strings. .......................................................................................................... 16 Definicin de string. .................................................................................................................................. 16 a) Arreglo de caracteres. ............................................................................................................................ 16 b) Puntero a carcter. ................................................................................................................................. 17 c)Strcpy. Copia el stringfuente en el string destino. .............................................................................. 18 3.3. MANEJO DINMICO DE LA MEMORIA EN C. ....................................................................................... 22 3.3.1. Asignacin, Referencias y tiempo de vida. ............................................................................... 22 3.3.2. Funciones para el manejo del heap. ........................................................................................ 22 3.3.2.1. void * malloc(size_t tamao) ............................................................................................................ 23 3.3.2.2. void free(void * puntero) .................................................................................................................. 23 Ejemplo 3.11. Arreglo dinmico de enteros. ............................................................................................. 23 Ejemplo 3.12. Strings dinmicos. .............................................................................................................. 25 Ejemplo 3.13. Matriz de enteros, de r renglones y n columnas. ................................................................ 25 Ejemplo 3.14. Crear nodo de un rbol binario. .......................................................................................... 26 NDICE GENERAL. .................................................................................................................................... 28 NDICE DE FIGURAS. ................................................................................................................................ 29 Manejo de la memoria en C.29 Profesor Leopoldo Silva Bijit26-05-2008 ndice de figuras. FIGURA 3.1. SEGMENTOS DE MEMORIA. ........................................................................................................ 1 FIGURA 3.1A. STACK DESPUS DE INVOCAR A LA FUNCIN ........................................................................... 3 FIGURA 3.2. STACK AL SALIR DE LA FUNCIN. .............................................................................................. 4 FIGURA 3.3. STACK ANTES DE INVOCAR A LA FUNCIN G. ............................................................................ 6 FIGURA 3.4. AL ENTRAR EN LA FUNCIN G. .................................................................................................. 6 FIGURA 3.5. STACK JUSTO ANTES DE SALIR DE LA FUNCIN G. ..................................................................... 7 FIGURA 3.6. STACK AL SALIR DE LA FUNCIN G. ........................................................................................... 7 FIGURA 3.7. STACK AL SALIR DE LA FUNCIN F. ........................................................................................... 8 FIGURA 3.8. STACK DESPUS DE LA SEGUNDA INVOCACIN A F. ................................................................... 8 FIGURA 3.9. AL SALIR DE LA SEGUNDA INVOCACIN. ................................................................................... 9 FIGURA 3.10. RBOL BINARIO. ................................................................................................................... 15 FIGURA 3.11. REPRESENTACIN EN MEMORIA DE UN STRING. .................................................................... 17 FIGURA 3.12. PUNTERO A CARCTER Y EL STRING VINCULADO. ................................................................. 18 FIGURA 3.13. COPIA DE STRING. ................................................................................................................. 18 FIGURA 3.14. MATRIZ. ARREGLO DE PUNTEROS A RENGLONES. ................................................................. 25 1 Profesor Leopoldo Silva Bijit26-05-2008 Captulo 4. Complejidad temporal de algoritmos. 4.1. Tiempo de ejecucin y tamao de la entrada. Sedesea tener unamedida deladuracin del tiempodeejecucin deun algoritmo enfuncin del tamao de la entrada. Atravsdellamadosalsistemaoperativosepuedeconocerelvalordelrelojdetiemporeal. Invocando al reloj, antes y despus de realizar el algoritmo se tendr una medida de la duracin del tiempo de ejecucin.Sin embargo esta medida es muy dependiente del hardware (memoria, reloj,procesador),delsistemaoperativo(multitarea,multiusuario)ypuedevariar significativamente dependiendo del computador, del compilador, y de la carga del sistema.Al disponerdesistemasconmultiprocesadoresoquelaejecucinseadistribuidatambinafecta medir el tiempo con cronmetro. Porlaraznanteriorcomounamedidadeltiempodeejecucin,seconsideracontarlas instrucciones del lenguaje de alto nivel que son necesarias realizar. Eltamaodelaentradadebeserprecisadoconmsdetalle.Podraserelnmerodebitsque midenlainformacinqueelalgoritmoprocesa,peroenformatradicionalseconsiderael nmero de elementos o componentes bsicas que son sometidos al proceso. Porejemplositenemosun arreglodencomponentes, y el algoritmo tienepor objetivo, sumar losvaloresdelascomponentes,obienordenarlascomponentes,sesueledecirquenesel tamao de la entrada. Independientemente si el arreglo es de enteros, o de estructuras. 4.2. Complejidad temporal. Definicin. SedenominacomplejidadtemporalalafuncinT(n)quemideelnmerodeinstrucciones realizadas por el algoritmo para procesar los n elementos de entrada.Cada instruccin tiene asociado un costo temporal. Afecta al tiempo de ejecucin el orden en que se procesen los elementos de entrada. Podraconsiderarsequelosvaloresdelosncasosquesepresentancomoentradasonlos correspondientes: a un caso tpico, o a un caso promedio, o de peor caso. El peor caso es el ms sencillodedefinir(elquedemoremsparacualquierentrada),perosisedeseaotrostiposde entradahabraquedefinirquseconsideratpico,oladistribucindelosvaloresenelcaso promedio. 2Estructuras de Datos y AlgoritmosProfesor Leopoldo Silva Bijit26-05-2008 4.3. Tipos de funciones. Las funciones de n pueden ser de diferente tipo: Funciones constantes:f(n) = 5,o bien g(n) =10. Funciones logartmicas: f(n) = log (n), o bien g(n) = nlog(n) Funciones polinomiales: f(n) = 2 n2, o bien g(n) = 8 n2 + 5 n Funciones exponenciales: f(n) = 2n, o bien g(n) = 25n. O mezclas de las anteriores, o cualquier funcin de n en un caso general. En general, a medida que aumenta n, las exponenciales son mayores que las polinomiales; a su vez stas son mayores que las logartmicas, que son mayores que las constantes. 4.4. Acotamiento de funciones. Veremosalgunasdefinicionesquepermitenclasificar las funciones por su orden demagnitud.Interesaencontrarunacotasuperiordelacomplejidadtemporal.Consideremoslasiguiente definicinpreliminardelafuncinOmayscula(bigoh),conlaintencindeclasificar funciones polinomiales. Se dice que T(n) es O(ni) , si existen c y k tales que: T(k) =1,4376 4n3 2n3 (n+1)2 Figura 4.1. T(n) es O(n3). Se advierte que T(n) queda acotada por arriba por 2n3 para n>1.5.Entonces T(n) es O(n3). Complejidad temporal de algoritmos3 Profesor Leopoldo Silva Bijit26-05-2008 Seguramente tambin es fcil encontrar soluciones si i es mayor que 3. Interesa encontrar el i menor posible, que cumpla la definicin. Si suponemos que i toma valor 2, la desigualdad anterior se cumple para c= 4 yk>=1 Lo cual prueba que T(n) es O(n2). Relaciones que podemos observar en el siguiente diagrama. 4n3 4n2 (n+1)2 Figura 4.2. T(n) tambin es O(n2). Si para i=2, intentamos encontrar un c menor, por ejemplo 2, se tendr que T(n) queda acotada para n>2.41412: (n+1)2 2n2 4n2 Figura 4.3. T(n) = (n+1)2 es O(n2). 4Estructuras de Datos y AlgoritmosProfesor Leopoldo Silva Bijit26-05-2008 Si seguimos disminuyendo c, por ejemplo 1.1, T(n) queda acotada para n>20,48. Considerando los casos anteriores, una mejor definicin de la funcin O es la siguiente: Se dice que T(n) es O(ni) , si existen c y n0 tales que: T(n) =n0 Intentemos probar que: T(n) = 3n3 + 2 n2 es O(n3)

Debemos encontrar un c que cumpla: 3n3 + 2 n2 =1. Por lo tanto c=5 y n0=1.Debido a que existen c y n0, T(n) es O(n3) La generalizacin para otro tipo de funciones se logra, con la siguiente definicin. 4.5. Funcin O. Se dice que T(n) es O( f(n) ) , si existen c y n0 tales que: T(n) =n0 Sinembargosenecesitaunmejorconceptoparaacotarelordenomagnituddeunafuncin. Esto considerando el primer ejemplo, en el que se poda decir que T(n) era O(n3) y tambin que era O(n2). 4.6. Funcin O. Unamejor definicin para acotar funciones, es la funcinO que define simultneamente cotas superior e inferior para T(n). Se dice que T(n) es O( f(n) ) , si existen c1, c2 y n0 tales que: c1 f(n) n. 4.9. Regla de productos. Si T1(n) es O(f(n)) y T2(n) es O(g(n)) entonces:T1(n)T2(n) es O( f(n) g(n) ). Demostracin. Por definicin: T1(n) = n1 T2(n) = n2 Sea n0 = max(n1, n2) Para n>=n0 se tiene:T(n) = T1(n) T2(n)=n0. Ejemplos: O( 3 n2 ) = O (n2) ya que 3 es O(1), y n2 esO(n2).La regla del producto tambin puede aplicarse en:n*O( n ) = O (n2) Si c es una constante y n el tamao de la entrada: O(c) = c*O(1) = O(1) O(cn) = c*O(n) = O(n) 4.10. Regla de alternativa. if(c) a1