[Duda] Unsigned int y enumeraciones

Iniciado por xRodak, 4 Febrero 2014, 22:27 PM

0 Miembros y 2 Visitantes están viendo este tema.

xRodak

Hola compañeros ! Me entró una duda sobre la definición de ciertas variables.

Supongamos tengo la siguiente enumeración:

namespace ENUM
{
    enum ID
    {
        a,
        b,
        c,
    };
}


Cuál sería una forma correcta de declarar un valor de dicha enumeración?

ENUM::ID       valor = ENUM::a;

o

unsigned int    valor = ENUM::a;

He visto ejemplo donde se utiliza la primera, pero según lo que he alcanzado a estudiar, la segunda sería más ideal.

Cómo sé cual de las dos debo utilizar dependiendo de cierto contexto?

Saludos y gracias de antemano.

Yoel Alejandro

Respondo: Según el libro Deitel&Deitel "Como programar en C/C++", una enumeración es un conjunto de constantes numéricas enteras, representadas por ciertos nombres o identificadores. O sea, una enumeración es como un arreglos de CONSTANTES. Dice además que el valor de cada constante de enumeración puede ser definido explícitamente durante su declaración. Ejemplo:

enum letras {A = 1, B = 3, C = 8};

Ahora, si son "constantes" su valor no se puede cambiar una vez declarado. Entonces ¿cómo lo vas a cambiar? Cualquier instrucción de asignación de un valor luego de la declaración de la enumeración sería ilegal. Yo creo que no puedes. De hecho, estuve probándolo y el compilador me da un error en cuanto intento asignar un valor a alguna de las constantes fuera de la declaración del enum.

Si quieres poder cambiar los valores a los campos debes usar otro tipo de dato, como un struct por ejemplo.
Saludos, Yoel.
P.D..-   Para mayores dudas, puedes enviarme un mensaje personal (M.P.)

eferion

Cita de: xRodak en  4 Febrero 2014, 22:27 PM
Hola compañeros ! Me entró una duda sobre la definición de ciertas variables.

Supongamos tengo la siguiente enumeración:

namespace ENUM
{
    enum ID
    {
        a,
        b,
        c,
    };
}


Cuál sería una forma correcta de declarar un valor de dicha enumeración?

ENUM::ID       valor = ENUM::a;

o

unsigned int    valor = ENUM::a;

He visto ejemplo donde se utiliza la primera, pero según lo que he alcanzado a estudiar, la segunda sería más ideal.

Cómo sé cual de las dos debo utilizar dependiendo de cierto contexto?

Saludos y gracias de antemano.

Salvo que se indique otra cosa, los enumerados son por defecto ints.

En realidad el compilador va a convertir tus enums en ints... pero con algunas restricciones relativas al uso de operadores:

Código (cpp) [Seleccionar]

// esta linea provoca un warning
ENUM::ID valor = ENUM::a | ENUM::b;

// mientras que esta otra linea no
int valor = ENUM::a | ENUM::b;


La ventaja de usar ENUM::ID en vez de int es que el que vaya a usar tus funciones / clases sabrá en todo momento cual es el rango válido de valores... ya que vienen definidos por el enumerado.

A partir de la versión 11 de C++ se puede especificar un tipo concreto para el enum:

Código (cpp) [Seleccionar]
enum ENUM : unsigned long { a, b, c, maximo = 0xFFFFFFFFU }


Cita de: yoel_alejandro en  5 Febrero 2014, 00:13 AM
Ahora, si son "constantes" su valor no se puede cambiar una vez declarado. Entonces ¿cómo lo vas a cambiar? Cualquier instrucción de asignación de un valor luego de la declaración de la enumeración sería ilegal. Yo creo que no puedes. De hecho, estuve probándolo y el compilador me da un error en cuanto intento asignar un valor a alguna de las constantes fuera de la declaración del enum.

Estás mezclando conceptos.

Que los valores del enumerado sean constantes quiere decir que no puedes redefinir sus valores, es decir, la siguiente línea da un error de compilación:

Código (cpp) [Seleccionar]
ENUM::a = 78

Sin embargo, nada te impide almacenar el valor en una variable y manipularlo a tu antojo. La relación que se va a mantener constante durante toda la ejecución del programa es que ENUM::a siempre va a tener el mismo valor.

Cita de: yoel_alejandro en  5 Febrero 2014, 00:13 AM
Si quieres poder cambiar los valores a los campos debes usar otro tipo de dato, como un struct por ejemplo.

Sigues mezclando conceptos. Las estructuras es un tipo que permite crear estructuras ( valga la redundancia ) complejas de datos, por ejemplo te permite agrupar el puntero a un vector y la variable que indica el número de elementos en dicho vector para que siempre vayan juntos:

Código (cpp) [Seleccionar]

struct Vector
{
  int* puntero;
  int size;
};


Realmente, como he comentado antes, solo necesitas almacenar el valor del enumerado en una variable de tipo numérico ( si no es del mismo tipo que el predefinido para el enum puede que tengas que hacer un casting ) y después puedes manipular la variable a tu antojo... eso si, no hay impedimentos para que esa variable forme parte de una estructura, una clase o una unión.

xRodak

Gracias por tu respuesta eferion ! Yo pensaba que la enumeración era algo más que un simple int (suponiendo que se utilizan como ints). Por eso pensaba que existía alguna diferencia considerable entre utilizar ambas definiciones. Ahora veo que definir una variable como entero es más adecuado.

Muchas gracias !

Y yoel, de verdad confundiste mi pregunta xD.

Saludos !

Yoel Alejandro

#4
Insisto, los enum son agrupaciones de constantes, lo cual significa que una vez declares su valor, NO lo puedes cambiar. Por ejemplo, sea:


enum {A=3, B, C};


Ya está definido el valor constante de A = 3. Si luego intentas poner por ejemplo:


A = 5

el compilador arroja un error, en mi caso el compilador gcc de GNU que es acorde a la especificación oficial ISO/IEC 9899:1999, conocida como C99:

test1.c: In function 'main':
test1.c:18: error: lvalue required as left operand of assignment

es decir, que A no es un "lvalue", su valor no se puede cambiar. Así que no la "puedes manipular a tu antojo". Lo que sí puedes es asignar su valor a una variable, algo como

int x;
x = A;


Recuerden que cuando declaras un identificador constante muchos compiladores (si respetan el estándar) intentarán ubicarlo en una zona de memoria donde su valor no pueda ser modificado.

Ahora, otra cosa es que estés usando algún compilador "flexible" que soporte funcionalidades no estándares, lo cual alienta a prácticas inadecuadas de programación que no serán compatibles con otras plataformas. ¿Sería este el caso?
Saludos, Yoel.
P.D..-   Para mayores dudas, puedes enviarme un mensaje personal (M.P.)

rir3760

Cita de: yoel_alejandro en  6 Febrero 2014, 00:14 AMel compilador arroja un error, en mi caso el compilador gcc de GNU que es acorde a la especificación oficial ISO/IEC 9899:1999, conocida como C99
Lo primero a considerar es el lenguaje de programación utilizado: este es C++ y por ende hay que compilar en modo C++98 o C++11.

Cita de: yoel_alejandro en  6 Febrero 2014, 00:14 AMInsisto, los enum son agrupaciones de constantes, lo cual significa que una vez declares su valor, NO lo puedes cambiar.
Me parece que aquí hay una confusión ya que eferion se refiere a modificar una variable de tipo "enum T" y, por supuesto, es correcto.

Por cierto una pagina donde se listan algunas diferencias entre las enumeraciones en C++98 y C++11 es Better types in C++11 - nullptr, enum classes (strongly typed enumerations) and cstdint.

Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language