C/C++ Crear una enumeración con valores negativos, sin tener que numerarlo

4 minutos de lectura

Por ejemplo, en C/C++, tendría el código:

typedef enum fruits{
   apple,
   banana,
   lemon,
   orange
} fruit_t;

Lo cual sería equivalente a:

typedef enum fruits{
   apple = 0,
   banana = 1,
   lemon = 2,
   orange = 3
} fruit_t;

Sin embargo, me gustaría que los valores fueran negativos, para que no entren en conflicto con nada más. Podría hacerlo así:

typedef enum fruits{
   apple = -1,
   banana = -2,
   lemon = -3,
   orange = -4
} fruit_t;

Pero si quiero agregar otra fruta, tengo que asignar otro valor, y si pongo una en el medio, tengo que volver a numerar la mayor parte. ¿Hay una manera más fácil de hacer esto?

  • Debe usar enumeraciones de ámbito C++ 11. No existe tal cosa como C/C++.

    – Carreras de ligereza en órbita

    9 de enero de 2014 a las 17:57


  • @LightnessRacesinOrbit: a menos que la intención sea escribir una definición que se pueda usar en cualquiera de los dos idiomas; en cuyo caso es bastante razonable llamarlo “C/C++”.

    –Mike Seymour

    9 de enero de 2014 a las 18:06

avatar de usuario
alca

Empezar con INT_MIN encima así:

#include <limits.h>

enum fruits
{
  orange = INT_MIN,
  lemon, 
  ...
}

por “5.2.4.2.1 Tamaños de tipos enteros ” y/o “Anexo E/1de la Norma C11 INT_MIN Por lo menos -32767.

INT_MIN se define al incluir <limits.h>.

avatar de usuario
Shafik Yaghmour

En C solo necesita numerar el primero y las entradas posteriores serán la entrada anterior +1esto está cubierto en el Proyecto de norma C99 sección 6.7.2.2 Especificadores de enumeración que dice (énfasis mío):

[…]Un enumerador con = define su constante de enumeración como el valor de la expresión constante. Si el primer enumerador no tiene =, el valor de su constante de enumeración es 0. Cada enumerador posterior sin = define su constante de enumeración como el valor de la expresión constante obtenida al sumar 1 al valor de la constante de enumeración anterior.[…]

y la redacción es similar en el Borrador del estándar C++ sección 7.2 Declaraciones de enumeración párrafo 2.

Así que haz algo similar a lo siguiente:

#define MIN -4

typedef enum fruits{
   orange = MIN,
   lemon,  
   banana,
   apple,
} fruit_t;

avatar de usuario
Moha el camello todopoderoso

En primer lugar, no existe tal cosa como “C/C++”, son dos lenguajes diferentes. No puede ver a C como un subconjunto de C++; algún código C legal no se compilará como un programa C++.

Si puede usar C++ 11, le sugiero que use enum classque te da enumeraciones fuertemente tipadas:

enum class Traffic {red , yellow, green};
Traffic t = Traffic::red;

if ( t == Traffic::red )  // to test the value of an enum 

De esta manera, puede garantizar que no haya conflictos, porque el compilador no le permitirá hacer ninguna comparación con un número entero o con una variable de un tipo de enumeración diferente.

Solo puede comparar con una variable del mismo tipo de enumeración o usar el operador de resolución de alcance binario como en el ejemplo.

Otra ventaja de esto enum class es que puede establecer el tamaño de su enumeración. Puede usar cualquier tipo de entero con o sin signo como este:

enum class Traffic : char { red, yellow, green }

Cuando no se especifica un tipo, el valor predeterminado int se supone.

Tenga en cuenta que necesita un compilador compatible con C++ 11 para esto.

avatar de usuario
Realidad_digital

Creo que puedes pedirlo como quieras.

Si no está dando ningún valor entonces siguiente enum tomará +1 de su valor anterior. si aun puño enum no tiene ningún valor, entonces comenzará desde 0.

Pero una buena práctica es tenerlo en el orden correcto.

avatar de usuario
florin hillebrand

También es bastante común declarar los errores como enumeraciones habituales y usar su valor negativo, como:

typedef enum fruits_e {
    APPLE=1,
    BANANA,
    LEMON,
    ORANGE
} fruit_t;

fruit_t eat_fastfood(void) {
    if (! me->healthy())
        return -APPLE;
}

  • Si una función devuelve una enumeración, espero que devuelva valores que realmente están definidos en la enumeración, por lo que puedo hacer switch(eat_fastFood()) { case APPLE: case BANANA: case LEMON: case ORANGE: break; } – Nunca esperaría tener que negar mis casos (con suerte, esto al menos está documentado en alguna parte, de lo contrario, lo descubriría solo depurando o registrando/imprimiendo los valores después de que mi programa no funcionó como se esperaba).

    – Aconcagua

    11 mayo 2016 a las 13:41

  • Si una función devuelve una enumeración, espero que devuelva valores que realmente están definidos en la enumeración, por lo que puedo hacer switch(eat_fastFood()) { case APPLE: case BANANA: case LEMON: case ORANGE: break; } – Nunca esperaría tener que negar mis casos (con suerte, esto al menos está documentado en alguna parte, de lo contrario, lo descubriría solo depurando o registrando/imprimiendo los valores después de que mi programa no funcionó como se esperaba).

    – Aconcagua

    11 mayo 2016 a las 13:41

¿Ha sido útil esta solución?