Publicado el 6 de Octubre del 2020
365 visualizaciones desde el 6 de Octubre del 2020
95,3 KB
22 paginas
Creado hace 19a (11/01/2005)
TEMA 6: Tipos de datos estructurados
TEMA 6: Tipos de datos estructurados
6.1. Introducción
Los tipos de datos estructurados o tipos compuestos son agrupaciones de otros tipos de
datos.
Los tipos de datos estructurados más comunes son: vectores y matrices (array), cadenas
de caracteres (string), registros y uniones, aunque estos últimos no los vamos a ver en
este curso.
6.2. Vectores y Matrices
6.2.1. Vectores
Sirve para agrupar variables de un mismo tipo con un único nombre.
Supongamos que queremos declarar 10 variables de tipo entero (por ej. contadores). La
única forma de hacerlo hasta ahora sería declararlos como variables individuales:
int a0, a1, a2, a3, a4, a5, a6, a7, a8, a9;
Y si quisiésemos inicializarlos a 0, habría que escribir 10 asignaciones.
Otra forma de hacerlo es utilizando un vector (o array).
Forma de declarar un vector:
Tipo Nombre[NumElementos]
Donde Tipo indica el tipo de datos de los elementos del vector. El tipo puede ser
cualquier tipo de dato, sea simple o estructurado. NumElementos es el número de
elementos que contiene el vector. Tiene que ser siempre una constante de tipo entero.
Ejemplo:
int a[10];
De esta forma tenemos los 10 enteros agrupados y se pueden tratar como una única
variable.
Fernando Barber y Ricardo Ferrís
72
TEMA 6: Tipos de datos estructurados
Podemos acceder a cada uno de los elementos de un vector utilizando un índice. A esta
operación se la denomina indexación. El índice indica la posición del elemento dentro
del vector.
En C++ El primer elemento es siempre el 0.
Ejemplo:
1º entero del vector:
2º entero del vector:
3º entero del vector:
...
Último entero del vector:
a[0]
a[1]
a[2]
a[9]
Hay que tener presente que cuando indexamos un vector, el resultado es un elemento
del vector y tendrá por tanto el tipo de este elemento. En nuestro ejemplo, a[2] es de
tipo int, y se podrá utilizar por tanto en cualquier lugar del programa donde se admita
una variable de tipo int.
La estructura más adecuada para manejar vectores es un bucle for, debido a que
siempre conocemos el número de elementos del vector.
Ejemplo: si tenemos un vector de 10 enteros que representan contadores, para
inicializar todos los contadores a 0 sería:
int a[10];
int i;
for(i = 0; i < 10; i++)
a[i] = 0;
Para escribir en pantalla todos los elementos:
for(i = 0; i < 10; i++)
cout << a[i];
Aunque una variable de tipo vector se puede declarar directamente, lo más
recomendable para evitar errores es declarar un tipo de dato nuevo mediante un
typedef. Además, para facilitar la realización de bucles y evitar también cometer
errores, el número de elementos del vector tiene que ser una constante declarada
previamente.
Fernando Barber y Ricardo Ferrís
73
TEMA 6: Tipos de datos estructurados
Ejemplo:
const int MAX = 10;
...
typedef int VectorInt[MAX];
...
VectorInt a;
...
for(i = 0; i < MAX; i++)
a[i] = 0;
...
NO se pueden realizar asignaciones entre vectores. La siguiente asignación no se debe
realizar NUNCA:
VectorInt a, b;
...
a = b;
// MAL
6.2.2. Matrices
Al igual que podemos crear vectores de cualquier tipo simple (enteros, reales, ...),
podemos crear vectores tomando como tipo base otro vector. De esta manera lo que
tendremos será una matriz.
Ejemplo:
typedef int Vector[10];
typedef Vector Matriz[20];
Matriz a;
a[19][3] = 0;
Esta declaración de la matriz se puede abreviar de la siguiente manera:
typedef int Matriz[20][10];
Matriz a;
Fernando Barber y Ricardo Ferrís
74
TEMA 6: Tipos de datos estructurados
O directamente declarar la variable (aunque es más recomendable declarar siempre
un tipo):
int a[20][10];
Se pueden declarar matrices no sólo de dos dimensiones, sino de cualquier número de
dimensiones.
La estructura más adecuada para manejar matrices serán bucles for anidados.
Ejemplo: Visualizar una matriz.
const int MAX_X, MAX_Y;
typedef int Matriz[MAX_X][MAX_Y];
Matriz a;
int i, j;
for(i = 0; i < MAX_X; i++)
for(j = 0; j < MAX_Y; j++)
cout << a[i][j];
6.2.3. Paso de arrays como parámetros
Los arrays, como cualquier otro tipo de datos, se pueden pasar como parámetros a una
función. Sin embargo, en C++ no es posible pasarlos por valor. Siempre que se pasa un
array a una función, se pasa por referencia, aunque no pongamos nada especial en el
parámetro.
Fernando Barber y Ricardo Ferrís
75
TEMA 6: Tipos de datos estructurados
Ejemplo: Una función para leer un vector por teclado se haría de la siguiente
manera:
const int MAX = 10;
typedef int Vector[MAX];
void LeerVector(Vector v)
{
int i;
for(i = 0; i < MAX; i++)
cin >> v[i];
return;
}
El vector v en este ejemplo está pasado por referencia, no es necesario escribir el &.
Al pasarse exclusivamente por referencia, el paso de arrays como parámetros es más
eficiente, puesto que no hay que copiar cada vez toda la matriz (que normalmente son
bastante grandes). El inconveniente es que dentro de la función se puede modificar el
array aunque no se quisiera. Para evitar esto, en C++ existen los parámetros constantes.
Son parámetros que se declaran como constantes, de manera que no pueden ser
modificados.
Ejemplo: Mostrar un vector.
void MostrarVector(const Vector v)
{
int i;
for(i = 0; i < MAX; i++)
cout << v[i];
return;
}
En la función anterior, si intentamos realizar una asignación del tipo:
a[0] = 1;
nos dará un error de compilación.
Fernando Barber y Ricardo Ferrís
76
TEMA 6: Tipos de datos estructurados
Por último, una función no debe devolver valores de tipo array, es decir, no hay que
declarar funciones de tipo array. Si se quiere devolver un array, se debe hacer
utilizando un parámetro como en la función LeerVector.
6.2.4. Representación en memoria de un array
Los elementos de un vector se almacenan en memoria de forma contigua, es decir, uno
al lado del otro.
Ejemplo:
int Vector[10]; //Si empieza en la dirección de memoria 10:
10 14 ... 42 46
2
2
4
1
Por lo tanto, para calcular la posición en memoria de un elemento se utiliza la fórmula:
d = do + Ind * sizeof (Elemento)
donde do es la dirección de memoria donde empieza el vector
Ind es el índice del elemento del vector del que queremos saber su
dirección, y
Elemento es el tipo de elementos que contiene el vector
sizeof devuelve el tamaño en bytes de una variable o tipo de dato. sizeof(char),
por ejemplo devolverá 1.
Puesto que una matriz no es más que un vector de vectores, el almacenamiento en
memoria es también contiguo:
Ejemplo:
int Matriz[20][10]; //Si empieza en 10:
10
2
50
1
14
1
54
4
...
...
42
4
82
1
46
2
86
8
Matriz[0]
Matriz[1]
.......
Fernando Barber y Ricardo Ferrís
77
770 774 ... 802 806
1
3
0
5
TEMA 6: Tipos de datos estructurados
Matriz[19]
Para calcular la posición del elemento Matriz[19][1], lo que hay que hacer es
primero resolver el primer índice (Matriz[19]), que tiene como elementos
vectores enteros de 10 elementos, y después el segundo tomando como
dirección inicial la que resulta del calculo anterior. Así, si el vector empieza
por ejemplo en la posición 10, la fórmula será:
d = 10 + 19 * sizeof(int [10]) + 1 * sizeof(int)
= 10 + 760 + 4 = 774
6.2.5. Uso de arrays con número de elementos variable
Como ya se ha comentado, el tamaño de un array ha de ser una constante, por lo tanto
no es posible modificar el tamaño de un array después de haber compilado el programa.
Para solucionar esto existen dos posibilidades: la primera es utilizar memoria dinámica,
que veremos en el Tema 8, la segunda es declarar un array lo suficientemente grande y
utilizar sólo una parte de este array.
Por ejemplo, si vamos a realizar un programa para sumar vectores matemáticos y
sabemos que en ningún caso vamos a tener vectores de un tamaño mayor de 10,
podemos declarar todos los vectores de tamaño 10 y después utilizar sólo una parte del
vector. Para ello necesitaremos utilizar también una variable entera extra para saber el
tamaño actualmente utilizado por el vector, puesto que todas las operaciones se
realizarán considerando el tamaño actual del vector y no el total.
Los inconvenientes de este método son que estamos desperdiciando memoria y además
que no siempre hay un límite conocido al tamaño del array.
Ejemplos de suma de vectores con tamaño fijo:
/************************************************/
/* Programa para la suma de vectores de enteros */
/************************************************/
#include<iostream.h>
const int MAX = 3; // Tamanyo del vector
typedef int Vector[MAX];
void MostrarVector(const Vector v);
void LeerVector(Vector v);
Fernando Barber y Ricardo Ferrís
78
TEMA 6: Tipos de datos estructurados
void SumarVector(const Vector v1, const Vector v2, Vector vr);
int main()
{
Vector v1, v2, vr;
cout << "Introduce el primer vector:" << endl;
LeerVector(v1);
cout << "Introduce el segundo vector:" << endl;
LeerVector(v2);
SumarVector(v1, v2, vr);
cout << "El vector suma es:" << endl;
MostrarVector(vr);
return 0;
}
void MostrarVector(const Vector v)
{
int i;
for(i = 0; i < MAX; i++)
cout << v[i] << " ";
cout << endl;
return;
}
void LeerVector(Vector v)
{
int i;
for(i = 0; i < MAX; i++)
cin >> v[i];
return;
}
void SumarVector(const Vector v1, const Vector v2, Vector vr)
{
int i;
for(i = 0; i < MAX; i++)
vr[i] = v1[i] + v2[i];
return;
}
Ejemplos de suma de vectores con tamaño fijo y con tamaño variable (hasta un
máximo de 10):
Fernando Barber y Ricardo Ferrís
79
TEMA 6: Tipos de datos estructurados
// Tamanyo maximo del vector
/***************************************************************/
/* Programa para la suma de vectores de enteros d
Comentarios de: TEMA 6: Tipos de datos estructurados (0)
No hay comentarios