web-dev-qa-db-ja.com

C ++の列挙型データのサイズは何ですか?

これは、宿題ではなく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;
 }

出力:

sizeof months_tは4です
sizeof y2kは4
sizeof months_t1は4です
sizeof y2k1は4

これらの4バイトすべてのサイズがなぜですか? 12 x 4 = 48バイトではない?
ユニオン要素が同じメモリ位置を占めることは知っていますが、これは列挙型です。

59
user1002288

enumintとして保存されるため、サイズは4バイトです。値が12のみの場合、実際に必要なのは4ビットだけですが、32ビットのマシンは、32ビットの量をより少ない量よりも効率的に処理します。

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

列挙型がないと、生の整数を使用して月を表現したくなるかもしれません。これは機能し、効率的ですが、コードが読みにくくなります。列挙型を使用すると、効率的なストレージと可読性が得られます。

49
ObscureRobot

これは、宿題ではなくC++のインタビューテストの質問です。

次に、インタビュアーは、C++標準がどのように機能するかについて思い出をリフレッシュする必要があります。 そして引用

基になる型が固定されていない列挙型の場合、基になる型は、列挙で定義されているすべての列挙子の値を表すことができる整数型です。

「基礎となる型が固定されていない」部分はすべてC++ 11のものですが、残りはすべて標準C++ 98/03です。つまり、sizeof(months_t)not4.です。2でもありません。それはcouldのいずれかです。標準では、サイズを指定していません。任意の列挙子に適合するのに十分な大きさでなければなりません。

すべてのサイズが4バイトなのはなぜですか? 12 x 4 = 48バイトではない?

列挙型は変数ではないためです。列挙型のメンバーは実際の変数ではありません。これらは#defineのセミタイプセーフ形式にすぎません。これらは、読みやすい形式で数値を保存する方法です。コンパイラは、列挙子のすべての使用を実際の数値に変換します。

列挙子は、数値について説明するための単なる別の方法です。 january0の省略形です。 0はどのくらいのスペースを占有しますか?保存する場所によって異なります。

101
Nicol Bolas

場合によります。標準では、すべての値を保持するのに十分な大きさであることが要求されるだけなので、正式にはenum foo { zero, one, two };は、1バイトの大きさである必要があります。ただし、ほとんどの実装では、これらの列挙型をintと同じ大きさにします(最新のハードウェアではより高速です。さらに、列挙型が基本的に栄光化されたCとの互換性のために必要です)。ただし、C++ではint範囲外の初期化子を持つ列挙型が許可され、それらの列挙型のサイズももちろん大きくなります。たとえば、enum bar { a, b = 1LL << 35 };その後、32ビット整数を持つシステム上でも、列挙型は32ビット(ほとんどの場合64ビット)より大きくなります(Cではその列挙型は許可されないことに注意してください)。

9
celtschk

列挙型は、int型(の種類)のtypedefのようなものです。

したがって、そこで定義した型には12の可能な値がありますが、1つの変数にはこれらの値の1つしかありません。

このように考えると、enumを定義するとき、基本的にint値を割り当てる別の方法を定義していることになります。

あなたが提供した例では、1月は0を表す別の方法、2月は1を表す別の方法、12月が11を表す別の方法までです。

6
agenttom

古くなったBorland C++ Builderコンパイラーの列挙型は、1、2、または4バイトになりますが、反転させることで強制的にintを使用することができます。

コンパイラ固有のものだと思います。

4
thedaver64

タイプのインスタンスのサイズであるため、おそらく列挙値は(32ビット/ 4バイト)intとしてここに格納されます。

4
Stuart Golodetz

同様の問題に対するEdXからの説明(Microsoft:DEV210x Introduction to C++)が好きです:

「enumは整数の日のリテラル値を表します。数値型の表を参照すると、intには4バイトのメモリが必要であることがわかります。コンパイラは列挙型の単一の要素のみを使用するため、メモリ内のサイズは実際には4バイトです。」

3
Anton Rasmussen

列挙型はほぼ整数です。簡単にするために

enum yourenum { a, b, c };

ほとんど似ている

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

もちろん、それは本当ではありません。私はenumが何らかのコーディングであると説明しようとしています...