2011-11-13 7 views
48

Questa è una domanda del test dell'intervista in C++ non i compiti.qual è la dimensione di un dato di tipo enum in 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; 
} 

uscita:

sizeof months_t è 4
sizeof Y2K è 4
sizeof months_t1 è 4
sizeof y2k1 è 4

Perché le dimensioni di tutti questi 4 byte? Non 12 x 4 = 48 byte?
So che gli elementi di unione occupano la stessa posizione di memoria, ma questo è un enume.

+3

Come nessuno ha menzionato le lezioni di enum? Mi aspetterei che le entasasias C++ vadano oltre il call of duty su una domanda come questa. –

+3

Deconfigurare l'OP è il primo ordine del giorno. Niente ti impedisce di valutare le lezioni di enum. – ObscureRobot

+1

@MattJoiner Vuoi dire che in C++ 11 puoi specificare il _ tipo di carattere _ di un enum, che è il tipo integrale che imita? Per esempio 'enum month: char {january, ...};'. Le enumerazioni di classe, note anche come enumerate, sono un'altra varietà di classi che creano uno spazio dei nomi che racchiude le sue costanti. Il fatto è che le enumerazioni di classe sono sempre di tipo fisso ('int' se non specificato). – rodrigo

risposta

39

La dimensione è di quattro byte poiché lo enum è memorizzato come int. Con solo 12 valori, sono necessari solo 4 bit, ma le macchine a 32 bit elaborano le quantità a 32 bit in modo più efficiente rispetto alle quantità più piccole.

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

Senza enumerri, si potrebbe essere tentati di utilizzare numeri interi grezzi per rappresentare i mesi. Ciò funzionerebbe e sarebbe efficiente, ma renderebbe difficile la lettura del codice. Con l'enumerazione ottieni una memoria e una leggibilità efficienti.

+0

Penso che lo standard voglia che l'enum sia uguale al numero intero. Il C++ 11 ha introdotto le classi enum. –

+0

Potrebbe essere il caso. Hai una citazione? – ObscureRobot

+0

Inoltre: anche se C consentisse che un enum fosse un byte, un compilatore a 32 bit probabilmente allineerebbe il tuo enum ai limiti a 32-bit, mangiando comunque 32 bit :) – ObscureRobot

4

Poiché è la dimensione di un'istanza del tipo - presumibilmente i valori di enum sono memorizzati come valori (a 32 bit/4 byte) qui.

2

Un enum è quasi un numero intero. Per semplificare un sacco

enum yourenum { a, b, c }; 

è quasi come

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

Naturalmente, non è proprio vero. Sto cercando di spiegare che enum sono una specie di codice ...

5

Un enum è un po 'come un typedef per il tipo int (tipo di).

Quindi il tipo definito ha 12 valori possibili, tuttavia una singola variabile ha sempre uno solo di questi valori.

Pensaci in questo modo, quando definisci un enum stai sostanzialmente definendo un altro modo per assegnare un valore int.

Nell'esempio che ci hai fornito, gennaio è un altro modo di dire 0, febbraio è un altro modo di dire 1, ecc fino a dicembre è un altro modo di dire 11.

9

Dipende. Lo standard richiede solo che sia abbastanza grande da contenere tutti i valori, quindi formalmente un enum come enum foo { zero, one, two }; deve essere grande solo un byte. Tuttavia la maggior parte delle implementazioni rende quelle enumerhe grandi quanto quelle di Ints (che è più veloce con l'hardware moderno, inoltre è necessario per la compatibilità con C, in cui enumerazioni sono fondamentalmente glorificate). Si noti tuttavia che C++ consente l'enumerazione con gli inizializzatori al di fuori dell'intervallo int e, per quelle enumerazioni, anche le dimensioni saranno ovviamente maggiori. Ad esempio, se hai enum bar { a, b = 1LL << 35 }; allora il tuo enum sarà più grande di 32 bit (molto probabilmente 64 bit) anche su un sistema con 32 bit inte (nota che in C quell'enumerazione non sarebbe consentita).

79

Questa è una domanda di test dell'intervista in C++ non i compiti.

Quindi l'intervistatore deve aggiornare il suo ricordo su come funziona lo standard C++. E cito:

Per un'enumerazione il cui tipo sottostante non è fisso, il tipo sottostante è un tipo integrale che può rappresentare tutti i valori dell'enumeratore definiti nell'enumerazione.

L'intera parte "il cui tipo sottostante non è fisso" proviene da C++ 11, mentre il resto è tutto standard C++ 98/03. In breve, lo sizeof(months_t) è non 4. Non è neanche 2. È potrebbe essere uno di quelli. Lo standard non dice quale dimensione dovrebbe essere; solo che dovrebbe essere abbastanza grande da adattarsi a qualsiasi enumeratore.

perché tutte le dimensioni sono 4 byte? non 12 x 4 = 48 byte?

Perché le enumerazioni non sono variabili. I membri di un enum non sono variabili reali; sono solo una forma semi-sicura di #define. Sono un modo per memorizzare un numero in un formato adatto ai lettori. Il compilatore trasformerà tutti gli usi di un enumeratore nel valore numerico effettivo.

Gli enumeratori sono solo un altro modo di parlare di un numero. january è solo una scorciatoia per 0. E quanto spazio occupa 0? Dipende da cosa lo memorizzi.

+7

Questa è una risposta eccellente che non deve essere trascurata. Sebbene la mia risposta fornisca le basi per la comprensione di un enume, è davvero necessario essere in grado di cogliere un enume a questo livello se si prevede di passare questo tipo di domanda di intervista. – ObscureRobot

3

Con il mio enfasi di compilazione di Borland C++ Builder ora può essere 1,2 o 4 byte, sebbene abbia un flag che puoi capovolgere per forzare l'uso di ints.

Suppongo che sia specifico del compilatore.

+1

Con gcc, il comportamento è riverito: l'enumerazione predefinita è 'int', ma il flag' -fshort-enums' accorcia lo spazio utilizzato dall'enumerazione per ciò che è appena necessario. (Anche se questo è probabilmente meno ottimale.) –

3

mi piace la spiegazione Da EDX (Microsoft: DEV210x Introduzione al C++) per un problema simile:.

"L'enum rappresenta i valori letterali di giorni come numeri interi Facendo riferimento alla tabella tipi numerici, si vede che un int richiede 4 byte di memoria, 7 giorni x 4 byte ciascuno richiede 28 byte di memoria se l'intero enum è memorizzato ma il compilatore utilizza solo un singolo elemento dell'enum, quindi la dimensione in memoria è in realtà 4 byte. "

Problemi correlati