web-dev-qa-db-fra.com

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

Ceci est une question de test d'interview C++ et non un devoir.

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

Sortie:

sizeof months_t est 4
La taille de l'an 2000 est 4
sizeof months_t1 est 4
La taille de y2k1 est 4

Pourquoi la taille de l'ensemble de ces 4 octets? Pas 12 x 4 = 48 octets?
Je sais que les éléments d’union occupent le même emplacement mémoire, mais c’est une énumération.

59
user1002288

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

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 enums, 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 enums, vous obtenez un stockage efficace et une lisibilité.

49
ObscureRobot

Ceci est une question de test d'interview C++ et non un devoir.

Ensuite, votre intervieweur doit actualiser ses souvenirs avec le fonctionnement de la norme 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.

La totalité de la partie "dont le type sous-jacent n'est pas fixe" provient de C++ 11, mais le reste appartient à la norme C++ 98/03. En bref, la sizeof(months_t) est pas 4. Ce n’est pas 2 non plus. Il pourrait être l'un de ceux-là. La norme ne dit pas quelle taille elle devrait être; seulement qu'il devrait être assez grand pour s'adapter à 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'une énumération ne sont pas des variables réelles; ils sont juste une forme de #define semi-sûre. Ils permettent de stocker un numéro dans un format facile à lire. Le compilateur transformera toutes les utilisations d'un énumérateur en valeur numérique réelle.

Les recenseurs sont simplement une autre façon de parler d’un nombre. january est juste un raccourci pour 0. Et combien d'espace occupe 0? Cela dépend de ce que vous stockez dans.

101
Nicol Bolas

Ça dépend. La norme exige seulement qu’elle soit assez grande pour contenir toutes les valeurs, donc formellement une énumération comme enum foo { zero, one, two }; n'a besoin que d'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, elle est nécessaire pour la compatibilité avec C, où les énums sont fondamentalement glorifiés). Notez cependant que C++ autorise les énumérations avec des initialiseurs en dehors de la plage int et que, pour ces énumérations, la taille sera bien sûr également plus grande. Par exemple, si vous avez 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 (notez qu'en C, cet enum ne serait pas permis).

9
celtschk

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

Donc, le type que vous avez défini a 12 valeurs possibles, mais une seule variable ne possède jamais l'une de ces valeurs.

Pensez-y de cette façon, lorsque vous définissez une énumération, vous définissez en gros un autre moyen d'attribuer une valeur int.

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

6
agenttom

Avec mon désormais vieillissant compilateur de compilateur Borland C++ Builder, les enums peuvent être de 1,2 ou 4 octets, bien qu'il ait un drapeau que vous pouvez inverser pour le forcer à utiliser ints.

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

4
thedaver64

Parce que c'est la taille d'une instance de type, on suppose que les valeurs enum sont stockées ici (32 bits/4 octets).

4
Stuart Golodetz

J'aime l'explication fournie par EdX (Microsoft: DEV210x Introduction to C++) pour un problème similaire:

"L’énumération représente les valeurs littérales de jours sous forme d’entiers. En vous référant au tableau des types numériques, vous voyez qu’un int prend 4 octets de mémoire. 7 jours sur 4 octets nécessiteraient chacun 28 octets de mémoire si l’énumération entière était stockée Le compilateur utilise un seul élément de l'énum, ​​par conséquent, la taille en mémoire est de 4 octets. "

3
Anton Rasmussen

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 code ...

1