Quelle est la taille d’une donnée de type enum en C ++?

Ceci est une question de test C ++ entretien pas à la maison.

#include  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; } 

Sortie:

sizeof months_t is 4
taille de y2k est 4
sizeof months_t1 est 4
sizeof y2k1 est 4

Pourquoi la taille de tous ces 4 octets? Pas 12 x 4 = 48 octets?
Je sais que les éléments syndicaux occupent le même emplacement mémoire, mais il s’agit d’une énumération.

La taille est de quatre octets car l’ enum est stockée sous la forme d’un int . Avec seulement 12 valeurs, vous n’avez besoin que de 4 bits, mais les machines 32 bits traitent les quantités 32 bits plus efficacement que les petites quantités.

 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 ** 

Sans énumérations, vous pourriez être tenté d’utiliser des entiers bruts pour représenter les mois. Cela fonctionnerait et serait efficace, mais cela rendrait votre code difficile à lire. Avec les énumérations, vous obtenez un stockage et une lisibilité efficaces.

Ceci est une question de test C ++ entretien pas à la maison.

Ensuite, votre interlocuteur doit actualiser ses souvenirs sur le fonctionnement du standard C ++. Et je cite:

Pour une énumération dont le type sous-jacent n’est pas fixe, le type sous-jacent est un type intégral pouvant représenter toutes les valeurs d’énumérateur définies dans l’énumération.

L’ensemble “dont le type sous-jacent n’est pas fixe” provient de C ++ 11, mais le rest est tout C ++ 98/03 standard. En bref, le sizeof(months_t) n’est pas 4. Il n’est pas 2 non plus. Cela pourrait être n’importe lequel. La norme ne dit pas quelle taille elle devrait être; seulement que ça devrait être assez grand pour convenir à n’importe quel enquêteur.

pourquoi la taille totale est de 4 octets? pas 12 x 4 = 48 octets?

Parce que les énumérations ne sont pas des variables. Les membres d’un enum ne sont pas des variables réelles; ils sont juste une forme semi-typée de #define. Ils permettent de stocker un numéro dans un format convivial. Le compilateur transformera toutes les utilisations d’un énumérateur en valeur numérique réelle.

Les énumérateurs ne sont qu’une autre façon de parler d’un numéro. january n’est qu’un raccourci pour 0 . Et combien d’espace prend 0? Cela dépend de ce que vous stockez.

Ça dépend. Le standard exige seulement qu’il soit assez grand pour contenir toutes les valeurs, donc formellement un enum comme enum foo { zero, one, two }; doit être seulement un octet de large. Cependant, la plupart des implémentations rendent ces énumérations aussi grandes que ints (c’est plus rapide sur le matériel moderne; de ​​plus, elles sont nécessaires pour la compatibilité avec C où les énumérations sont fondamentalement des ints glorifiés). Notez cependant que C ++ autorise les énumérations avec des initialiseurs en dehors de la plage int, et pour ces énumérations, la taille sera bien sûr également plus grande. Par exemple, si vous avez une enum bar { a, b = 1LL << 35 }; alors votre enum sera plus grand que 32 bits (probablement 64 bits) même sur un système avec 32 bits ints (notez que dans C cet enum ne serait pas autorisé).

Un enum est un peu comme un typedef pour le type int (sorte de).

Ainsi, le type que vous avez défini comporte 12 valeurs possibles, mais une seule variable ne possède qu’une de ces valeurs.

Pensez-y de cette façon, lorsque vous définissez une énumération, vous définissez essentiellement une autre façon d’atsortingbuer une valeur int.

Dans l’exemple que vous avez fourni, janvier est une autre façon de dire 0, feb est une autre façon de dire 1, etc. jusqu’à décembre est une autre façon de dire 11.

Comme il s’agit de la taille d’une instance du type, les valeurs d’énumération sont probablement stockées sous la forme de valeurs ints (32 bits / 4 octets) ici.

Avec mon ancien compilateur de compilateur Borland C ++ Builder peut avoir 1,2 ou 4 octets, bien qu’il ait un drapeau, vous pouvez le retourner pour le forcer à utiliser ints.

Je suppose que c’est spécifique au compilateur.

J’aime l’explication De EdX (Microsoft: Introduction à DEV ++ C ++) pour un problème similaire:

“L’énumération représente les valeurs littérales des jours en tant que nombres entiers. En vous référant à la table des types numériques, vous voyez qu’un int prend 4 octets de mémoire. 7 jours x 4 octets chacun nécessiteraient 28 octets le compilateur n’utilise qu’un seul élément de l’énumération, donc la taille en mémoire est en réalité de 4 octets. ”

Un enum est presque un entier. Pour simplifier beaucoup

 enum yourenum { a, b, c }; 

est presque comme

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

Bien sûr, ce n’est pas vraiment vrai. J’essaie d’expliquer que les enum sont une sorte de codage …