PUNTEROS DE LISTAS YTABLAS - TIPO BASE INHOMOGÉNEO







Definición, declaración y acceso a listas y tablas de estructuras.
La declaración de listas, tablas y matrices de estructuras sigue las reglas expuestas anteriormente y también son válidas las afirmaciones realizadas en lo tocante a la construcción de punteros de listas , tablas, tarugos etc. en el caso en que estén formados por estructuras. La única precaución que hay que tener en cuente es la necesidad de emplera el operador punto (.) o el operador flecha ( -> ) según las estructuras sean estáticas o dinámicas, respectivamente. Según puede verse en las declaraciones siguientes,

struct Tipo_estructura {
	Tipo_1 campo_1;
	...
	Tipo_N campo_M;};
struct Tipo_estructura lista[DIM_1];
struct Tipo_estructura tabla[DIM_1][DIM_2];
struct Tipo_estructura matriz[DIM_1][DIM_2]...[DIM_P];
struct Tipo_estructura * puntero;


El valor de puntero se asignará con los métodos habituales

/* Directamente, lista es ya la dirección del primer elemento */
puntero = lista;
/* tabla[0] es la dirección del primer elemento de la primera fila */
puntero = tabla[0];
/* matriz[0][0] es la dirección del primer elemento de la primera
 fila de la primera capa */
puntero = matriz[0][0];


¿Por qué no se puede utilizar &tabla ni &matriz ? Véase el oportuno Ejercicio .

La función memcpy() .
El lenguaje C no admite la asignación de matrices entre sí dada la traducción automática de sus nombres a direcciones. Por tanto, para copiar el valor de una matriz de estructuras en otra será preciso recurrir una vez mas a la función memcpy() . La sintaxis de memcpy() es básicamente de la forma memcpy(donde, que, cuanto); con las siguientes convenciones:


Recuérdese que no hay comprobación alguna, ni de la validez de las direcciones ni tampoco de la cantidad de espacio reservado en destino ( donde ) o de la cantidad de información disponible en origen ( que ). Véase el oportuno Ejercicio .

Ejercicio .- Construir un programa que muestre la utilización de punteros para recorrer listas, tablas y matrices de estructuras.

/*
	Este programa muestra la utilización de listas
	y tablas de estructuras, haciendo uso de punteros.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define DIM_CAPAS 3
#define DIM_FILAS 5
#define DIM_COLS 5

	struct Tipo_estructura {
		int un_entero;
		float un_real;
		char cadena[80];
	};

	/* Por brevedad. */
#define Tipo_base struct Tipo_estructura

Tipo_base lista[DIM_COLS];
Tipo_base tabla[DIM_FILAS][DIM_COLS];
Tipo_base matriz[DIM_CAPAS][DIM_FILAS][DIM_COLS];
Tipo_base * p;
int i,j,k;

int main(void)
{
printf ("Uso de listas y tablas de Estructuras.\n\n");
/* Iniciación de la lista */
p = lista; /* lista señala el primer elemento */
for(i=0;i<DIM_COLS;i++)
{
	(p + i)->un_entero = i;
	(p + i)->un_real = i;
	strcpy((p + i)->cadena,"Una cadena.");
}
/* Iniciación de la tabla */
p = tabla[0]; /* O también &tabla[0][0] */
for(i=0;i<DIM_FILAS*DIM_COLS;i++)
{
	(p + i)->un_entero = i;
	(p + i)->un_real = i;
	strcpy((p + i)->cadena,"Una cadena.");
}
/* Iniciación de la matriz */
p = matriz[0][0]; /* O también &matriz[0][0][0] */
for(i=0;i<DIM_CAPAS*DIM_FILAS*DIM_COLS;i++)
{
	(p + i)->un_entero = i;
	(p + i)->un_real = i;
	strcpy((p + i)->cadena,"Una cadena.");
}
/* Ahora mostramos todo con punteros */
printf("Contenido de la lista (0..%d):\n\n", DIM_COLS);
p = lista;
for(i=0;i<DIM_COLS;i++)
{
	printf("lista[%d]: entero = %6d; ",i, (p+i)->un_entero);
	printf("real = %6.2f; ",(p+i)->un_real);
	printf("cadena = %s\n",(p+i)->cadena);
}
printf("\nContenido de la tabla (%d X %d):\n\n", DIM_FILAS, DIM_COLS);
p = tabla[0];
for(i=0;i<DIM_FILAS;i++)
	for(j=0;j<DIM_COLS;j++)
	{
		printf("tabla[%d][%d]: entero = %6d; ",i,j, (p+i*DIM_COLS+j)->un_entero);
		printf("real = %6.2f; ",(p+i*DIM_COLS+j)->un_real);
		printf("cadena = %s\n",(p+i*DIM_COLS+j)->cadena);
	}
printf("\nContenido de la matriz (%d X %d X %d):\n\n",
DIM_CAPAS, DIM_FILAS, DIM_COLS);
p = matriz[0][0];
for(i=0;i<DIM_CAPAS;i++)
	for(j=0;j<DIM_FILAS;j++)
		for(k=0;k<DIM_COLS;k++)
		{
			printf("matriz[%d][%d][%d]: entero = %6d; ",
			i,j,k, (p+i*DIM_FILAS*DIM_COLS +j*DIM_COLS + k)->un_entero);
			printf("real = %6.2f; ",
			(p+i*DIM_FILAS*DIM_COLS +j*DIM_COLS + k)->un_real);
			printf("cadena = %s\n",
			(p+i*DIM_FILAS*DIM_COLS +j*DIM_COLS + k)->cadena);
		}

	printf("\n\nTerminación normal del programa.\n");
	return 0;
}

/*
Todo funciona. Se podría reducir el código empleando un solo
bucle que fuera desde 0 hasta DIM_COLS, DIM_FILAS*DIM_COLS
o DIM_CAPAS*DIM_FILAS*DIM_COLS respectivamente. Esto implica
sin embargo calcular los valores de i, j y k para poder
mostrarlos. Lo dejaré como ejercicio para el lector.

	RESULTADO (abreviado)
Uso de listas y tablas de Estructuras.

	Contenido de la lista (0..5):

lista[0]: entero = 0; real = 0.00; cadena = Una cadena.
lista[1]: entero = 1; real = 1.00; cadena = Una cadena.
lista[2]: entero = 2; real = 2.00; cadena = Una cadena.
lista[3]: entero = 3; real = 3.00; cadena = Una cadena.
lista[4]: entero = 4; real = 4.00; cadena = Una cadena.

	Contenido de la tabla (5 X 5):

tabla[0][0]: entero = 0; real = 0.00; cadena = Una cadena.
tabla[0][1]: entero = 1; real = 1.00; cadena = Una cadena.
tabla[0][2]: entero = 2; real = 2.00; cadena = Una cadena.
...
tabla[4][2]: entero = 22; real = 22.00; cadena = Una cadena.
tabla[4][3]: entero = 23; real = 23.00; cadena = Una cadena.
tabla[4][4]: entero = 24; real = 24.00; cadena = Una cadena.

Contenido de la matriz (3 X 5 X 5):

matriz[0][0][0]: entero = 0; real = 0.00; cadena = Una cadena.
matriz[0][0][1]: entero = 1; real = 1.00; cadena = Una cadena.
matriz[0][0][2]: entero = 2; real = 2.00; cadena = Una cadena.
...
matriz[2][4][2]: entero = 72; real = 72.00; cadena = Una cadena.
matriz[2][4][3]: entero = 73; real = 73.00; cadena = Una cadena.
matriz[2][4][4]: entero = 74; real = 74.00; cadena = Una cadena.


Terminación normal del programa.

*/



Ejercicio .- Construir un programa que, haciendo uso de las declaraciones anteriores, sea capaz de copiar una lista en una determinada fila de una tabla o matriz.

/*
Este programa muestra la forma de copiar una lista
en una determinada fila de una tabla o matriz.
Recuérdese que no hay comprobaciones.
Recuérdese que es fácil sobrepasar los límites
de filas y columnas.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define DIM_CAPAS 3
#define DIM_FILAS 5
#define DIM_COLS 5

struct Tipo_estructura {
	int un_entero;
	float un_real;
	char cadena[80];
};

/* Por brevedad. */
#define Tipo_base struct Tipo_estructura

Tipo_base lista[DIM_COLS];
Tipo_base tabla[DIM_FILAS][DIM_COLS];
Tipo_base matriz[DIM_CAPAS][DIM_FILAS][DIM_COLS];
Tipo_base * p;
int i,j,k;

int main(void)
{
printf ("Copia de filas en listas y tablas de Estructuras.\n\n");
/* Iniciación de la lista */
p = lista; /* lista señala el primer elemento */
for(i=0;i<DIM_COLS;i++)
{
	(p + i)->un_entero = i;
	(p + i)->un_real = i;
	strcpy((p + i)->cadena,"Cadena de Lista * * * * *.");
}
/* Iniciación de la tabla */
p = tabla[0]; /* O también &tabla[0][0] */
for(i=0;i<DIM_FILAS*DIM_COLS;i++)
{
	(p + i)->un_entero = i;
	(p + i)->un_real = i;
	strcpy((p + i)->cadena,"Cadena de tabla.");
}
/* Iniciación de la matriz */
p = matriz[0][0]; /* O también &matriz[0][0][0] */
for(i=0;i<DIM_CAPAS*DIM_FILAS*DIM_COLS;i++)
{
	(p + i)->un_entero = i;
	(p + i)->un_real = i;
	strcpy((p + i)->cadena,"Cadena de columna.");
}

	/* Copiamos la lista en la fila 2 de la tabla */
memcpy(tabla[2],lista,sizeof(lista));
/* Copiamos la lista en la capa 1, fila 2 de la matriz */
memcpy(matriz[1][2],lista,sizeof(lista));
/* Ahora mostramos todo con punteros */
printf("Contenido de la lista (0..%d):\n\n", DIM_COLS);
p = lista;
for(i=0;i<DIM_COLS;i++)
{
	printf("lista[%d]: entero = %6d; ",i, (p+i)->un_entero);
	printf("real = %6.2f; ",(p+i)->un_real);
	printf("cadena = %s\n",(p+i)->cadena);
}
printf("\nContenido de la tabla (%d X %d):\n\n", DIM_FILAS, DIM_COLS);
p = tabla[0];
for(i=0;i<DIM_FILAS;i++)
	for(j=0;j<DIM_COLS;j++)
	{
		printf("tabla[%d][%d]: entero = %6d; ",i,j, (p+i*DIM_COLS+j)->un_entero);
		printf("real = %6.2f; ",(p+i*DIM_COLS+j)->un_real);
		printf("cadena = %s\n",(p+i*DIM_COLS+j)->cadena);
	}
printf("\nContenido de la matriz (%d X %d X %d):\n\n",
DIM_CAPAS, DIM_FILAS, DIM_COLS);
p = matriz[0][0];
for(i=0;i<DIM_CAPAS;i++)
	for(j=0;j<DIM_FILAS;j++)
		for(k=0;k<DIM_COLS;k++)
		{
			printf("matriz[%d][%d][%d]: entero = %6d; ",
			i,j,k, (p+i*DIM_FILAS*DIM_COLS +j*DIM_COLS + k)->un_entero);
			printf("real = %6.2f; ",
			(p+i*DIM_FILAS*DIM_COLS +j*DIM_COLS + k)->un_real);
			printf("cadena = %s\n",
			(p+i*DIM_FILAS*DIM_COLS +j*DIM_COLS + k)->cadena);
		}

	printf("\n\nTerminación normal del programa.\n");
	return 0;
}
/*
RESULTADO (abreviado)
Todo funciona.
Copia de filas en listas y tablas de Estructuras.

	Contenido de la lista (0..5):

	lista[0]: entero = 0; real = 0.00; cadena = Cadena de Lista * * * * *.
lista[1]: entero = 1; real = 1.00; cadena = Cadena de Lista * * * * *.
lista[2]: entero = 2; real = 2.00; cadena = Cadena de Lista * * * * *.
lista[3]: entero = 3; real = 3.00; cadena = Cadena de Lista * * * * *.
lista[4]: entero = 4; real = 4.00; cadena = Cadena de Lista * * * * *.

	Contenido de la tabla (5 X 5):

	tabla[0][0]: entero = 0; real = 0.00; cadena = Cadena de tabla.
...
tabla[1][4]: entero = 9; real = 9.00; cadena = Cadena de tabla.
tabla[2][0]: entero = 0; real = 0.00; cadena = Cadena de Lista * * * * *.
tabla[2][1]: entero = 1; real = 1.00; cadena = Cadena de Lista * * * * *.
tabla[2][2]: entero = 2; real = 2.00; cadena = Cadena de Lista * * * * *.
tabla[2][3]: entero = 3; real = 3.00; cadena = Cadena de Lista * * * * *.
tabla[2][4]: entero = 4; real = 4.00; cadena = Cadena de Lista * * * * *.
...
tabla[4][4]: entero = 24; real = 24.00; cadena = Cadena de tabla.

	Contenido de la matriz (3 X 5 X 5):

	matriz[0][0][0]: entero = 0; real = 0.00; cadena = Cadena de columna.
...
matriz[1][1][4]: entero = 34; real = 34.00; cadena = Cadena de columna.
matriz[1][2][0]: entero = 0; real = 0.00; cadena = Cadena de Lista * * * * *.
matriz[1][2][1]: entero = 1; real = 1.00; cadena = Cadena de Lista * * * * *.
matriz[1][2][2]: entero = 2; real = 2.00; cadena = Cadena de Lista * * * * *.
matriz[1][2][3]: entero = 3; real = 3.00; cadena = Cadena de Lista * * * * *.
matriz[1][2][4]: entero = 4; real = 4.00; cadena = Cadena de Lista * * * * *.
matriz[1][3][0]: entero = 40; real = 40.00; cadena = Cadena de columna.
...
matriz[2][4][4]: entero = 74; real = 74.00; cadena = Cadena de columna.


Terminación normal del programa.
*/



Volver a la parte superior de esta página

Ejercicios propuestos



  1. Ejercicio 0705r01.- Se dispone de la estructura siguiente:
    
    struct Ficha {
    	char nombre[40];
    	float valor;
    };
    
    


    Se pide construir un programa que maneje una lista de estas fichas y sea capaz de mostrar la que tiene el valor máximoy el valor mínimo. Si se construye adecuadamente, una de las funciones de este ejercicio permitirá resolver fácilmente el siguiente.

  2. Ejercicio 0705r02.- Considérese la estructura del ejercicio anterior. Se pide construir un programa que maneje una tabla de fichas como estas, y que sea capaz de mostrar el máximo y el mínimo de valor la tabla.

  3. Ejercicio 0705r03.- Considérese el ejercicio anterior. Se pide construir un programa que muestre un tarugo de estas estructuras y que, para cada capa, sea capaz de mostrar los valores máximo y mínimo de la tabla.

  4. Ejercicio 0705r04.- Considérese una lista formada para las estructuras anteriores. Se pide construir un programa que la muestre en pantalla con formato encolumnado. Se recomienda utilizar la función sprintf() para preparar las líneas.

  5. Ejercicio 0705r05.- Considérese una lista formada para las estructuras anteriores. Se pide construir un programa que la muestre en pantalla con formato delimitado.

  6. Ejercicio 0705r06.- Se dispone de un archivo de texto que contiene el resultado de enviar a disco el resultado obtenido en pantalla en el Ejercicio 0705r04. Se pide construir un programa que lea de disco la información almacenada y reconstruya la lista original de estructuras.

  7. Ejercicio 0705r07.- Se dispone de un archivo de texto que contiene el resultado de enviar a disco el resultado obtenido en pantalla en el Ejercicio 0705r05. Se pide construir un programa que lea de disco la información almacenada y reconstruya la lista original de estructuras.

  8. Ejercicio 0705r08.- Considérese la lista empleada en los ejercicios anteriores. Escribir un programa adecuado para escribir y leer en disco la lista en cuestión, empleando un archivo de formato binario.