2011-11-13 48 views
48

这是一个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 2000年是4
的sizeof months_t1是4
的sizeof y2k1是4

为什么所有的大小这4个字节?不是12 x 4 = 48字节?
我知道联合元素占据相同的内存位置,但这是一个枚举。

+3

没有人提到枚举类吗?我希望C++ enthuasiasts在这样的问题上超越责任的要求。 –

+3

对OP的解密是当天的第一步。尽管如此,没有什么能够阻止你对枚举类进行权衡。 – ObscureRobot

+1

@MattJoiner你的意思是说,在C++ 11中,你可以指定一个枚举的_underlying type_,它是它模仿的整型类型?例如'enum month:char {january,...};'。类枚举,又名范围枚举,是另一种为其常量创建封闭名称空间的类。事情是,类枚举总是一个固定的基础类型(如果没有指定'int')。 – rodrigo

回答

39

大小为四个字节,因为enum存储为int。只有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 ** 

没有枚举,你可能会试图用原始整数来表示月份。这会工作并且高效,但会让你的代码难以阅读。通过枚举,您可以获得高效的存储和可读性。

+0

我认为这个标准希望enum和整数一样。 C++ 11引入了枚举类。 –

+0

可能是这种情况。有一个引用? – ObscureRobot

+0

另外:即使C允许一个枚举为一个字节,32位编译器很可能会将您的枚举与32位边界对齐,无论如何都会消耗32位:) – ObscureRobot

4

因为它是一个类型实例的大小 - 可能枚举值在这里存储为(32位/ 4字节)整数。

2

enum几乎是一个整数。为了简化很多

enum yourenum { a, b, c }; 

几乎是像

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

当然,这不是真的。我试图解释枚举是某种编码...

5

枚举有点像int类型的typedef。

所以你在那里定义的类型有12个可能的值,但是一个变量只有一个值。

想想这样,当你定义一个枚举时,你基本上定义了另一种分配int值的方法。

在您所提供的例子,一月份是说0的另一种方式,就是月1说,等至十二月的另一种方法是说11

9

它依赖的另一种方式。该标准只要求它足够大以保存所有值,因此形式上像enum foo { zero, one, two };这样的枚举只需要一个字节大。然而,大多数实现使得这些枚举与int一样大(这在现代硬件上是更快的;而且它需要与C兼容,而enums基本上是荣耀整数)。不过请注意,C++允许枚举的初始值在int范围之外,对于这些枚举,大小当然也会更大。例如,如果你有enum bar { a, b = 1LL << 35 };,那么即使在32位整数的系统上,你的枚举也会大于32位(最可能是64位)(注意在C中不允许枚举)。

79

这是一个C++面试测试题而不是作业。

然后你的面试官需要刷新他的回忆C++标准的工作原理。我引用:

对于基础类型不固定的枚举,基础类型是一个整型,它可以表示枚举中定义的所有枚举值。

整个“其底层类型不固定”部分来自C++ 11,但其余全部是标准C++ 98/03。总之,sizeof(months_t)而不是 4.它也不是2。它可能是是其中的任何一个。该标准没有说明它应该是多少;只是它应该足够大以适应任何统计员。

为什么所有大小都是4字节?不是12 x 4 = 48字节?

因为枚举不是变量。枚举的成员不是实际变量;它们只是#define的半安全形式。它们是以易于阅读的格式存储数字的一种方式。编译器会将枚举器的所有用途转换为实际的数值。

统计员只是谈论一个数字的另一种方式。 january只是0的简写。 0占用多少空间?这取决于你存储它的内容。

+7

这是一个不容忽视的优秀答案。虽然我的答案提供了理解枚举的基础知识,但如果您希望通过这种面试问题,您确实需要能够掌握此级别的枚举。 – ObscureRobot

3

随着我现在老化的Borland C++ Builder编译器枚举可以是1,2或4个字节,虽然它有一个标志可以翻转来强制它使用整数。

我想这是编译器的具体情况。

+1

使用gcc时,行为受到尊重 - 枚举默认为'int',但标记'-fshort-enums'将枚举所使用的空间缩短为几乎不需要的空间。 (虽然这可能不太理想。) –

3

我喜欢这个解释从EDX:对于类似的问题。(微软DEV210x介绍C++):

“枚举表示天面值为整数参考数值类型的表,你看到的int需要4个字节的内存,如果整个枚举被存储但是编译器只使用枚举的一个元素,那么7天x 4个字节将需要28个字节的内存,因此内存中的大小实际上是4个字节。