Lenguajes de Programación I - Tipos de Datos Compuestos

Anuncio
Registros y Registros Variantes
Arreglos
Lenguajes de Programación I
Tipos de Datos Compuestos
Ernesto Hernández-Novich
<[email protected]>
c 2006-2010
Copyright Cadenas
Registros y Registros Variantes
Arreglos
Registros
Registros – agrupan datos de tipos heterogéneos para
almacenarlos y manipularlos en conjunto.
También son llamados Estructuras (structures).
Cada componente se denomina campo (field).
En la mayoría de los lenguajes, las declaraciones de
registros pueden anidarse.
Equivalen al concepto matemático de n-upla.
Cadenas
Registros y Registros Variantes
Arreglos
Declarando Registros
En C
struct elemento {
int
numero_atomico;
char
nombre[2];
double peso_atomico;
int
es_metalico;
};
En Pascal
type elemento = record
numero_atomico : integer;
nombre
: array[1..2] of char;
peso_atomico
: real;
es_metalico
: boolean
end;
Cadenas
Registros y Registros Variantes
Arreglos
Usando Registros
Operador sintáctico para acceso a los campos –
tradicionalmente es el punto.
En C
struct elemento carbono;
carbono.numero_atomico = 12;
if (carbono.es_metalico) { ... }
En Pascal
var cobre : elemento;
cobre.nombre := ’Cu’;
cobre.es_metalico := true;
En Fortran se escribe carbono %nombre.
Cadenas
Registros y Registros Variantes
Arreglos
Cadenas
Almacenamiento de Registros
Los campos se almacenan en ubicaciones contiguas.
El compilador/interpretador calcula los desplazamientos
desde la base de almacenamiento hasta cada campo.
Optimizar para velocidad (lo usual).
Campos alineados con límites de palabra en hardware.
Espacios vacíos entre los campos.
Optimizar para espacio (opcional en Pascal)
Registros empaquetados (packed) – no hay espacio entre
los campos.
Necesita más instrucciones para acceso.
Lo mejor de ambos mundos se obtiene reordenando los
campos – costoso de implantar en el compilador.
¿Es posible compararlos directamente?
Registros y Registros Variantes
Arreglos
Velocidad vs. Espacio
Restricciones de la arquitectura
Supongamos que en la arquitectura
int ocupa 32 bits y debe alinearse a 32 bits.
char ocupa 8 bits y debe alinearse a 16 bits – pero sus
arreglos se disponen de manera contigua.
float ocupa 64 bits y debe alinearse a 64 bits.
bool ocupa 8 bits y debe alinearse a 16 bits.
Las restricciones siempre son arbitrarias – respetarlas
conduce a buen desempeño del lenguaje.
¿Cómo organizar este registro?
struct meta {
int
foo;
char
bar[2];
int
baz;
double qux;
bool
meh;
};
Cadenas
Registros y Registros Variantes
Arreglos
Cadenas
Para velocidad
Respetar alineación a costa de espacio desperdiciado
4 bytes
Dispuestos en el mismo
orden de aparición.
Alineados de forma
óptima según reglas de
la arquitectura.
Ocupación: 28 bytes.
0
4
foo
bar
8
Desperdicio: 9 bytes.
12
El primer campo del
registro siempre está
alineado según las
reglas.
16
20
24 meh
baz
qux
Registros y Registros Variantes
Arreglos
Cadenas
Para espacio
Un campo detrás de otro, sin alinear
Dispuestos en el mismo
orden de aparición.
4 bytes
No se dejan espacios
vacíos entre campos.
0
Ocupación: 28 bytes.
4
bar
Desperdicio: 0 bytes.
8
baz
El primer campo del
registro siempre está
alineado según las
reglas.
12
16
foo
baz
qux
meh
Registros y Registros Variantes
Arreglos
Cadenas
Balance
Reordenar los campos
Minimizar espacio –
maximizar acceso.
Reordenar no es trivial –
equivale a knapsack que
es NP-completo.
Ocupación: 20 bytes.
Desperdicio: 1 byte.
4 bytes
0
4
8
foo
bar
meh
qux
12
16
baz
Registros y Registros Variantes
Arreglos
Registros Variantes
Colecciones alternativas de campos; sólo una válida.
struct elemento {
char
nombre[2];
int
numero_atomico;
double peso_atomico;
int
es_metalico;
int
es_natural;
union {
struct {
char *donde;
double prevalencia;
} natural;
double tiempo_de_vida;
} extra;
} cobre;
Cadenas
Registros y Registros Variantes
Arreglos
Cadenas
Registros Variantes
Se originan en los equivalence de Fortran
integer i
real r
logical b
equivalence (i, r, b)
¿Cómo obligar a un uso correcto de las alternativas?
Si no hay control, es un caso extremo de aliasing.
Algunos lenguajes mantienen un campo escondido que
establece cuál alternativa particular está vigente.
Algunos lenguajes exigen un campo discriminante (Pascal)
y hasta es obligatorio asignar campos al cambiar el
discriminante (Ada).
Registros y Registros Variantes
Arreglos
Arreglos
Son una asociación entre un tipo índice a un tipo
componente o tipo almacenado.
En la mayoría de los lenguajes el tipo índice es entero,
pero muchos lenguajes permiten cualquier tipo discreto.
Para hacer referencia a un elemento dentro de un arreglo
suele utilizarse un subíndice delimitado
En Fortran y Ada se usa A(42).
En Pascal y C se usa A[42].
Cadenas
Registros y Registros Variantes
Arreglos
Declaración de Arreglos
Agregando notación subíndice a una declaración escalar.
C/C++ con la base en cero
char letras[26];
En Fortran con la base en uno
character dimension (1:26) :: letras
Con un constructor especial.
Como en Pascal
var letras : array [’a’..’z’] of char
Como en Ada
letras : array (character range ’a’..’z’)
of character
Arreglos multidimensionales.
Cadenas
Registros y Registros Variantes
Arreglos
Cadenas
Operaciones sobre Arreglos
Obtener un elemento particular (acceso directo por
subíndice) es el habitual.
En lenguajes orientados a objetos se puede sobrecargar el
operador de indexado (caso [] en C++, indexer en C#).
Secciones de Arreglo (slices) como en Fortran y Perl.
Fortran90 permite
Comparar arreglos directamente.
Utilizar operandos aritméticos sobre arreglos y obtener un
arreglo resultante correspondiente.
Búsqueda, transposición, permutación de subíndices.
Registros y Registros Variantes
Arreglos
Cadenas
Dimensiones, Límites y Almacenamiento
El número de dimensiones y límites de un arreglo (su
forma) pueden determinarse estática o dinámicamente.
Vida Global, Forma Estática se almacena estáticamente.
Vida Local, Forma Estática se almacena en la pila de
ejecución.
Vida Local, Forma Estática al elaborar se almacena en
la pila pero con una indirección (parte fija vs. parte variable
usando dope vectors).
Vida Arbitraria, Forma Estática al elaborar (Java, C#) se
almacenan en el heap y su tamaño nunca cambia.
Vida Arbitraria, Forma Dinámica se almacena en el heap
y su tamaño cambiante obliga a reubicación.
Registros y Registros Variantes
Arreglos
Disposición en Memoria
Se almacenan en posiciones contiguas de memoria.
Para arreglos multidimensionales
Orden por filas (row major order) – dos elementos
consecutivos difieren en el último subíndice.
Orden por columnas (column major order) – dos
elementos consecutivos difieren en el primer subíndice.
Fortran usa column major order, la mayoría de los
lenguajes usa row major order.
La disposición con apuntadores permite colocar filas a
voluntad en la memoria, manteniendo apuntadores al
primer elemento de cada una.
Filas de diferente longitud son posibles – arreglos
esparcidos o cadenas.
Requiere código extra y con indirecciones.
Cadenas
Registros y Registros Variantes
Arreglos
Cadenas
Calculando las direcciones
Declaración
A : array [ L1 ..U1 ] of array [ L2 ..U2 ] of array [ L3 ..U3 ] of e_type;
Tamaño de cada dimensión
S3 = sizeof(e_type)
S2 = (U3 - L3 + 1) * S3
S1 = (U2 - L2 + 1) * S2
La dirección de A[i,j,k] será
addressof (A) + (i − L1 ) ∗ S1 + (j − L2 ) ∗ S2 + (k − L3 ) ∗ S3
¿Se podrá calcular a tiempo de compilación?
Registros y Registros Variantes
Arreglos
Cadenas
Arreglo de Caracteres vs. entidades especiales.
Cadenas literales entre comillas simples o dobles.
Caracteres literales vs. cadenas literales (como en C).
Secuencias de escape para caracteres especiales.
Longitud variable vs. longitud constante.
Operaciones disponibles en el lenguaje vs. librerías.
Cadenas
Descargar