C/C++的enum类型大小

本文主要探讨了C和C++11下enum类型的相关内容。C语言中enum大小由编译器根据定义值选择合适整数类型,可能导致结构体大小变化;C++11下enum可显式指定大小,超范围会编译报错。此外,二者在enum关键字使用和变量取值范围上也存在区别,C++11对enum的控制更好。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们在编程时有时想让一个变量的值只在规定范围里取值,那么就会考虑使用enum类型。
例如我们想定义一个变量来表示红绿蓝三原颜色,那么就使用enum来定义取值范围,

enum color {RED, GREEN, BLUE};

然后我们在用enum color来定义变量,并赋值,

enum color myColor = GREEN;

本文不是讨论enum的使用细节,而是看一下enum类型的变量大小。


一 C下的enum

C语言下面,enum大小是一个整型大小,但是C下整型有很多种,char、long int和short int等,具体哪一种呢?下面引用《C in a nutshell》里的一句话来解释下,

The compiler may select the appropriate integer type depending on the defined values of
the enumeration constants.

意思就是enum类型的大小是由编译器根据定义值的大小来选择合适的整数类型,所以enum类型的大小并不是固定的。

下面这个代码例子可以说明这个问题,

#include <stdio.h>


enum color1
{
    RED = 0,
    GREEN,
    BLUE
};

enum color2
{
    GRAY = 0x1122334455,
    YELLOW,
    PURPLE
};

int main(void)
{
    printf("enum color1: %d\n", sizeof(enum color1));
    printf("enum color2: %d\n", sizeof(enum color2));
    return 0;
}

输出如下,
在这里插入图片描述
因为enum color2的大小已经超过了4个字节,这样编译器就会把它的大小扩大。

这样会有一个潜在的弊端:如果我们定义了一个结构体,其成员有enum类型,那么就可能导致结构体大小发生变化,而我们却没有察觉,例如随着代码的更迭,我们加入了更多enum规定的范围值,当超过某个值时,它的大小就产生了变化,这是比较危险的。


二 C++11下的enum

C++11下,enum类型可以显式的指定大小,

#include <cstdio>
#include <cstdint>

enum color1 : uint8_t
{
    RED,
    GREEN,
    BLUE
};


enum color2 : uint16_t
{
    GRAY,
    YELLOW,
    PURPLE
};

int main(void)
{
    printf("enum color1: %d\n", sizeof(enum color1));
    printf("enum color2: %d\n", sizeof(enum color2));

    return 0;
}

输出如下,
在这里插入图片描述
因为显式的指定了enum color1为一个字节大小,enum color2为2个字节大小。而且如果enum规定的范围值超过了指定大小,编译会报错,如这种,

enum color1 : uint8_t
{
    RED = 266,
    GREEN,
    BLUE
};

出错信息如下,
在这里插入图片描述


三 C和C++11的enum使用区别

1. enum关键字

在C下我们使用enum去定义变量时必须带上enum这个关键字,而在C++11下可以不用带这个关键字,更加人性化了一点,如下

// c++11 code
#include <cstdio>
#include <cstdint>

enum color
{
    RED,
    GREEN,
    BLUE
};


int main(void)
{
    printf("enum color1: %d\n", sizeof(color));
	color myColor = GREEN;
    return 0;
}
2. enum变量的取值范围

这是很重要的一点区别:在C下enum定义的变量可以赋规定范围外的值,而在C++11下这是不允许的。
下面是C代码,

// c code
#include <stdio.h>

enum color
{
    RED = 0,
    GREEN,
    BLUE
};

int main(void)
{
    enum color myColor;

    myColor = GREEN;
    printf("myColor: %d\n", myColor);

    myColor = 10;
    printf("myColor: %d\n", myColor);

    return 0;
}

输出如下,
在这里插入图片描述
个人感觉这是不好的,因为我们已经规定了范围,但是现在整个变量却可以赋一个范围外的值。

而在C++11里,这样写编译就不通过,

// c++11 code
#include <cstdio>
#include <cstdint>

enum color : uint8_t
{
    RED,
    GREEN,
    BLUE
};

int main(void)
{
    color myColor;

    myColor = GREEN; // correct
    printf("myColor: %d\n", myColor);

    myColor = 10; // error
    printf("myColor: %d\n", myColor);

    myColor = 1; // error
    printf("myColor: %d\n", myColor);

    return 0;
}

可以看到C++11下enum的值必须从规定范围里取,即使是对应的数字也不行,这样就把enum类型的变量值实实在在的限制在规定范围里了,就不用担心会出现范围外的值。

关于C++11的enum,还有很多其它内容,感兴趣的同学可以去cppreference上查看。


四 总结

本文分析了C/C++下的enum类型的实际大小,可以看出C++11下enum的大小范围都得到了更好的控制,这样编程时就可以避免潜在的问题。

谢谢阅读,如果有写的不对的地方,请留言指正,谢谢。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值