2011-11-13 12 views
48

Esta es una pregunta de prueba de entrevista C++ no deberes.¿cuál es el tamaño de un tipo de datos enum en C++?

#include <iostream> 
using namespace std; 
enum months_t { january, february, march, april, may, june, july, august, september,  
    october, november, december} y2k; 

int main() 
    { 
    cout << "sizeof months_t is " << sizeof(months_t) << endl; 
    cout << "sizeof y2k is " << sizeof(y2k) << endl; 
    enum months_t1 { january, february, march, april, may, june, july, august,  
     september, october, november, december} y2k1; 
    cout << "sizeof months_t1 is " << sizeof(months_t1) << endl; 
    cout << "sizeof y2k1 is " << sizeof(y2k1) << endl; 
} 

Salida:

months_t sizeof es 4
sizeof Y2K es 4
sizeof months_t1 es 4
sizeof y2k1 es 4

¿Por qué es el tamaño de todos estos 4 bytes? ¿No es 12 x 4 = 48 bytes?
Sé que los elementos de unión ocupan la misma ubicación de memoria, pero esta es una enumeración.

+3

¿Cómo nadie mencionó las clases enum? Espero que los entusiastas de C++ vayan más allá del deber en una pregunta como esta. –

+3

Desconfundir el OP es la primera orden del día. Sin embargo, no hay nada que te impida pesar en las clases enum. – ObscureRobot

+1

@MattJoiner ¿Quiere decir que en C++ 11 puede especificar el _ tipo subyacente_ de una enumeración, que es el tipo integral que imita? Por ejemplo 'enum month: char {january, ...};'. Las enumeraciones de clase, también conocidas como enums delimitados, son otra variedad de clases que crean un espacio de nombres adjunto para sus constantes. El problema es que las enumeraciones de clase son siempre de un tipo subyacente fijo ('int' si no se especifica). – rodrigo

Respuesta

39

El tamaño es de cuatro bytes porque el enum se almacena como int. Con solo 12 valores, solo necesita 4 bits, pero las máquinas de 32 bits procesan cantidades de 32 bits de forma más eficiente que las cantidades más pequeñas.

0 0 0 0 January 
0 0 0 1 February 
0 0 1 0 March 
0 0 1 1 April 
0 1 0 0 May 
0 1 0 1 June 
0 1 1 0 July 
0 1 1 1 August 
1 0 0 0 September 
1 0 0 1 October 
1 0 1 0 November 
1 0 1 1 December 
1 1 0 0 ** unused ** 
1 1 0 1 ** unused ** 
1 1 1 0 ** unused ** 
1 1 1 1 ** unused ** 

Sin enumeraciones, usted podría estar tentado a usar números enteros primas para representar los meses. Eso funcionaría y sería eficiente, pero haría que tu código fuera difícil de leer. Con enumeraciones, obtienes un almacenamiento y una legibilidad eficientes.

+0

Creo que el estándar quiere que enum sea el mismo que el entero. C++ 11 introdujo clases enum. –

+0

Ese podría ser el caso. ¿Tienes una cita? – ObscureRobot

+0

también: incluso si C permitió una enumeración de ser un byte, un compilador de 32 bits lo más probable es alinear su enumeración de los límites de 32 bits, 32 bits de hasta comer de todos modos :) – ObscureRobot

4

Dado que tiene el tamaño de una instancia del tipo, presumiblemente los valores enum se almacenan como entradas de (32 bits/4 bytes) aquí.

2

Una enumeración es casi un número entero. Para simplificar mucho

enum yourenum { a, b, c }; 

es casi como

#define a 0 
#define b 1 
#define c 2 

Por supuesto, no es realmente cierto. Estoy tratando de explicar que enum hay algún tipo de codificación ...

5

Una enum es como un typedef para el tipo int (tipo de).

Así que el tipo que ha definido allí tiene 12 valores posibles, sin embargo, una sola variable solo tiene uno de esos valores.

Piénselo de esta manera, cuando define una enumeración, básicamente está definiendo otra forma de asignar un valor int.

En el ejemplo que nos ha facilitado, enero es otra forma de decir 0, febrero es otra forma de decir 1, etc hasta diciembre es otra forma de decir 11.

9

Depende. El estándar solo exige que sea lo suficientemente grande como para contener todos los valores, por lo que formalmente una enumeración como enum foo { zero, one, two }; solo necesita tener un byte de gran tamaño. Sin embargo, la mayoría de las implementaciones hacen que las enumeraciones sean tan grandes como ints (eso es más rápido en hardware moderno; además, es necesario para la compatibilidad con C, donde las enumeraciones son, básicamente, glorificados). Sin embargo, tenga en cuenta que C++ permite enumeraciones con inicializadores fuera del rango int, y para esas enumeraciones, el tamaño, por supuesto, también será mayor. Por ejemplo, si tiene enum bar { a, b = 1LL << 35 };, entonces su enum será mayor que 32 bits (lo más probable es 64 bits) incluso en un sistema con 32 bits de entrada (tenga en cuenta que en C esa enum no estaría permitida).

79

Esta es una pregunta de prueba de entrevista C++ no deberes.

Luego, su entrevistador debe actualizar su recuerdo con el funcionamiento del estándar C++. Y cito:

Para una enumeración cuyo tipo subyacente no es fijo, el tipo subyacente es un tipo entero que puede representar todos los valores de enumerador definidos en la enumeración.

Toda la parte "cuyo tipo subyacente no es fijo" es de C++ 11, pero el resto es todo C++ 98/03 estándar. En resumen, sizeof(months_t) es no 4. Tampoco es 2. Es podría ser cualquiera de esos. La norma no dice qué tamaño debería ser; solo que debe ser lo suficientemente grande como para caber en cualquier enumerador.

¿por qué el tamaño es de 4 bytes? no 12 x 4 = 48 bytes?

Debido a las enumeraciones no son variables. Los miembros de una enumeración no son variables reales; solo son una forma de #define segura para el medio tipo. Son una manera de almacenar un número en un formato fácil de leer. El compilador transformará todos los usos de un enumerador en el valor numérico real.

enumeradores son sólo otra forma de hablar de un número. january es solo una abreviatura de 0. ¿Y cuánto espacio ocupa 0? Depende de lo que lo guarde en.

+7

Esta es una respuesta excelente que no debe pasarse por alto. Aunque mi respuesta proporciona los conceptos básicos para comprender una enumeración, realmente necesita poder comprender una enumeración en este nivel si espera pasar este tipo de pregunta de entrevista. – ObscureRobot

3

Con mis ahora envejecimiento enumeraciones compilador Borland C++ Builder puede ser 1,2 o 4 bytes, aunque tiene una bandera que puede dar la vuelta para forzarlo a utilizar enteros.

Supongo que es un compilador específico.

+1

Con gcc, el comportamiento es venerado: las enum predeterminadas a 'int', pero la bandera' -fshort-enums' acorta el espacio utilizado por la enumeración a lo que apenas es necesario. (Aunque esto es probablemente menos óptimo). –

3

me gusta la explicación por parte de EDX (Microsoft: DEV210x Introducción a C++) para un problema similar:.

"La enumeración representa los valores literales de día como enteros Refiriéndose a la mesa de tipos de datos numéricos, se ve que una int toma 4 bytes de memoria. 7 días x 4 bytes cada uno requeriría 28 bytes de memoria si se almacenara toda la enumeración, pero el compilador solo usa un elemento de la enumeración, por lo tanto, el tamaño en la memoria es en realidad de 4 bytes ".

Cuestiones relacionadas