Prerrequisitos: declaraciones de variables, punteros,
structy archivos de cabecera.Objetivos: 1. Crear un alias con
typedef. 2. Distinguir un alias de la creación de un tipo nuevo.Comprobación de salida: reescribí una declaración de puntero usando un alias y explicá qué tipo sigue representando.
Definición de Tipos y Alias¶
Introducción¶
En C, el mecanismo nativo para crear nombres alternativos o alias de tipos
de datos es la palabra clave typedef. A diferencia de lo que ocurre en otros
lenguajes, typedef no introduce un nuevo tipo de dato físicamente diferente
para el compilador; simplemente asocia un identificador secundario a un tipo
existente (primitivo, puntero, estructura o enumeración) para simplificar la
escritura o mejorar la abstracción conceptual del código.
Desarrollo¶
Alias de Tipos con typedef¶
La declaración se asemeja a la de una variable estándar, pero precedida por
typedef:
typedef tipo_existente nuevo_nombre_t;Por ejemplo, si necesitás trabajar con enteros que representen distancias en metros y querés que el código exprese con claridad esa unidad:
typedef double metros_t;
// Ahora podés usar 'metros_t' como un tipo estándar
metros_t distancia_casa = 1500.50;
metros_t altura_edificio = 45.2;Físicamente, distancia_casa es un double. El compilador simplemente
reemplazará sintácticamente metros_t por double durante el análisis
semántico.
Abstracción de Plataforma¶
Uno de los usos más rigurosos de typedef es garantizar la portabilidad e
independencia del hardware. Tipos de datos como int o long pueden variar su
tamaño en bytes dependiendo de la arquitectura de la CPU (16, 32 o 64 bits).
Mediante typedef, se pueden definir alias que denoten explícitamente el ancho
físico del tipo de dato, facilitando la compilación del mismo código en
múltiples plataformas:
// Definiciones basadas en la arquitectura del compilador
typedef signed char entero8_t;
typedef short int entero16_t;
typedef int entero32_t;
typedef long long int entero64_t;(Nota: En el C estándar moderno, estas definiciones ya se encuentran
normalizadas en la cabecera estándar <stdint.h> mediante los tipos int8_t,
int16_t, int32_t e int64_t).
Regla de Estilo de la Cátedra: El sufijo _t¶
Para mantener la claridad y coherencia en el código desarrollado, la cátedra
impone la regla 0x3004h: Utilizá typedef para definir tipos de estructuras con el sufijo _t, la cual establece que todo alias de tipo
creado mediante typedef debe finalizar de forma obligatoria con el sufijo
_t (por ejemplo, metros_t, velocidad_t, nodo_t). Esto permite
distinguir instantáneamente los tipos personalizados de las variables y
constantes en cualquier bloque de código.
A lo largo de este apunte le iremos dando uso a este concepto de manera gradual, particularmente para simplificar la declaración de estructuras complejas (Bloque 3) y la definición de Tipos de Datos Abstractos (Bloque 4).
Enumeraciones en C¶
Las enumeraciones (enum) se utilizan para representar conjuntos finitos y
discretos de constantes enteras nombradas.
Para un análisis detallado de la sintaxis de enumerativos, la asignación de valores, las colisiones en espacios de nombres y las validaciones de rango con switch defensivo, consultá el capítulo específico de Blockquote.
Typedef de Structs y Arreglos¶
El patrón más frecuente en C no aplica typedef a un tipo ya declarado, sino
que combina la declaración de una struct (o un arreglo) con su alias en una
única sentencia:
typedef struct
{
double x;
double y;
} punto_t;
punto_t origen = {0.0, 0.0};Acá typedef no le da nombre a la struct en sí (que queda anónima), sino al
tipo resultante de esa declaración. Es equivalente, aunque menos común, dar un
nombre de etiqueta (tag) a la struct y asignarle el alias por separado:
struct punto { double x; double y; };
typedef struct punto punto_t;La primera forma es la que vas a ver a lo largo de todo este apunte
(empezando por 7_estructuras.md): evita repetir la palabra struct en cada
declaración de variable y es la forma idiomática recomendada por la cátedra.
typedef también puede nombrar un tipo arreglo completo, incluyendo su
tamaño:
typedef int vector3_t[3];
vector3_t velocidad = {1, 0, -1}; // equivale a: int velocidad[3]Typedef de Punteros a Función¶
La sintaxis de un puntero a función es una de las más difíciles de leer en C. Comparalos:
// Sin alias: hay que leer "de adentro hacia afuera"
int (*operacion)(int, int);
// Con alias: el tipo se lee como cualquier otra declaración
typedef int (*operacion_t)(int, int);
operacion_t operacion;operacion_t es un alias para “puntero a función que recibe dos int y
retorna int”. Una vez declarado, se usa como cualquier otro tipo: como
parámetro de función (para recibir un callback), como campo de una
struct, o como tipo de una variable local.
typedef int (*comparador_t)(const void *a, const void *b);
void ordenar(void *base, size_t n, size_t tam, comparador_t comparar)
{
qsort(base, n, tam, comparar);
}Sin el alias, la misma firma de ordenar se escribiría
void ordenar(void *base, size_t n, size_t tam, int (*comparar)(const void *, const void *))
— válida, pero mucho más difícil de leer y de repetir consistentemente en
.h y .c. El uso de punteros a función como parámetro se retoma en
profundidad en el Bloque 4, al estudiar callbacks y genericidad.
Ejercicios de Autoevaluación¶
Solution to Exercise 1
1 2 3 4 5 6 7 8 9 10 11 12 13#include <stdio.h> // Definición de alias con el sufijo _t obligatorio typedef double distancia_t; typedef double tiempo_t; typedef double velocidad_t; velocidad_t calcular_velocidad(distancia_t d, tiempo_t t) { if (t <= 0.0) { return 0.0; } return d / t; }
Solution to Exercise 2
typedef unsigned char u8_t;
typedef unsigned short u16_t;
typedef unsigned int u32_t;Estas declaraciones garantizan la portabilidad porque si el código se porta a un
microcontrolador donde int ocupa 16 bits, solo es necesario redefinir el alias
u32_t a unsigned long en un único archivo centralizado, sin alterar las
declaraciones de variables a lo largo de todo el proyecto.
Solution to Exercise 3
No define un nuevo tipo de dato físicamente diferente.
typedef introduce únicamente un sinónimo o alias sintáctico en la tabla de
símbolos del compilador. Físicamente, el compilador trata a las variables
real_t como variables de tipo float estándar. Por lo tanto, realizar la
asignación directa entre variables de ambos tipos es totalmente válido y no
requiere ningún moldeo de tipo (cast), ya que no existe incompatibilidad
alguna.
Solution to Exercise 4
1 2 3 4 5 6 7 8 9 10typedef struct { double ancho; double alto; } rectangulo_t; double area(rectangulo_t r) { return r.ancho * r.alto; }
La struct no necesita un nombre de etiqueta propio porque nunca se la
referencia como struct algo: todo el código posterior usa el alias
rectangulo_t.
Solution to Exercise 5
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21#include <stdbool.h> #include <stddef.h> typedef bool (*validador_t)(int); bool es_par(int n) { return n % 2 == 0; } size_t contar_que_cumplen(const int *arreglo, size_t n, validador_t validar) { size_t contador = 0; for (size_t i = 0; i < n; i++) { if (validar(arreglo[i])) { contador++; } } return contador; }
contar_que_cumplen no conoce de antemano qué condición va a evaluar: recibe
esa lógica como un parámetro más, mediante validador_t. Esto le permite
reutilizarse con cualquier función que cumpla la firma bool (*)(int), sin
modificar su propio código.
Glosario¶
- Alias de tipo (typedef)
- Nombre alternativo asignado a un tipo de dato existente para mejorar la legibilidad y abstracción.
- Portabilidad
- Capacidad de un código para compilar y ejecutarse correctamente en diferentes arquitecturas de CPU sin cambios mayores.
Síntesis y Resumen¶
La directiva typedef se emplea para crear alias de tipos en C sin generar
nuevos tipos físicos. Su uso facilita la abstracción y la portabilidad del
código entre arquitecturas con diferentes tamaños de datos, y es el mecanismo
estándar para nombrar struct anónimas y punteros a función, dos patrones
que aparecen en todo el resto del libro. Por normas de la cátedra, todo alias
definido con typedef debe utilizar obligatoriamente el sufijo _t.
Referencias y Lecturas Complementarias¶
Kernighan & Ritchie (2014). Capítulo 5: Pointers and Arrays y Capítulo 6: Structures (sección
typedef).King (2008). Capítulo 14: The Preprocessor (secciones de tipos).
- Kernighan, B. W., & Ritchie, D. M. (2014). C Programming Language, 2nd Edition.
- King, K. N. (2008). C Programming: A Modern Approach (2nd ed.). W. W. Norton & Company.