CAPÍTULO 5: Punteros y Estructuras

Como sabemos, podemos declarar un bloque de datos que alojen datos de diferentes tipos mediante la declaración de una estructura. Por ejemplo, un archivo personal puede contener una estructura parecida a la siguiente:

    struct registro {
        char nombre[20];        /* nombre */
        char apellidos[50];     /* apellidos */
        int edad;               /* edad */
        float salario;          /* por ej. 12.75 por hora */
    };

Digamos que tenemos un montón de estructuras como éstas en un archivo y queremos leerlas para mostrar los nombres y apellidos en un listado de personas. El resto de información no la necesitamos. Queremos hacer esto llamando a una función y pasarle un puntero a la estructura en cuestión. Para demostrarlo utilizaremos por ahora sólo una estructura y el objetivo será la escritura de esta función, no la lectura del archivo, que, seguramente ya sabemos hacer.

Como repaso, recuerda que podemos acceder a los miembros de una estructura mediante el operador punto, como en:

--------------- programa 5.1 -----------------

/* Programa 5.1 de PTRTUT10.HTM     6/13/97 */


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

struct registro {
    char nombre[20];      /* nombre */
    char apellidos[50];   /* apellidos */
    int edad;             /* edad */
    float salario;        /* por ej. 12.75 por hora */
};

struct registro mi_estructura;       /* declaración de la estructura mi_estructura */

int main(void)
{
    strcpy(mi_estructura.nombre,"Ted");
    strcpy(mi_estructura.apellidos,"Jensen");
    printf("\n%s ",mi_estructura.nombre);
    printf("%s\n",mi_estructura.apellidos);
    return 0;
}

--------------- fin del programa 5.1 ---------

Ahora bien, esta estructura en particular es bastante pequeña en comparación con otras muchas utilizadas en programas escritos en C. A lo anterior es posible que quieras agregar:

    fecha_contratacion;      (no se muestran los tipos de datos)
    fecha_ultimo_ascenso;
    ultimo_porcentaje_incremento;
    telefono_emergencia;
    seguro_medico_privado;
    numero_seguridad_social;
    etc.....

Si tenemos muchos empleados, lo suyo es manipular los datos de esas estructuras mediante funciones. Por ejemplo, podríamos querer pasar una estructura a una función para visualizar el nombre del empleado de esta estructura. Sin embargo en el original C (Kernighan & Ritchie, 1st Edition) no era posible pasar una estructura a una función, sólo se podía pasar un puntero que apunte a la estructura en cuestión. En ANSI C sí es posible pasar una estructura completa. Pero, ya que ahora nuestro objetivo es aprender más acerca de los punteros, lo veremos con punteros.

De todas formas, si pasamos toda la estructura a la función, el contenido de la estructura se copiará desde la función que realiza la llamada a la función que recibe la llamada. En sistemas que utilizan pilas, esto se realiza metiendo los contenidos de la estructura en la pila, pero si tenemos estructuras muy grandes, esto puede ser un problema. Sin embargo, si a la función le pasamos un puntero que apunta a una estructura, estaremos metiendo un puntero en la pila, que es una cantidad mínima de espacio.

En cualquier caso, como estamos hablando de punteros, veremos cómo pasar un puntero a una estructura y utilizarlo dentro de una función.

Consideremos el caso que hemos descrito, es decir, queremos una función que acepte un puntero (que apunta a una estructura) como parámetro, y dentro de esta función queremos acceder a los miembros de esta estructura para mostrar el nombre del empleado.

Bien, sabemos que nuestro puntero tiene que apuntar a una estructura declarada mediante struct registro. Este puntero lo declaramos así:

    struct registro *st_ptr;

y después hacemos que el puntero apunte a nuestra estructura con:

    st_ptr = &mi_estructura;

Ahora podemos acceder a un miembro mediante la desreferenciación del puntero, pero ¿cómo lo hacemos con un puntero que apunta a una estructura? Bien, consideremos que queremos utilizar el puntero para guardar la edad de un empleado. Lo podemos hacer así:

    (*st_ptr).edad = 63;

Mira esto con atención porque esto quiere decir: reemplaza lo que está entre paréntesis con el valor donde apunta st_ptr, que es la estructura mi_estructura. Si utilizamos mi_estructura.edad, el resultado sería el mismo.

Como esta es una expresión bastante frecuente, los diseñadores de C han creado una sintáxis alternativa para hacer lo mismo:

    st_ptr->edad = 63;

Con esto en mente, mira el siguiente programa:

------------ programa 5.2 --------------------

/* Programa 5.2 de PTRTUT10.HTM   6/13/97 */

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

struct registro{                /* el tipo de estructura */
    char nombre[20];            /* nombre */
    char apellidos[50];         /* apellidos */
    int edad;                   /* edad */
    float salario;              /* por ej. 12.75 por hora */
};

struct registro mi_estructura;            /* define la estructura */
void mostrar_nombre(struct registro *p);  /* prototipo de función */

int main(void)
{
    struct registro *st_ptr;     /* un puntero de tipo registro (estructura) */
    st_ptr = &mi_estructura;     /* el puntero apuntando a mi_estructura */
    strcpy(mi_estructura.nombre,"Ted");
    strcpy(mi_estructura.apellidos,"Jensen");
    printf("\n%s ",mi_estructura.nombre);
    printf("%s\n",mi_estructura.apellidos);
    mi_estructura.edad = 63;
    mostrar_nombre(st_ptr);      /* pasa el puntero */
    return 0;
}

void mostrar_nombre(struct registro *p)
{
    printf("\n%s ", p->nombre);  /* p apunta a una estructura */
    printf("%s ", p->apellidos);
    printf("%d\n", p->edad);
}

-------------------- fin del programa 5.2 ----------------

Una vez más, tenemos un montón de información para digerir. El lector debe compilar y ejecutar los diversos fragmentos de código y utilizar un depurador para ver cosas como mi_estructura y p paso a paso para ver lo que sucede.

Continuar con el Tutorial de Punteros

Tabla de Contenidos