Sunteți pe pagina 1din 58

Tema 1 Elementos para el estudio

de las estructuras de datos


Objetivo: El alumno comprenderá los aspectos básicos
de la estructura de una computadora digital, que le
permitirá obtener un marco de referencia para iniciar
el estudio de las estructuras de datos.
1.1 Generalidades

La historia de la computación tiene sus orígenes en el inicio


mismo de la civilización.
La búsqueda de nuevos métodos para
realizar cálculos ha evolucionado desde
la antigüedad.
Desde el ábaco, pasando por los huesos
de Napier y hasta las supercomputadoras,
se siguen buscando nuevas formas de
automatizar tareas.
1.1.1 Componentes físicos de una computadora

Una computadora digital es un dispositivo electrónico, utilizado


para procesar información y obtener resultados, capaz de
ejecutar cálculos a velocidades millones o cientos de millones más
rápido de lo que pueden hacerlo los seres humanos.
Durante la década de los 40’s el matemático John
von Neumann propuso una idea revolucionaria para
la época: una computadora con una memoria para
almacenar datos y programas.
Este modelo se conoce como arquitectura von Neumann y es el
modelo que se sigue utilizando en las computadoras actuales.
1.1.2 Elementos internos de la computadora
(estructura y función)

Las computadoras con arquitectura


von Neumann constan de cinco partes:
Unidad aritmético-lógica (ALU),

Unidad de control,

Memoria,

Dispositivos de entrada/salida

Buses que proporcionan un medio de transporte de los datos entre las otras
partes.
1.1.2 Elementos internos de la computadora
(estructura y función)

Otro modelo muy utilizado es la arquitectura Harvard. Las


computadoras basadas en esta arquitectura utilizan dispositivos de
almacenamiento físicamente separados para las instrucciones y
para los datos.
Una computadora basada en estas arquitecturas realiza los
siguientes pasos secuencialmente:
Lee la instrucción

Incrementa el contador de programa

Decodifica la instrucción

Ejecuta la instrucción

Vuelve al paso 1 para leer la siguiente instrucción


1.1.2 Elementos internos de la computadora
(estructura y función)

Un programa es un conjunto de instrucciones que una vez


ejecutadas realizarán una o varias tareas en una computadora.

Un lenguaje de programación es un lenguaje


artificial diseñado para expresar instrucciones
que pueden ser llevadas a cabo por máquinas
como las computadoras. De acuerdo al nivel de
abstracción, se clasifican en:
Lenguajes de bajo nivel
Lenguajes de alto nivel.
1.1.3 Conceptos básicos de programación de
bajo nivel

Los lenguajes de bajo nivel son cercanos a la arquitectura de la


máquina.
Algunas de sus características principales son:
Dependencia absoluta de la arquitectura de la computadora.

Imposibilidad de transportar programas entre distintas


máquinas, salvo que sean de la misma familia.

Instrucciones poco potentes.

Programas muy largos.

Códigos de operación, datos y referencias en binario.


1.1.3 Conceptos básicos de programación de
bajo nivel

Los tipos de lenguajes de bajo nivel son:


Lenguaje máquina (binario).

Es directamente interpretable y ejecutable por


los circuitos de la computadora.

Lenguaje ensamblador (mnemotécnicos).

Es la representación simbólica del lenguaje


máquina.

Datos y referencias codificadas mediante


nombres simbólicos (símbolos o etiquetas).
1.1.3 Conceptos básicos de programación de
bajo nivel

El lenguaje ensamblador debe ser traducido a lenguaje máquina


para poder ser interpretado y ejecutado por la computadora.

La codificación de programas en binario es conveniente y natural para la


circuitería de la computadora, pero es difícil para un programador humano.

El lenguaje ensamblador surgió para facilitar la escritura de programas.


1.1.4 Conceptos de programación de alto nivel
(estructurada)

Los lenguajes de alto nivel son aquellos que se aproximan más al


lenguaje natural humano que al lenguaje binario de las
computadoras (de bajo nivel).
Al aproximarse al lenguaje natural, el programa se puede escribir
y leer de una forma más sencilla,
eliminando muchas de las posibilidades
de cometer errores que se daban en el
lenguaje máquina, ya que se utilizan
palabras (generalmente en inglés) en
lugar de cadenas de símbolos sin ningún
significado aparente.
1.1.4 Conceptos de programación de alto nivel
(estructurada)

Algunas de sus características principales son:


Posibilidad de traducción automática a
lenguaje máquina.
Independencia de la arquitectura de la
computadora.
Transportabilidad entre diferentes
computadoras.
1.1.4 Conceptos de programación de alto nivel
(estructurada)

De acuerdo al paradigma de programación que utilizan, los


lenguajes se pueden clasificar como imperativos o declarativos.
Los programas imperativos son un conjunto de instrucciones que
le indican a la computadora cómo realizar una tarea.

Los programas declarativos especifican o "declaran" un


conjunto de condiciones, proposiciones, afirmaciones o
restricciones que describen el problema y detallan su
solución. La solución es obtenida mediante mecanismos
internos de control, sin especificar exactamente cómo
encontrarla, tan sólo se le indica a la computadora qué
es lo que se desea obtener.
1.1.4 Conceptos de programación de alto nivel
(estructurada)

Algunos lenguajes de programación según su paradigma.


!"#$%&'"()*")
+,-$,&.&/01#

2.3",&405-( 6"/7&,&405-(

9,0"#4&*-()&
8(4,%/4%,&*-( ;%#/0-#&7"( !1$0/-(
9:'"4-(

<
+&(/&7 +H4>-# +,-7-$
<9=9! <!2+F
3>3 ???
??? <@@ D&(E"77
A&5& !2F+
<B 6,?)F/>"."
3>3C 6,?)G&/E"4
??? ???
1.1.4.1 Representación de tipos de datos,
enteros, reales, caracteres

En la actualidad, las computadoras tienen la capacidad de


manipular y procesar datos que parecen ser totalmente diferentes
entre ellos texto, imágenes, audio, video, etc.
¿Cómo hacer que una sola computadora manipule cualquiera de
estos tipos diferentes? Después de mucho tiempo, se encontró que
la mejor forma de hacerlo es mediante una representación
uniforme de la información: agrupaciones o patrones de bits.
Un bit es la unidad mínima de almacenamiento en las
computadoras, el término fue acuñado originalmente por John
Tukey (Binary digIT) y representa dos estados (binario):
1.1.4.1 Representación de enteros

Los enteros en la computadora se representan mediante


agrupaciones de dígitos binarios, se tienen las siguientes formas
de representación:
Sin signo
Con signo
Magnitud y signo
Complemento a 1
Complemento a 2
1.1.4.1 Enteros sin signo

También conocido como binario puro, sirve para representar


solamente 0 y enteros positivos. El intervalo de números que
puede representar, depende del número de bits disponibles, si el
número sobrepasa el intervalo, se genera un desbordamiento:
( )
Intervalo: ⎡⎣ 0, 2 n − 1 ⎤⎦
Donde n es el número de bits disponibles; por ejemplo:
Número de bits Intervalo
8 [ 0, 255 ]
16 [ 0, 65 535 ]
1.1.4.1 Enteros sin signo
1.1.4.1 Enteros en signo y magnitud

El almacenamiento de un entero en el formato de signo y


magnitud requiere 1 bit para representar el signo (0 para positivo,
1 para negativo).
Esto significa que en una asignación de ocho bits, sólo se pueden
usar siete bits para representar el valor absoluto del número
(número sin signo):
( )( )
Intervalo: ⎡⎣ − 2 n −1 − 1 , 2 n −1 − 1 ⎤⎦

Número de bits Intervalo


8 [ −127,127 ]
16 [-32 767, 32 767 ]
1.1.4.1 Enteros en complemento a 1

Para representar un número positivo, se usa la convención


adoptada para un entero sin signo y para representar un número
negativo, se complementa el número positivo.
El complemento de un número se obtiene al cambiar todos los 0 a
1 y todos los 1 a 0.
( )( )
Intervalo: ⎡⎣ − 2 n −1 − 1 , 2 n −1 − 1 ⎤⎦

Por ejemplo, si se tienen 4 bits, los números +4 y -4 se


representan de la siguiente manera:
+4 → 0100
−4 → 1011
1.1.4.1 Enteros en complemento a 1

Para almacenar los enteros complemento a 1 se realizan los


siguientes pasos:
1. Cambiar el número a binario, el signo es ignorado.
2. Añadir uno o varios 0 a la izquierda del número para hacer
un total de N bits.
3. Si el número es positivo, no se necesita ninguna otra acción;
si es negativo, se complementa cada bit (cambiar 0 por 1 y 1 por
0).
1.1.4.1 Enteros en complemento a 2

Las dos representaciones anteriores presentan el problema de la


ambigüedad del cero, es decir, ambas tienen representación para
el +0 y el -0:
+0 → 0000 +0 → 0000
−0 → 1000 −0 → 1111

La representación de complemento a 2 evita esta ambigüedad, es


la representación de enteros más común, más importante y de más
amplio uso en la actualidad:
Número de bits Intervalo
( )
Intervalo: ⎡⎣ −2 n −1 , 2 n −1 − 1 ⎤⎦ 8 [ −128,127 ]
16 [-32 768, 32 767 ]
1.1.4.1 Enteros en complemento a 2

Para almacenar los enteros complemento a 2 se realizan los


siguientes pasos:
1. Cambiar el número a binario, el signo es ignorado.
2. Añadir uno o varios 0 a la izquierda del número para hacer
un total de N bits.
3. Si el número es positivo, no se necesita ninguna otra acción;
si el signo es negativo, todos los 0 en el extremo derecho y el
primer 1 permanecen sin cambios; el resto de los bits se
complementa.
1.1.4.1 Enteros en complemento a 2

Ejemplo: representar los números +4 y -4 en complemento a 2,


utilizando 4 bits:

1. 4 → 100
2. 100 → 0100
3. +4 → 0100 3. −4 → 1100
1.1.4.1 Enteros en complemento a 2

Para obtener el valor decimal de un número representado en


complemento a dos se realiza lo siguiente:
Si el primer bit es 0, se aplica la conversión de binario a
decimal.
Si el primer bit es 1, se aplica el complemento a 2, se convierte
de binario a decimal y el resultado será el negativo del número
obtenido.
1.1.4.1 Enteros en complemento a 2

Ejemplo: determinar el valor decimal de los siguientes números


representados en complemento a 2, con 4 bits:

0100 → 4 1100 → 0100


0100 → 4
4 → −4
1.1.4.1 Representación de enteros, tarea

Obtener la representación en complemento a 1 y complemento a 2


con 8 bits de los siguientes números enteros:
-121, -56, 26, 75, 115, 234
Obtener el valor decimal de los siguientes números representados
en complemento a 1:
0000, 1000, 1111, 01010110, 10101010
Obtener el valor decimal de los siguientes números representados
en complemento a 2:
0000, 1000, 1111, 01010110, 10101010
1.1.4.1 Representación de “reales”

Las computadoras, con un número finito de bits, no pueden


almacenar todos los números reales en forma exacta, similar a lo
que ocurre con los números irracionales (como pi, e, etc.) o
periódicos (1/3, 1/11, etc.) en el sistema decimal, por tanto, se
pueden utilizar aproximaciones con las siguientes notaciones:
Punto fijo
Punto flotante
1.1.4.1 Notación de punto fijo

Esta representación consiste en destinar una cantidad fija de


dígitos para la parte entera y otra para la parte fraccionaria. La
cantidad de dígitos destinados a la parte fraccionaria indica la
posición (siempre fija) del punto dentro del número.
La posición del punto (punto decimal en base diez) es la que fija
la potencia de la base por la que hay que multiplicar el dígito
correspondiente.
1.1.4.1 Notación de punto fijo

Por ejemplo, para obtener el valor del siguiente número,


representado con 8 bits: 10101110. Primero se debe definir el
número de digitos que corresponden a la parte entera y los que
representan la parte fraccionaria; para el ejemplo, se consideran 5
y 3 bits respectivamente: 10101.110.
Con esta convención, el valor decimal se obtiene como:

r = 1 × 2 4 + 0 × 2 3 + 1 × 2 2 + 0 × 21 + 1 × 2 0 + 1 × 2 −1 + 1 × 2 −2 + 0 × 2 −3

r = 21.75
1.1.4.1 Notación de punto flotante

La forma convencional de almacenar números reales en la


memoria de una computadora es mediante el método llamado de
punto flotante o “floating point”.
Uno de los sistemas más comunes es la representación de números
reales en la convención IEEE 754. En dicho sistema cada número
de precisión simple ocupa 32 bits (4 bytes) que se destinan a: 1
bit para el signo, 8 bits para el exponente y 23 bits para la parte
fraccionaria de la mantisa (en doble precisión se utilizan 64 bits
(8 bytes): 1 para el signo, 11 bits para el exponente y 52 bits para
la mantisa).
1.1.4.1 Notación de punto flotante

De esta manera un número está determinado por estas tres


cantidades:
r = ( −1) × 2 exponente− E × 1.mantisa
signo

En esta representación, los 8 bits utilizados permiten que el


exponente se encuentre en el rango [0,255]. Se utiliza la
constante E=127 para también obtener resultados negativos.
Obsérvese que para ganar un bit, se omite la parte entera de la
mantisa que se supone igual a 1. Esta representación se llama
normalizada.
1.1.4.1 Notación de punto flotante

Ejemplo: obtener el valor decimal del número de precisión simple:


01000001100111100010000000000000
Como primer paso, se deben identificar los elementos de la
representación:
signo exponente mantisa

 (1).00111100010000000000000
0 10000011 
1.1.4.1 Notación de punto flotante

Con esto podemos obtener los valores decimales de cada


elemento:
Signo: ( -1)signo = ( -1)0 = 1
Exponente: 131; exponente − E = 131 − 127 = 4
Mantisa, se debe considerar el 1 implícito (mostrado entre
paréntesis) de la parte entera:
1 + 1 8 + 116 + 1 32 + 1 64 + 11024 = 1.2353515625

Finalmente, se sustituyen estas cantidades para obtener el valor


decimal:
r = 1 × 2 4 × 1.2353515625=19.765625
1.1.4.1 Representación de reales, ejercicio

Obtener el valor decimal de los siguientes números representados


en punto flotante de precisión simple:
11010110001101010100101000000000
01011010010101011001101000000000

r = ( −1) × 2 exponente− E × 1.mantisa


signo
1.1.4.1 Representación de reales, tarea

Obtener el valor decimal de los siguientes números representados


en punto fijo con 10 bits para la parte entera:
1001010101100111, 0101101010100001
Obtener el valor decimal de los siguientes números representados
en punto flotante de precisión simple:
11010010010001010101101010101011
01011010110101011101101011101100
Supón que te solicitan desarrollar un estándar para representar
números en punto flotante de precisión semi-simple, da tu
definición para cada uno de los elementos de la representación y
al menos 2 ejemplos de números usando tu definición.
1.1.4.1 Conversión de decimal a punto flotante

Para obtener la representación de punto flotante a partir de un número


decimal, se realiza lo siguiente:
1. El bit más significativo indica el signo: + -> 0; - ->1
2. Convertir a binario, dejando el punto decimal en la misma posición.
3. Normalizar, recorrer el punto tantas posiciones como sea necesario
para obtener un número de la forma 1. ...
La cantidad de posiciones desplazadas indica el valor del exponente en
exceso a 127 en binario; si el desplazamiento a las izquierda, el exponente
es positivo, a la derecha, será negativo.
4. La mantisa incluye el bit implícito (no se escribe en la representación).
5. Agregar a la derecha de la mantisa tantos 0’s como sea necesario para
complementar los 23 bits.
1.1.4.1 Conversión de decimal a punto flotante

Ejemplo: obtener la representación de punto flotante del número


decimal 19.765625
1. +⇒0
2. 19.765625 ⇒ 10011.110001
3. 10011.110001 ⇒ 1.00111100010000000000000
El punto se recorrió 4 posiciones a la izquierda ⇒ 127+4=131
⇒ 10000011

Finalmente, se unen cada uno de los elementos en una cadena


binaria:
01000001100111100010000000000000
1.1.4.1 Conversión de decimal a punto flotante,
tarea

Obtener la representación de punto flotante de los siguientes


números decimales:
-6.53125
9.8125
-17.28125
35.515625
1.1.4.1 Representación de caracteres

Para representar texto es necesario establecer un código que


asocie a cada caracter un valor binario Este código debe ser
conocido por todos los participantes en un intercambio de
información. Las codificaciones más conocidas son:
ASCII.
EBCDIC.
UNICODE.
1.1.4.1 ASCII, EBCDIC

El American Standard Code for Information Interchange (ASCII)


utiliza siete bits para cada símbolo. Esto significa que se pueden
representar 2^7=128 símbolos distintos. El código ASCII-extendido
utiliza 8 bits, es decir 2^8=256 símbolos.
El Extended Binary Coded Decimal Interchange Code (EBCDIC) es
un código binario que representa caracteres alfanuméricos,
controles y signos de puntuación. Cada
carácter está compuesto por 8 bits,
define un total de 256 caracteres. Es
un código estándar usado por
computadoras mainframe IBM.
1.1.4.1 UNICODE, UTF-8, UTF-16, UTF-32

El principal problema de ambos códigos de caracteres es su


limitación a 256 símbolos, que no son suficientes para lenguajes
ideográficos con varios miles de símbolos. Unicode es un estándar
que proporciona un código único para cada carácter independiente
del software y el idioma. El objetivo original fue utilizar un
código de 16 bits para representar 2^16=65 536 caracteres.
En la actualidad soporta tres formatos para representar millones
de caracteres:
UTF-8, los caracteres ASCII tienen
asignados los mismos valores.
UTF-16.
UTF-32.
1.1.4.2 Ciclos de control

Un programa (algoritmo) contiene instrucciones elementales


seleccionadas cuidadosamente que pueden ser realizadas por un
robot ó un procesador; el procesador recibe las órdenes y ejecuta
lo que indican. Por tanto, el algoritmo debe incluir instrucciones
de control que modifiquen la ruta que debe seguir el procesador,
además de indicar que debe hacerse en cada paso, así como el
momento en el cual debe detenerse.
Se ha probado que para implementar cualquier algoritmo, son
suficientes tres construcciones básicas para control de flujo:
Secuencia.
Condicional.
Ciclos iterativos (repetitivos).
♦ Condicional.
etitivos). ♦ Ciclos iterativos (repetitivos).

A continuación se describe cada una de ellas y se muestra su representación tanto e


cada una de ellas y se muestra su representación tanto en pseudoc
1.1.4.2 Ejecución secuencial
como en diagrama de flujo.

Ejecución secuencial
La ejecución secuencial consiste en ejecutar una instrucción y al terminar, realiz
el siguiente paso del algoritmo.

···
consiste en ejecutar una instrucción y al terminar, realizar lo que
n. Instrucción i
La ejecución secuencial consiste en ejecutar una instrucción y al
o. Instrucción i+1
mo. terminar, realizar lo que indica el siguiente
· · · paso del algoritmo.

!!!
···
n. Instrucción i !"#$%&''()"*!

o. Instrucción i + 1 !"#$%&''()"*!+,

···

!!!
!!!

Figura 1.10: Ejecución secuencial

Ejecución condicional
CAPÍTULO 1. ELEMENTOS PARA EL ESTUDIO DE LAS ESTRUCTURAS

1.1.4.2 Ejecución condicional


···
n. SI c ENTONCES
n.1. Subinstrucción 1
···
n.k. Subinstrucción k
o. SI NO
Consiste en ejecutar un grupo de acciones o.1.ASubinstrucción
ó un grupo1 de
ENTOS PARA ELBESTUDIO
acciones DE LASen
(pero no ambos) ESTRUCTURAS
función del DE DATOS
· · · resultado de la13
o.j. Subinstrucción j
evaluación de una condición C (Verdadero
··· ó Falso).
···

!!!
n. SI c ENTONCES
n.1. Subinstrucción 1 ! "
"
···
n.k. Subinstrucción k !"#$%&'("))$*%+, !"#$%&'("))$*%+,

o. SI NO
!!!

!!!
o.1. Subinstrucción 1
!"#$%&'("))$*%+! !"#$%&'("))$*%+!
···
o.j. Subinstrucción j
···
!!!
!!!
CAPÍTULO 1. ELEMENTOS PARA EL ESTUDIO DE LAS ESTRUCTURAS DE DA

···
1.1.4.2 Ciclo: iteración definida n. DESDE cont ← 1 HASTA N
n.1. Subinstrucción 1
···
n.k. Subinstrucción k
n.k+1. cont ← cont + 1
MENTOSSirve
PARA para
ELejecutar
ESTUDIO un DE
grupo
LASdeESTRUCTURAS DE DATOS N
instrucciones
14··· A exactamente
veces, donde N es un entero positivo.

!!!
··· "#$%++++++,

n. DESDE cont ← 1 HASTA N "#$%&-.+'


"

n.1. Subinstrucción 1 !

!"#$%&'("))$*%+,
···

!!!
n.k. Subinstrucción k !"#$%&'("))$*%+!

n.k+1. cont ← cont + 1 "#$%++++++"#$%/,

···

!!!
Es importante notar que en el caso de la iteración definida existe
!!!

Figura 1.12: Iteración definida


una variable implícita llamada contador, ‘cont’ en el ejemplo, y
sirve para tener unEs importante
"#$%++++++,
registronotar
delquenúmero
en el caso dede iteraciones
la iteración realizadas
definida existe una variable implícita
contador, cont en el ejemplo, y sirve para tener un registro del número de iteraciones r
hasta el momento y para llegar a la condición de paro.
hasta el momento y para llegar a la condición de paro. Otra variable muy utilizada c
"
"#$%&-.+'
trabaja con ciclos es conocida como acumulador, y sirve para almacenar resultados par
1.1.4.2 Ciclo: iteración condicional
CAPÍTULO 1. ELEMENTOS PARA EL ESTUDIO DE LAS ESTRUCTURAS DE DAT

···
n. MIENTRAS c HACER
n.1. Subinstrucción 1
Conocida también como iteración indefinida,
···
se utiliza para repetir
NTOS PARA EL ESTUDIO DE LAS ESTRUCTURAS DE DATOS 15
n.k. Subinstrucción k
un bloque de acciones A, mientras una
· · · condición C sea verdadera,

c es una condición de paro.

!!!
··· "

n. MIENTRAS c HACER
!
!

n.1. Subinstrucción 1 !"#$%&'("))$*%+,

···

!!!
n.k. Subinstrucción k !"#$%&'("))$*%+"

···

!!!
En este caso, a diferencia de la iteración definida, la condición de
!!!

paro C depende exclusivamente de las Figuraoperaciones realizadas


1.13: Iteración condicional

dentro del cuerpo


!
deleste
En " ciclo. Cuandode en
caso, a diferencia un algoritmo
la iteración se utilizan
definida, la condición de paro C depende excl
mente de las operaciones realizadas dentro del cuerpo del ciclo.
iteraciones, es necesario tener cuidado de no crear ciclos infinitos.
Cuando en un algoritmo se utilizan iteraciones, es necesario tener cuidado de no crear
!
infinitos, esto se hace con operaciones dentro del bloque de instrucciones que garanticen
condición de paro se cumplirá.
!"#$%&'("))$*%+,
1.1.5 Manejo de memoria, acceso, asignación
dinámica, apuntadores, arreglos

En su forma más simple, la administración de memoria incluye


proporcionar formas para asignar porciones de memoria a
programas cuando lo soliciten además de liberar esa memoria
cuando ya no sea requerida, para que pueda ser utilizada por
otros procesos. El manejo de memoria principal es crítico para los
sistemas de cómputo.
La unidad de manejo de memoria (en inglés:
Memory Management Unit) es un dispositivo
de hardware formado por un grupo de
circuitos integrados, responsable del manejo
de los accesos a la memoria por parte de la
Unidad de Procesamiento Central (CPU).
1.1.5 Manejo de memoria: Memoria estática

Es la forma más fácil de almacenar el contenido de una variable


en memoria en tiempo de ejecución.
Para que un objeto pueda ser almacenado en memoria estática su
tamaño (bytes) se debe conocer en tiempo de compilación, como
consecuencia de esta condición no podrán almacenarse en
memoria estática:

Objetos correspondientes a procedimientos o funciones


recursivas, ya que en tiempo de compilación no se sabe el
número de variables que serán necesarias.

Estructuras dinámicas de datos tales como listas, árboles, etc.


ya que el número de elementos que las forman no es conocido
hasta que el programa se ejecuta.
1.1.5 Manejo de memoria: Memoria estática

Las técnicas de asignación de memoria estática son sencillas:


A partir de una posición señalada por un
apuntador de referencia se aloja el objeto X,
y se avanza el apuntador tantos bytes como
sean necesarios para almacenar el objeto X.
La asignación de memoria puede hacerse en
tiempo de compilación y los objetos están
vigentes desde que comienza la ejecución del
programa hasta que termina.
1.1.5 Manejo de memoria: Memoria dinámica

Supóngase que un programa debe manipular estructuras de datos


de longitud desconocida. Un ejemplo simple podría ser el de un
programa que lee las líneas de un archivo y las ordena. Por tanto,
deberemos leer un número indeterminado de líneas, y tras leer la
última, ordenarlas.
Una manera de manipular ese número indeterminado, sería
declarar una constante MAX_LINEAS, darle un valor muy grande,
y declarar un arreglo de tamaño MAX_LINEAS.
Obviamente esto es muy ineficiente, el programa no sólo quedaría
limitado por ese valor máximo, sino que además gastaría esa
enorme cantidad de memoria para procesar hasta el más pequeño
de los archivos.
1.1.5 Manejo de memoria: Memoria dinámica

La solución consiste en utilizar memoria dinámica. La memoria


dinámica es un espacio de almacenamiento que se solicita en
tiempo de ejecución. De esa manera, a medida que el proceso
necesita espacio para más líneas, solicita más memoria al sistema
operativo para guardarlas.
El medio para manejar la memoria que
otorga el sistema operativo, es el
apuntador, puesto que no podemos saber
en tiempo de compilación dónde habrán
huecos en la memoria.
1.1.5 Manejo de memoria: Asignación dinámica

Un problema común de asignación de memoria dinámica, es cómo


satisfacer una necesidad de tamaño n con una lista de huecos
libres. Las estrategias más comunes para asignar algún hueco de
la tabla son:
Primer ajuste: Consiste en
asignar el primer hueco con
capacidad suficiente.
Mejor ajuste: Busca asignar
el espacio más pequeño de
los espacios con capacidad
suficiente.
Peor ajuste: Asigna el hueco más grande.
1.1.5 Manejo de memoria: Arreglos

Un arreglo (array) es una colección de


variables del mismo tipo que se asocian a
un nombre común. A un elemento específico
de un array se accede mediante un índice.
Los arreglos constan de posiciones de
memoria contiguas, la dirección más baja
corresponde al primer elemento y la más
alta al último. Los arrays pueden tener una
o varias dimensiones.
1.1.5 Manejo de memoria: Arreglos
unidimensionales
Son los arreglos más simples y constan de un solo índice, también
CAPÍTULO
suelen llamarse1.vectores.
ELEMENTOS PARA EL ESTUDIO DE LAS ESTR

Como los elementos se almacenan de forma adyacente, su represe


Como los elementos
la siguiente se almacenan de forma adyacente, su
manera:
representación en la memoria es de la siguiente manera:
Dirección Elemento
... ...
Para obtener la dirección en la
z elem (0)
memoria de algún elemento, se
utiliza la siguiente expresión: z+1 elem (1)
... ...
elem ( i ) = z + i z+n−1 elem (n − 1)
... ...
1.1.5 Manejo de memoria: Arreglos
multidimensionales

Estos arreglos constan de más de un índice, cuando son de dos


dimensiones también se llaman matrices.
1.1.5 Manejo de memoria: Arreglos
multidimensionales
CAPÍTULO 1. ELEMENTOS PARA EL ESTUDIO DE LAS ESTRU
Para el caso de dos dimensiones un arreglo de n x m elementos se
almacena en la memoria como: Dirección Elemento
Para obtener la dirección en la ... ...
z elem (0, 0)
memoria de algún elemento, se
... ...
utiliza la siguiente expresión:
z+m−1 elem (0, m − 1)
elem ( i, j ) = z + m × i + j z+m elem (1, 0)
... ...
Tarea: Hacer un ejemplo de
z + 2m − 1 elem (1, m − 1)
una tabla con n=4, m=3 y
... ...
verificar si las expresiones
z + n × m − 1 elem (n − 1, m − 1)
mostradas son correctas.
... ...
De ser necesario, obtener las expresiones corregidas.
Figura 1.18: Arreglo bidimensional en memori
1.1.5 Manejo de memoria: Arreglos
multidimensionales, tarea

Para el caso de un arreglo de tres dimensiones (n x m x l),


obtener:
La forma en la que se almacena en la memoria.
La expresión para obtener la dirección de algún elemento en la
memoria.
1.1.5 Manejo de memoria: Apuntadores

En programación, un apuntador es un tipo de dato especial cuyo


valor hace referencia (“apunta”) directamente a otro valor
almacenado en algún lugar de la memoria de la computadora,
usando su dirección. Un apuntador señala alguna posición en la
memoria y obtener el valor almacenado en esa posición se conoce
como indirección (dereference).
Usar apuntadores mejora significativamente
el desempeño para realizar operaciones
repetitivas, tales como recorrer cadenas,
buscar en tablas ó controlar estructuras
tipo listas y árboles.

S-ar putea să vă placă și