← C EspañolChapter 08 of 13

Estructuras y Uniones

## Objetivos de Aprendizaje - Definir y usar estructuras - Trabajar con arreglos de estructuras - Comprender uniones - Dominar alineación de memoria ## Estructuras ### Definición ```c struct Point { int x; int y; }; ``` ### Declaración ```c struct Point p1; // Declaración struct Point p2 = {10, 20}; // Declaración con inicialización ``` ### Acceder Miembros ```c struct Point p; p.x = 10; p.y = 20; printf("%d %d\n", p.x, p.y); ``` ### Inicialización ```c struct Point p1 = {10, 20}; struct Point p2 = {.x = 10, .y = 20}; // Inicializadores designados (C99) ``` ## typedef ### Con Estructuras ```c typedef struct { int x; int y; } Point; Point p1 = {10, 20}; Point p2 = {30, 40}; ``` ### Nombres Más Claros ```c typedef struct Person { char name[50]; int age; float salary; } Person; Person employee = {"Alice", 30, 50000.0f}; ``` ## Estructuras y Funciones ### Paso por Valor ```c struct Point { int x; int y; }; double distance(struct Point p) { return sqrt((double)p.x * p.x + (double)p.y * p.y); } int main(void) { struct Point p = {3, 4}; printf("%f\n", distance(p)); // 5.0 return 0; } ``` ### Paso por Puntero ```c void move(struct Point *p, int dx, int dy) { p->x += dx; p->y += dy; } int main(void) { struct Point p = {0, 0}; move(&p, 3, 4); printf("%d %d\n", p.x, p.y); // 3 4 return 0; } ``` ### Operador Flecha (->) ```c struct Point { int x; int y; }; struct Point *ptr = malloc(sizeof(struct Point)); ptr->x = 10; // Igual que (*ptr).x = 10; ptr->y = 20; free(ptr); ``` ## Estructuras Anidadas ```c struct Address { char city[50]; char street[100]; }; struct Person { char name[50]; struct Address address; }; int main(void) { struct Person p = { "Alice", {"New York", "123 Main St"} }; printf("%s\n", p.address.city); return 0; } ``` ## Arreglos de Estructuras ```c struct Point { int x; int y; }; struct Point points[10]; points[0].x = 0; points[0].y = 0; struct Point p1 = {1, 2}; points[1] = p1; ``` ### Arreglo de Estructuras typedef ```c typedef struct { char name[50]; int age; } Person; Person people[] = { {"Alice", 30}, {"Bob", 25}, {"Charlie", 35} }; int count = sizeof(people) / sizeof(people[0]); ``` ## Campos de Bits ### Declaración de Campo de Bits ```c struct Flags { unsigned int isActive : 1; unsigned int isVisible : 1; unsigned int mode : 3; // 3 bits (0-7) }; struct Flags f; f.isActive = 1; f.mode = 3; ``` ### Caso de Uso ```c struct Packet { unsigned int type : 4; // 0-15 unsigned int id : 8; // 0-255 unsigned int data : 20; // 0-1,048,575 }; ``` ## Uniones ### Definición de Unión ```c union Data { int i; float f; char c; }; ``` ### Todos los Miembros Comparten la Misma Memoria ```c union Data d; d.i = 42; printf("%d\n", d.i); // 42 d.f = 3.14f; printf("%f\n", d.f); // 3.14 (sobrescribe i) d.c = 'A'; printf("%c\n", d.c); // A (sobrescribe todo) ``` ### Tamaño ```c union Data { int i; // 4 bytes float f; // 4 bytes char c; // 1 byte }; printf("%zu\n", sizeof(union Data)); // 4 (tamaño del miembro más grande) ``` ## Uniones para Etiquetas de Tipo ```c typedef enum { INT, FLOAT, STRING } Type; typedef struct { Type type; union { int i; float f; char *s; } value; } Variant; void print(Variant *v) { switch (v->type) { case INT: printf("%d\n", v->value.i); break; case FLOAT: printf("%f\n", v->value.f); break; case STRING: printf("%s\n", v->value.s); break; } } ``` ## Estructuras Anónimas (C11) ```c struct Outer { int x; struct { // Estructura anónima int y; int z; }; // Miembros accesibles directamente desde Outer }; int main(void) { struct Outer o; o.x = 1; o.y = 2; // Acceso directo a miembros de estructura anónima o.z = 3; return 0; } ``` ## Uniones Anónimas (C11) ```c struct Container { int type; union { // Unión anónima int i; float f; }; }; ``` ## Alineación de Memoria ### Relleno de Estructura ```c struct A { char c; // 1 byte + 3 de relleno int x; // 4 bytes }; printf("%zu\n", sizeof(struct A)); // 8, no 5 ``` ### Estructura Empaquetada ```c #pragma pack(push, 1) struct B { char c; int x; }; #pragma pack(pop) printf("%zu\n", sizeof(struct B)); // 5 ``` ### #define packed ```c #define PACKED __attribute__((__packed__)) struct PACKED C { char c; int x; }; ``` ## Cálculo de Desplazamiento ```c #include struct Person { char name[50]; int age; float salary; }; printf("%zu\n", offsetof(struct Person, name)); // 0 printf("%zu\n", offsetof(struct Person, age)); // 52 printf("%zu\n", offsetof(struct Person, salary)); // 56 ``` ## Estructura Auto-referencial ### Nodo de Lista Enlazada ```c typedef struct Node { int data; struct Node *next; } Node; Node *head = malloc(sizeof(Node)); head->data = 1; head->next = malloc(sizeof(Node)); head->next->data = 2; head->next->next = NULL; ``` ### Nodo de Árbol ```c typedef struct TreeNode { int data; struct TreeNode *left; struct TreeNode *right; } TreeNode; ``` ## Resumen - Estructuras: `struct Nombre { miembros };` - Usar `typedef` para nombres más limpios - Acceder miembros con `.` (punto) - Usar `->` para puntero a estructura - Las uniones comparten memoria (tamaño del miembro más grande) - Campos de bits: `unsigned int x : n;` - Las estructuras pueden tener relleno - Usar `offsetof()` para desplazamientos de miembros - Estructuras auto-referenciales para listas enlazadas

Comments

Comments powered by Giscus

To enable comments, add your Giscus embed code here.

Learn more about Giscus →