Número de elementos en una enumeración

7 minutos de lectura

En C, ¿hay una buena manera de rastrear la cantidad de elementos en una enumeración? He visto

enum blah {
    FIRST,
    SECOND,
    THIRD,
    LAST
};

Pero esto solo funciona si los elementos son secuenciales y comienzan en cero.

  • Ver la pregunta en enum en C++ como enum en Ada.

    –Jonathan Leffler

    23 de abril de 2013 a las 17:58

Si no asigna sus enumeraciones, puede hacer algo como esto:

enum MyType {
  Type1,
  Type2,
  Type3,
  NumberOfTypes
}

NumberOfTypes evaluará a 3, que es el número de tipos reales.

  • ¿Puede estar siempre seguro de que en cada implementación de C, en cualquier lugar y en todo momento, las enumeraciones comienzan desde 0? Supongo que sí, pero ¿es siempre realmente cierto?

    – JohnyTex

    30 de noviembre de 2017 a las 11:22

  • Respuesta tardía @JohnyTex, pero el estándar C menciona en ‘Especificadores de enumeración’: If the first enumerator has no =, the value of its enumeration constant is 0. Each subsequent enumerator with no = defines its enumeration constant as the value of the constant expression obtained by adding 1 to the value of the previous enumeration constant. Entonces, sí, esto se aplicaría a cualquier implementación que cumpla con los estándares.

    – seri

    7 ago 2018 a las 21:29


No creo que haya. Pero, ¿qué harías con ese número si no son secuenciales y no tienes una lista de ellos en alguna parte? Y si son secuenciales pero comienzan en un número diferente, siempre puedes hacer:

enum blah {
    FIRST = 128,
    SECOND,
    THIRD,
    END
};
const int blah_count = END - FIRST;

  • ¿Pueden los tipos de enumeración ser negativos? Si es así, cuidado con este.

    – ojblass

    3 de abril de 2009 a las 3:51

  • FIRST=-2 aún calcularía correctamente, creo: 1 – (-2) = 3.

    – pax diablo

    3 de abril de 2009 a las 3:53

  • No hay necesidad de tener cuidado; la resta funciona bien para números negativos. Pax tiene razón.

    –Brian Campbell

    3 de abril de 2009 a las 3:59

  • PRIMERO = -200, SEGUNDO = -199, TERCERO = -198, FIN = -100. -200 – (-100) = malas noticias

    – ojblass

    3 de abril de 2009 a las 4:00

  • No, obtendrías PRIMERO = -9 SEGUNDO = -8 TERCERO = -7 FIN = -6, entonces tendrías -6 – (-9) = -6 + 9 = 3

    –Brian Campbell

    3 de abril de 2009 a las 4:18

Numero de elementos en una enumeracion
Sam

Vieja pregunta, lo sé. Esto es para los googlers con la misma pregunta.

podrías usar X-macros

Ejemplo:

//The values are defined via a map which calls a given macro which is defined later
#define ENUM_MAP(X) \
      X(VALA, 0)    \
      X(VALB, 10)   \
      X(VALC, 20)

//Using the map for the enum decl
#define X(n, v) [n] = v,
typedef enum val_list {
    ENUM_MAP(X) //results in [VALA] = 0, etc...
} val_list;
#undef X

//For the count of values
#define X(n, v) + 1
int val_list_count = 0 + ENUM_MAP(X); //evaluates to 0 + 1 + 1 + 1
#undef X

Esto también es transparente para un IDE, por lo que la función de autocompletar funcionará bien (ya que todo se hace en el preprocesador).

  • Impresionante, en realidad vine aquí porque estaba buscando una buena manera de determinar el número de elementos en una X_MACRO, y esta es una buena manera.

    – BeeOnRope

    5 de noviembre de 2016 a las 23:38

  • También podría simplemente tomar el número de elementos en el val_list matriz usando el lenguaje idiomático (sizeof val_list / sizeof val_list[0])

    – Jo So

    14 dic 2017 a las 21:43

  • Probablemente debería ser n = v, aunque,

    – Antti Haapala — Слава Україні

    9 de agosto de 2019 a las 2:07

Lamentablemente no. No hay.

Numero de elementos en una enumeracion
David Stosik

Sé que esta es una pregunta muy antigua, pero como la respuesta aceptada es incorrecta, me siento obligado a publicar la mía. Reutilizaré el ejemplo de la respuesta aceptada, ligeramente modificado. (Suponiendo que las enumeraciones son secuenciales).

// Incorrect code, do not use!
enum blah {
  FIRST   =  0,
  SECOND, // 1
  THIRD,  // 2
  END     // 3
};
const int blah_count = END - FIRST;
// And this above would be 3 - 0 = 3, although there actually are 4 items.

Cualquier desarrollador sabe la razón: count = last - first + 1. Y esto funciona con cualquier combinación de signos (ambos extremos negativos, ambos positivos o solo el primer extremo negativo). Puedes probar.

// Now, the correct version.
enum blah {
  FIRST   =  0,
  SECOND, // 1
  THIRD,  // 2
  END     // 3
};
const int blah_count = END - FIRST + 1; // 4

Editar: leyendo el texto de nuevo, tengo una duda. Es eso END destinado a no ser parte de los artículos ofrecidos? Eso me parece raro, pero bueno, supongo que podría tener sentido…

  • La intención es que haya 3 elementos en la enumeración (FIRST, SECOND & THIRD), siendo el último un marcador de posición que siempre designa el final de la lista, de modo que si se agregan elementos adicionales, no es necesario cambiar la fórmula para el recuento de elementos.

    –Peter Gibson

    28 de enero de 2015 a las 1:31

  • Sí, eso es lo que pensé cuando volví a leer unas horas más tarde. Gracias por confirmar. Un comentario al lado END que dice “No está destinado a ser utilizado” o algo que pueda ayudar a comprender el código.

    – David Stosik

    30 de enero de 2015 a las 7:59


  • Me gusta usar una convención como “blah_end_marker”; el “marcador_final” identifica el propósito, mientras que el prefijo mantiene distintos los marcadores finales. Luego puede definir el conteo, o para las enumeraciones “secuenciales” que comienzan con 0, use el valor del marcador directamente (por ejemplo, “blah all_blahs[blah_end_marker];” – aunque empiezo a pensar que la const int blah_count tiene más sentido…

    – Beto

    26 oct 2017 a las 14:36

  • Solo funciona si los valores asignados aumentan monótonamente en 1

    – Larry_C

    6 ene a las 18:06

  • ¿A qué valores se les asigna valor no consecutivo? No voy a volar.

    – Larry_C

    6 ene a las 18:24

1647535629 2 Numero de elementos en una enumeracion
paxdiablo

Bueno, dado que las enumeraciones no pueden cambiar en tiempo de ejecución, lo mejor que puede hacer es:

enum blah {
    FIRST = 7,
    SECOND = 15,
    THIRD = 9,
    LAST = 12
};
#define blahcount 4 /* counted manually, keep these in sync */

Pero me resulta difícil imaginar una situación en la que esa información sería útil. ¿Qué estás tratando de hacer exactamente?

  • La intención es que haya 3 elementos en la enumeración (FIRST, SECOND & THIRD), siendo el último un marcador de posición que siempre designa el final de la lista, de modo que si se agregan elementos adicionales, no es necesario cambiar la fórmula para el recuento de elementos.

    –Peter Gibson

    28 de enero de 2015 a las 1:31

  • Sí, eso es lo que pensé cuando volví a leer unas horas más tarde. Gracias por confirmar. Un comentario al lado END que dice “No está destinado a ser utilizado” o algo que pueda ayudar a comprender el código.

    – David Stosik

    30 de enero de 2015 a las 7:59


  • Me gusta usar una convención como “blah_end_marker”; el “marcador_final” identifica el propósito, mientras que el prefijo mantiene distintos los marcadores finales. Luego puede definir el conteo, o para las enumeraciones “secuenciales” que comienzan con 0, use el valor del marcador directamente (por ejemplo, “blah all_blahs[blah_end_marker];” – aunque empiezo a pensar que la const int blah_count tiene más sentido…

    – Beto

    26 oct 2017 a las 14:36

  • Solo funciona si los valores asignados aumentan monótonamente en 1

    – Larry_C

    6 ene a las 18:06

  • ¿A qué valores se les asigna valor no consecutivo? No voy a volar.

    – Larry_C

    6 ene a las 18:24

1647535630 116 Numero de elementos en una enumeracion
DaveShaw

int enaumVals[] =
{
FIRST,
SECOND,
THIRD,
LAST
};

#define NUM_ENUMS sizeof(enaumVals) / sizeof ( int );

  • Esto parece requerir repetir la enumeración completa en una matriz, simplemente para permitir el uso de sizeof; me parece más esfuerzo que solo #define COUNT 4

    –Peter Gibson

    12 de diciembre de 2011 a las 0:16


  • En tamaño C, se calcula en el momento de la compilación. C no es un lenguaje interpretado, este método es tan eficiente como usar una definición fija y simplifica el mantenimiento.

    – Fulup

    03/04/2015 a las 10:55

  • Excepto que no lo es. Esto contaminará los símbolos de su programa con una serie inútil de NUM_ENUMS En t. Su programa tardará más en iniciarse, utilizará más espacio en disco, etc. La única forma de evitar esto es declarar y definir esto en una unidad de compilación independiente, pero entonces no tienes NUM_ENUMS disponible por lo que no funcionará. Más adelante, si agrega un miembro a su lista de enumeración, es posible que se olvide de hacerlo en la matriz y NUM_ENUMS no coincidirá más

    – xryl669

    14 de junio de 2019 a las 16:44

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad