Otro escenario en el que los punteros son de gran utilidad es para “enlazar” estructuras de datos. Supongamos que en la agenda de tu teléfono móvil puedes guardar para cada contacto un mapa. Una posible estructura de datos almacenaría los datos del contacto y tendría un campo para almacenar el mapa. A continuación se muestra una posible definición de las estructuras de datos:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #define SIZE 64 struct datos_mapa { /* Datos referentes al mapa */ ... }; struct datos_contacto { char nombre[SIZE]; char apellidos[SIZE]; ... /* Datos del mapa para este contacto */ struct datos_mapa mapa; }; |
Si la agenda almacena 100 contactos, cada uno de ellos tiene el espacio para almacenar los datos del mapa. Pero imaginemos que este mapa ocupa mucho espacio en memoria debido a los gráficos, y que varios usuarios tienen el mismo mapa, por lo que largas porciones de memoria son réplicas. Lo ideal es mantener la posibilidad de tener un mapa por contacto, pero a la vez evitar tener mapas duplicados. Una posible solución es guardar por separado los usuarios y los mapas. En la estructura del usuario se “enlaza” el mapa pertinente. De esta forma, si varios usuarios comparten el mismo mapa, todos estarán enlazados a una única copia. Este enlace se puede implementar con el uso de punteros tal y como se muestra en las siguientes definiciones:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #define SIZE 64
struct datos_mapa
{
/* Datos referentes al mapa */
...
};
struct datos_contacto
{
char nombre[SIZE];
char apellidos[SIZE];
...
/* Enlace a los datos del mapa */
struct datos_mapa *mapa;
}; |
En la siguiente figura se muestra la diferencia en tamaño de memoria utilizado en las dos soluciones para el caso en que cinco contactos comparten dos mapas.
Con la nueva solución, el acceso a los datos del mapa se
debe hacer con el operador de indirección
“->
” porque el campo de los datos del mapa es
un puntero.