HOWTO · C

Cómo usar typedef enum en C

Este artículo presenta cómo usar typedef enum en C, explica sus ventajas y ofrece ejemplos claros. Aprenda a mejorar la legibilidad y el mantenimiento del código con typedef enum, y descubra cómo usarlo en structs. Tanto si es principiante como si busca perfeccionar sus habilidades, esta guía le ayudará a manejar los enums en C con facilidad.

En esta página

En C, un enum declara constantes enteras con nombre, y typedef puede dar al tipo enum un nombre más corto. Utilice los nombres para que los valores de estado y de opciones sean más fáciles de leer, y luego trate esos valores de forma explícita siempre que la entrada o los datos almacenados puedan proceder de fuera de su programa. Un enum mejora la claridad, pero no valida automáticamente cada valor asignado a una variable.

Definir un enum y asignar valores

Un enumerador sin un valor explícito comienza en 0; cada enumerador siguiente es uno mayor que el valor anterior. Por ejemplo, enum { MONDAY, TUESDAY, WEDNESDAY }; asigna 0, 1 y 2. Puede asignar valores de forma explícita cuando deben coincidir con un formato, protocolo o conjunto estable de códigos existente: enum Status { STATUS_READY = 1, STATUS_RUNNING = 4, STATUS_DONE = 8 };. Después de un valor explícito, el siguiente valor implícito es uno mayor que ese valor.

Los nombres como STATUS_READY son constantes enteras. No son variables. A una variable enum se le puede asignar un valor diferente más adelante, y C no suele restringirla a los enumeradores enumerados en su declaración. Trate los valores procedentes de la entrada, de archivos u otras fuentes externas como datos que deben comprobarse antes de utilizarlos.

Crear un alias typedef para un enum

Una etiqueta enum y un alias typedef son nombres relacionados pero distintos. Con enum State { ... };, una declaración utiliza enum State. Un typedef puede introducir el alias más corto State, lo que permite declaraciones como State current;. El alias se refiere al mismo tipo; typedef no crea un tipo distinto. La escritura combinada typedef enum State { ... } State; declara la etiqueta y el alias juntos.

Este ejemplo solicita un entero, comprueba que la lectura se realiza correctamente y valida el valor antes de convertirlo a State y almacenarlo en el campo de Job. Introduzca 2 para ver la ruta correcta. El programa imprime la solicitud y el valor repetido en la misma línea, y luego el switch imprime Running. Si la lectura falla o el número está fuera de los tres estados admitidos, el programa imprime un mensaje y se detiene antes de la conversión.

#include <stdio.h>

typedef enum State {
    STATE_READY = 1,
    STATE_RUNNING = 2,
    STATE_DONE = 3
} State;

typedef struct Job {
    State state;
} Job;

int main(void) {
    int input;
    printf("Input: ");
    if (scanf("%d", &input) != 1) {
        puts("Could not read an integer.");
        return 0;
    }
    printf("%d\n", input);

    if (input != STATE_READY && input != STATE_RUNNING && input != STATE_DONE) {
        puts("Unsupported state.");
        return 0;
    }

    Job job = { (State)input };
    switch (job.state) {
        case STATE_READY:
            puts("Ready");
            break;
        case STATE_RUNNING:
            puts("Running");
            break;
        case STATE_DONE:
            puts("Done");
            break;
        default:
            puts("Unsupported state.");
            break;
    }

    return 0;
}
Input: Could not read an integer.

Usar un tipo enum en un struct

El struct Job anterior almacena su estado en un campo State. Esto mantiene el estado junto a los demás datos que describen un trabajo, mientras que las constantes enum hacen que las asignaciones y los casos de switch sean legibles. También puede declarar el campo con la etiqueta como enum State state; si decide no definir un alias typedef.

Un struct no añade validación al campo. Si el valor procede de una fuente que puede proporcionar un número no admitido, compruébelo antes de confiar en él. La rama default ofrece al programa una respuesta definida cuando el valor almacenado no coincide con ninguno de los estados con nombre. Si una aplicación concreta necesita garantías más estrictas, valide en el límite por el que el valor entra en el programa y mantenga esa comprobación cerca de la asignación.

Elegir los valores de un enum y usarlos de forma segura

Utilice valores implícitos cuando las constantes sean etiquetas internas y su representación numérica no importe. Asigne valores de forma explícita cuando otra interfaz requiera números concretos, y mantenga esas asignaciones estables si los datos se guardan o se intercambian. En ambos casos, las constantes con nombre comunican la intención mejor que los literales enteros sin explicación y ofrecen a quienes mantienen el código un único lugar donde ver las etiquetas disponibles.

Estas ventajas no hacen que las variables enum sean de solo lectura ni garantizan que contengan únicamente enumeradores con nombre. Una variable puede cambiar durante la ejecución, y una conversión o una entrada externa pueden producir un valor que no tenga un nombre correspondiente. Utilice un switch con una rama default, o valide el valor frente a los enumeradores aceptados antes de procesarlo. Esto evita que datos inesperados sigan silenciosamente una ruta pensada para un estado conocido.

En resumen, declare el enum para las constantes con nombre, añada un alias typedef cuando aclare las declaraciones, y utilice el tipo resultante siempre que corresponda el estado, incluidos los campos de struct y los parámetros de función. Elija valores numéricos explícitos solo cuando los números formen parte de un requisito, y mantenga la validación separada de la comodidad de nomenclatura que ofrecen los enums.