Estructuras

En este episodio hablamos de las estructuras y de cómo se pueden usar para agrupar datos. Por medio de la palabra clave struct podemos declararlas y luego podemos usarlas para hacer cosas chulas.

Las estructuras en C son una herramienta fundamental para organizar datos relacionados de manera coherente y manejable dentro de nuestros programas. En lugar de trabajar con variables sueltas y separadas, las estructuras nos permiten agrupar varios datos bajo un mismo identificador, facilitando así la manipulación de entidades completas, como podría ser una cuenta bancaria o una persona en una libreta de direcciones.

Para declarar una estructura en C, utilizamos la palabra clave struct seguida del nombre que queramos darle a la estructura, por ejemplo, cuenta. Entre llaves definimos los campos que compondrán esa estructura, que pueden ser variables de distintos tipos. Es importante recordar que al finalizar la declaración de la estructura debemos poner un punto y coma, algo que suele olvidarse y provoca errores de compilación.

Por ejemplo, podemos definir una estructura cuenta con campos para el nombre del cliente, apellido, saldo e identificador, así:

struct cuenta {
    char nombre[30];
    char apellido[40];
    int saldo;
    int identificador;
};

Una vez declarada la estructura, podemos crear variables de ese tipo usando la sintaxis struct cuenta c1;. Esta variable c1 contendrá todos los campos definidos en la estructura y podremos acceder a ellos mediante el operador punto (.). Por ejemplo, para asignar un saldo a c1 haríamos c1.saldo = 400;.

Para trabajar con cadenas de caracteres dentro de las estructuras, es común utilizar funciones de la biblioteca estándar string.h. Aunque un string en C es simplemente un array de caracteres terminado en un carácter nulo ('\0'), estas funciones nos ayudan a manipularlos de forma más sencilla. Por ejemplo, para copiar un nombre a c1.nombre podemos usar strcpy(c1.nombre, "Pepito");. Sin embargo, hay que tener cuidado con strcpy porque no verifica el tamaño del destino y puede provocar desbordamientos si la cadena de origen es demasiado larga.

Es importante entender que las cadenas en C terminan con un carácter nulo, que indica el final de la cadena. Esto es fundamental para que las funciones de manipulación de strings sepan dónde detenerse.

Para mostrar los datos de una estructura, podemos crear funciones que reciban la estructura como parámetro. Por ejemplo, una función que imprima los datos de una cuenta podría definirse así:

#include <stdio.h>

void imprimirDatos(struct cuenta c) {
    printf("Cliente %s %s tiene %d euros en cuenta.\n", c.nombre, c.apellido, c.saldo);
}

Al pasar la estructura como parámetro, C realiza una copia completa de la misma. Esto puede ser ineficiente si la estructura es grande o compleja. Por eso, es habitual pasar un puntero a la estructura en lugar de la estructura completa. De esta forma, solo se copia la dirección de memoria, y la función puede acceder directamente a los datos originales.

Cuando trabajamos con punteros a estructuras, la sintaxis para acceder a los campos cambia. No podemos usar el operador punto directamente sobre un puntero. En su lugar, tenemos dos opciones. La primera es desreferenciar el puntero y luego usar el punto:

(*c).saldo = 400;

Pero esta sintaxis puede ser engorrosa, por lo que C ofrece un operador especial, la flecha (->), que combina la desreferenciación y el acceso al campo en una sola expresión:

c->saldo = 400;

Esta forma es mucho más cómoda y es la que se utiliza habitualmente cuando manejamos punteros a estructuras.

En resumen, las estructuras nos permiten agrupar datos relacionados, facilitando la gestión de entidades complejas en nuestros programas. Aprender a declararlas, acceder a sus campos y pasarlas a funciones, ya sea por valor o por puntero, es esencial para escribir código en C más organizado y eficiente. Además, el manejo adecuado de cadenas dentro de estas estructuras es clave para evitar errores y asegurar la integridad de los datos.

Lista de reproducción
  1. 1
    Instalar CodeBlocks
    15 minutos
  2. 2
    Funciones y hola mundo
    17 minutos
  3. 3
    Variables y tipos de datos
    17 minutos
  4. 4
    Condicionales y operadores lógicos
    16 minutos
  5. 5
    Bucles
    11 minutos
  6. 6
    Punteros
    12 minutos
  7. 7
    Arrays
    14 minutos
  8. 8
    Estructuras
    12 minutos
  9. 9
    Otras construcciones de C
    9 minutos
  10. 10
    Memoria dinámica
    8 minutos
  11. 11
    El preprocesador (parte 1)
    10 minutos
  12. 12
    El preprocesador (parte 2)
    9 minutos
  13. 13
    Archivos de cabecera y múltiples .c (parte 1)
    8 minutos
  14. 14
    Archivos de cabecera y múltiples .c (parte 2)
    9 minutos
  15. 15
    C desde la línea de comandos (parte 1)
    8 minutos
  16. 16
    C desde la línea de comandos (parte 2)
    9 minutos
  17. 17
    Break y continue
    10 minutos
  18. 18
    Goto
    13 minutos
  19. 19
    Manipulación de bits
    15 minutos
  20. 20
    Máscaras de bit
    19 minutos
  21. 21
    Archivos (1): fopen y fclose
    13 minutos
  22. 22
    Archivos (2): leer con fgetc
    9 minutos
  23. 23
    Archivos (3): fseek y ftell
    11 minutos
  24. 24
    Archivos (4): leer con fgets
    9 minutos
  25. 25
    Archivos (5): fputc y fputs
    7 minutos
  26. 26
    Archivos (6): volcar en archivos con fwrite
    10 minutos
  27. 27
    Archivos (7): fread, fwrite y los arrays
    10 minutos
  28. 28
    Archivos (8): entrada estándar y salida estándar
    9 minutos
  29. 29
    Archivos (9): buffers
    14 minutos
  30. 30
    Archivos (y 10): otras funciones útiles con archivos
    5 minutos
  31. 31
    printf (1)
    18 minutos
  32. 32
    printf (parte 2)
    12 minutos
  33. 33
    scanf (parte 1)
    17 minutos
  34. 34
    scanf (parte 2)
    17 minutos
  35. 35
    fprintf, sprintf y snprintf
    8 minutos
  36. 36
    Tipos de datos opacos
    13 minutos
  37. 37
    Bibliotecas estáticas
    13 minutos
  38. 38
    Bibliotecas dinámicas
    15 minutos
  39. 39
    Más flags: i mayúscula (include), wall, werror, pedantic...
    12 minutos
  40. 40
    pkg-config
    12 minutos
  41. 41
    Make
    17 minutos
  42. 42
    GDB
    21 minutos
  43. 43
    Variables globales
    6 minutos
  44. 44
    extern
    9 minutos
  45. 45
    Funciones variádicas
    12 minutos
  46. 46
    El optimizador de GCC y la opción -O
    12 minutos
  47. 47
    Volatile
    6 minutos