C/C++的enum类型大小

我们在编程时有时想让一个变量的值只在规定范围里取值,那么就会考虑使用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的大小范围都得到了更好的控制,这样编程时就可以避免潜在的问题。

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

### 回答1: C和C++语言中的基本数据类型大小是根据系统架构和编译器的不同而有所差异。在大多数系统上,以下是常见的C和C++的基本数据类型大小: 1. char:通常是一个字节大小,表示一个字符或小整数值。 2. short:通常是两个字节大小,表示一个短整数值。 3. int:通常是四个字节大小,表示一个整数值。 4. long:通常是四个字节或八个字节大小,表示一个长整数值。 5. long long:通常是八个字节大小,表示一个很长的整数值。 6. float:通常是四个字节大小,表示一个单精度浮点数值。 7. double:通常是八个字节大小,表示一个双精度浮点数值。 8. long double:通常是八个字节或更多字节大小,表示一个长双精度浮点数值。 9. bool:通常是一个字节大小,表示真值(true或false)。 需要注意的是,上述大小只是通常情况下的值,实际大小可能因为不同的系统和编译器而有所不同。此外,C和C++语言提供了一些限定符(如unsigned和signed)以及可变长度的数据类型(如数组和结构体),使得程序员能够更灵活地定义自己所需的数据类型大小。 ### 回答2: C语言中的基本数据类型大小是根据不同系统和编译器而有所差异的。一般来说,C语言中的基本数据类型大小可以使用sizeof关键字来获取。 在大多数系统中,C语言中的基本数据类型大小通常为以下几种: 1. 字符型(char):通常占用1个字节的内存空间。 2. 整型(int):通常占用4个字节的内存空间。但是在一些特殊的嵌入式系统中,int可能占用2个字节或者更多的字节。 3. 短整型(short):通常占用2个字节的内存空间。 4. 长整型(long):通常占用4个字节的内存空间,但是在一些特殊的系统中,long可能占用8个字节。 5. 浮点型(float):通常占用4个字节的内存空间。 6. 双精度浮点型(double):通常占用8个字节的内存空间。 此外,还有一些其他的数据类型,如无符号整型(unsigned int),指针类型(pointer),枚举类型enum)等,它们的大小也是根据不同的系统和编译器而有所差异的。 需要注意的是,这些数据类型大小只是一般情况下的约定,实际上还可能受到系统的位宽、编译器优化等因素的影响。因此,如果需要确切地知道某个系统中这些数据类型大小,可以使用sizeof关键字进行查询。 ### 回答3: C语言中的基本数据类型大小取决于不同的编译器和不同的机器架构。基本数据类型大小是以字节为单位来表示。 一般而言,C语言中的基本数据类型大小如下: 1. char类型大小通常为1字节,即8位。 2. short类型大小通常为2字节,即16位。 3. int类型大小通常为4字节,即32位。 4. long类型大小通常为4或8字节,即32位或64位。 5. float类型大小通常为4字节,即32位。 6. double类型大小通常为8字节,即64位。 但是这只是一般情况下的大小,具体的大小可能因编译器和机器架构的不同而有所变化。在不同的编译器和不同的机器上,基本数据类型大小可能有所不同。因此,在编写程序时,应该尽量避免依赖特定的基本数据类型大小,而要使用C语言提供的宏定义来表示数据类型大小,比如"sizeof"关键字,以确保程序的可移植性和兼容性。 总之,C语言中的基本数据类型大小是以字节为单位来表示的,具体大小取决于编译器和机器架构。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值