Unix/C/C++--enum

1 介绍

12个月份名、一周7天名、模式名、状态名,等同类名合集,在程序中会用到。使用宏定义实现,宏名过多,代码松散;使用数组实现,亦是如此,enum能减少内存占用、使得代码紧凑、清晰简洁!

1.1 C中enum

  • enum变量

1.2 C++中enum

  • enum变量
  • enum类
enum class Level : unsigned int {
	Global = 1,
  	Trace = 2,
  	Debug = 4,
  	Fatal = 8,
  	Error = 16,
  	Warning = 32,
  	Verbose = 64,
  	Info = 128,
  	Unknown = 1010
};

2 详解

2.1 定义

  • 语法结构:
    enum [枚举名] {e1[=Value1], e2[=Value2] ,… …};
    e1、e2… …:称为枚举常量,枚举成员,也称为枚举子。
    Value1,Value2… …:称为枚举子值,即枚举值,可忽略不写,默认从0依次赋值。
  • 定义枚举类型变量:
    [enum] 枚举名 枚举变量名 [=初始化值];
enum color {red,green,blue}; //枚举值分别为0,1,2.
color paint = red;

或者

enum color {red=1 , green =5, blue=10} paint;

枚举值在未特定赋值外,后续枚举成员默认都是依上个成员的枚举值依次递增的。

2.2 内存

2.2.1 占用内存大小

C/C++中枚举变量的大小是 1<=sizeof(enum)<=sizeof(int) 字节 (1-4字节),编译器通过编译器选项,有的处理成32bit,有的处理成8bit。

  • 该博主测过数据、论枚举类型的存储空间
    在Visual C++ 6.0编译器默认为枚举变量分配4字节的存储空间
    在MDK–ARM环境下测试的结果是只为枚举变量分配1字节的存储空间

  • 可以通过继承方式改变枚举的大小,例如:

enum EnumChar : unsigned char {
    A = 0x00,
    B,
    C = 0xff
};

TypeChar 类型变量大小占用1字节
在这里插入图片描述

2.2.2 存储区域

枚举常量,它们不占用数据区(常量区、全局数据区、栈区和堆区)的内存,而是直接被编译到命令里面,放到代码区,所以不能用&取得它们的地址。

2.3 作用域

枚举列表中的标识符的作用范围是全局的(严格来说是 main() 函数内部),不能再定义与它们名字相同的变量。

2.4 存储类型

2.4.1 C

2.4.2 C++

c++11可以指定编译器使用哪种整型来存储定义的枚举类型。如 enum class test : unsigned int {TEST1,TEST2};
如果不指定存储类型,则限定作用域的枚举类型使用int来作为存储类型,如果枚举成员的取值超过其表达范围会编译错误。
如果不指定存储类型,则不限定作用域的枚举类型使用什么类型由编译器负责,编译器只要保证存储类型够大可以存储所有成员即可,不同的编译器可能会使用不同的存储类型。

2.5 类型转换

enum MyEnum{
  EXAMPLE_1 = 0,
  ...
};

char type = 0;
MyEnum etype = static_cast<MyEnum>(type);

2.6 生命周期

2.7 特殊用法

  • 枚举成员不可以重复,但是枚举值可以重复。重复枚举值的枚举成员表明它们具有共同性质,所以放在一起。
enum weeks {mon=1,tue=1,wed=1,thu=1,fri=1,sat=2,sun=2};
  • 一周周一到周五是工作日,我们希望它们具有共性和相同的枚举值。而周末休息,我们希望它两有另外一个枚举值。
  • .一个整数不能直接赋给一个枚举变量,必须强制进行类型转换才能赋值
enum weeks day;
day =(weeks)2;
  • 枚举值可以用在if-else或者switch-case判断中
if(day != mon)
{
    printf("今天是工作日\n");
}

3 编译

  • 枚举和宏其实非常类似:宏在预处理阶段将名字替换成对应的值,枚举在编译阶段将名字替换成对应的值。我们可以将枚举理解为编译阶段的宏。

4 C++高级应用

在c++11标准中,除了传统的enum关键字之外, 还新增了一个概念: enum class, enum struct组合的形式(两者是等价的),当然单纯的enum关键字和enum class组合并不冲突,都能使用。 这一组合的出现就是为了解决传统enum关键字面临的问题。

enum class组合具有class封装性的特性,作用域是确定的
enum class A
{
my_enum3 = 0,
};

enum class B
{
my_enum3 = 0,
};

enum C
{
my_enum3 = 0,
};

如上面这样声明和定义枚举就是正确的,要访问A和B中的枚举是需要加上作用域的,形如:
A a = A::my_enum3;
B b = B::my_enum3;
可以指定底层数据类型
enum class A: int /** 每个枚举都是int类型的 */
{
my_enum3 = 0,
};

enum class B: unsigned char /** 每个枚举都是unsigned char类型的 */
{
my_enum3 = 0,
};

不能隐式转换
int my_int = A::my_enum3; /** 错误,无法通过编译 */
int my_int = static_cast<int>(A::my_enum3); /** 正确, 可以通过编译 */

参考

1、枚举类型
2、C/C++中枚举类型enum使用
3、C语言枚举类型(C语言enum用法)详解–编程
4、enum 变量内存大小(c++)
5、unsigned char to enum
6、论枚举类型的存储空间
7、c++11 强类型枚举 enum class
8、奇妙的enum class,enum struct组合

展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 技术黑板 设计师: CSDN官方博客
应支付0元
点击重新获取
扫码支付

支付成功即可阅读