作者:李春港

出处:https://www.cnblogs.com/lcgbk/p/14101271.html

一、前言

由于C++项目中用了相对比较多的枚举(enum),正常情况下,枚举变量都是占用一个整形类型的大小,但是项目中枚举(enum)只需要使用到一个字节的大小,因为是在嵌入式设备上执行的代码,资源比较少,那么如果枚举都是按照int型大小来使用的话,这无疑是一种资源浪费。

所以就想有没有一种办法可以控制枚举(enum)占用内存的办法。所幸,通过查找资料,发现C++11的新特性刚好加入了控制枚举大小的机制。那么接下来我们就来看看,枚举(enum)在C++11标准有哪些变化?以及C和C++11中的枚举(enum)有什么区别?

二、C中的枚举(enum)

2.1 C中枚举的大小

前面有说到,默认情况下,枚举enum的大小是一个整形类型的大小,但是整形类型有很多:int、long int、short int等,所以enum的大小还是不能确定的。在C中enum的大小是不可以通过程序员显式控制的,这个大小是编译器根据我们给枚举(enum)赋值的大小来选择合适的整数类型的。

下面举个例子:

/*****************************************************************************
** Copyright 2020 lcg. All rights reserved.
** File name: enum.c
** Description: 测试enum的特性
** Author: lcg
** Version: 1.0
** Date: 2020.12.08
*****************************************************************************/ #include <stdio.h> enum color1
{
RED = 0,
GREEN,
BLUE
}; enum color2
{
GRAY = 0x1122334455,
YELLOW,
PURPLE
}; int main(int argc, char *argv[])
{
printf("enum color1: %d\n", sizeof(enum color1));
printf("enum color2: %d\n", sizeof(enum color2));
return 0;
}

输出结果:

enum color1: 4
enum color2: 8

我们发现这两个枚举变量所占用的大小是不一样的,enum color2已经超过了4个字节,所以编译器会根据实际值的大小来调整枚举变量的大小。

这就存在了一个弊端,当我们定义的一个结构体里面有枚举变量的时候,当枚举变量值变化的时候,那么结构体的大小就有可能会跟着变化。在没有给枚举赋值的时候为结构体申请了堆空间,后面如果给枚举赋了一个超过4个字节的值,那么这个时候结构体的实际大小就已经变化了,这样我们后面程序对该结构体进行操作时就会存在隐患。

2.2 C中枚举的取值范围

我们继续使用上面的例程来说明取值范围:

/*****************************************************************************
** Copyright 2020 lcg. All rights reserved.
** File name: enum.c
** Description: 测试enum的特性
** Author: lcg
** Version: 1.1
** Date: 2020.12.08
*****************************************************************************/ #include <stdio.h> enum color1
{
RED = 0,
GREEN,
BLUE
}; enum color2
{
GRAY = 1,
YELLOW,
PURPLE
}; int main(int argc, char *argv[])
{
enum color1 myClolor1; myClolor1 = RED;
printf("myClolor1: %d\n", myClolor1); myClolor1 = GRAY;
printf("myClolor1: %d\n", myClolor1); myClolor1 = 10;
printf("myClolor1: %d\n", myClolor1); return 0;
}

输出结果:

myClolor1: 0
myClolor1: 1
myClolor1: 10

可以看到,在C下enum定义的变量可以赋规定范围外的值的,但是在C++11下这是不允许的。在C++11中编译会不通过,是C++11对C中enum的优化。

三、C++11中的枚举(enum)

3.1 c++11中新增枚举大小的控制

在C++11中程序员就可以对枚举(enum)进行显式控制其占用内存的大小了,如下示例:

/*****************************************************************************
** Copyright 2020 lcg. All rights reserved.
** File name: enum.cpp
** Description: 测试enum的特性
** Author: lcg
** Version: 1.2
** Date: 2020.12.08
*****************************************************************************/ #include <stdio.h> enum color1 : char {
RED = 0,
GREEN,
BLUE
}; enum color2 : int {
GRAY = 1,
YELLOW,
PURPLE
}; int main(int argc, char *argv[])
{
printf("enum color1: %d\n", sizeof(enum color1));
printf("enum color2: %d\n", sizeof(enum color2)); return 0;
}

输出结果:

enum color1: 1
enum color2: 4

C++11这样的特性就可以很好地解决我在前言所说的那些情况啦,可以节省资源。

3.2 c++11新增有作用域的枚举类型

如上面2.2小节的程序如果在C++11的标准中编译就会出现以下的报错:

1.cpp:33:15: error: cannot convert ‘color2’ to ‘color1’ in assignment
myClolor1 = GRAY;
^
1.cpp:36:15: error: invalid conversion from ‘int’ to ‘color1’ [-fpermissive]
myClolor1 = 10;

在C++11标准中,enum定义的变量是不可以赋规定范围外的值的。这样为后期的调试带来了很多的便利之处。

【C/C++】C和C++11之enum枚举的使用细节的更多相关文章

  1. C++11的enum class & enum struct和enum

    C++11的enum class & enum struct和enum C++标准文档--n2347(学习笔记) 链接:http://www.open-std.org/jtc1/sc22/wg ...

  2. C++11:强类型枚举(enum)

    // C++11之前的enum类型是继承C的,不温不火: // C++11对enum动刀了,加强了类型检查,推出强类型enum类型,眼前一亮 // 使用过QT 的都知道,早就应该这么做了,用的非常爽! ...

  3. [转]C++11的enum class & enum struct和enum

    1. 旧版enum存在的问题 问题 描述 1 向整形的隐式转换(Implicit conversion to an integer) 2 无法指定底层所使用的数据类型(Inability to spe ...

  4. 【转】C++11的enum class & enum struct和enum

    转自:https://blog.csdn.net/sanoseiichirou/article/details/50180533 C++标准文档——n2347(学习笔记) 链接:http://www. ...

  5. 第11课 - enum, sizeof, typedef 分析

    第11课 - enum, sizeof, typedef 分析 1. enum介绍 (1)enum是C语言中的一种自定义类型,和struct.union地位相同,格式如下: // enum每个值的最后 ...

  6. 第11课 enum、sizeof、typedef 分析

    1. enum枚举类型 1.1 使用方法 (1)enum是C语言中的一种自定义类型 (2)enum值是可以根据需要自定义的的整型值 (3)第一个定义的enum值默认为0. (4)默认情况下的enum值 ...

  7. Java enum(枚举)的用法详解(转)

    用法一:常量 在JDK1.5 之前,我们定义常量都是: public static fianl.... .现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法. p ...

  8. Enum枚举

    Java Enum原理 public enum Size{ SMALL, MEDIUM, LARGE, EXTRA_LARGE }; 实际上,这个声明定义的类型是一个类,它刚好有四个实例,在此尽量不要 ...

  9. Swift Enum 枚举

    前言 枚举是一种自定义的数据类型,在 Swift 中枚举类型拥有相当高的自由度.在 Swift 语言中枚举是一级类型,它拥有在其他语言中只有类才拥有的一些特性,比如实例方法,实例构造器等. 枚举声明的 ...

随机推荐

  1. gdb 调试 报 stepping until--- has no line number information

    gdb 经常用 ,但今天使用gdb 调试的时候, break 打断点, 结果也没有打出 哪一行的信息,就只是提示一个具体地址. 使用单步调试 结果爆出 stepping until exit from ...

  2. 剑指offer刷题(算法类_2)

    排序 035-数组中的逆序对(归并排序) 题目描述 题解 代码 复杂度 029-最小的K个数(堆排序) 题目描述 题解 代码 复杂度 029-最小的K个数(快速排序) 题目描述 题解 代码 复杂度 位 ...

  3. deepin20 作为生产力安装体验

    deepin 20安装使用体验,先看一下桌面吧! deepin介绍 简单介绍一下deepin吧,中文名称:深度操作系统,是由武汉深之度科技有限公司在Debian基础上开发的Linux操作系统,注意国内 ...

  4. Java web项目 Jxl 读取excel 并保存到数据库,(从eclipse上移动到tomact服务器上,之路径更改,)

    最开始在eclipse中测试的时候,并没有上传到服务器上,后来发现,想要读取数据必须上传服务器然后把文件删除就可以了,服务器不可以直接读取外地的文件.用到jxl 1.上传到服务器 前端 <for ...

  5. Python 调用Get接口

    import requests,jsonurl = 'http://localhost:30627/api/jobs/GetNuberId?id=2'req = requests.get(url)re ...

  6. 工作中用到的redis操作

    del exists 1.字符串 set,get 2.列表 lRange lRem lPush rPush 3.有序列表 zadd zrem zscore 4.hash hset hget hdel

  7. appium服务器参数

    appium服务器初始化参数 Appium服务器初始化参数(功能) 设置能力 能力参数项 获取appPackage与appActivity 查看当前活动名称 使用uiautomatorviewer定位 ...

  8. MySql学习笔记--详细整理--上

    目录 MySql MySql安装 连接数据库 操作数据库 数据库的列类型 数据库的字段属性 创建数据库 修改删除表 数据管理 外键 DML语言 添加 修改 删除 DQL查询数据(重点) 查询 去重 w ...

  9. LeetCode周赛#209

    1609. 奇偶树 #广搜 #二叉树的层次遍历 题目链接 题意 如果一棵二叉树满足下述几个条件,则可以称为奇偶树 : 二叉树根节点所在层下标为 0 ,根的子节点所在层下标为 1 ,根的孙节点所在层下标 ...

  10. C语言讲义——函数

    为实现特定目的而编写的一段可被调用的代码 简单地讲:函数就是一组语句,取了个名字 别名:子例程(routine)/方法(Method,一般面向对象的语言使用这个叫法) 函数的组成部分 以主函数为例: ...