zoukankan      html  css  js  c++  java
  • 【C/C++】C和C++11之enum枚举的使用细节

    作者:李春港
    出处: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
    ", sizeof(enum color1));
        printf("enum color2: %d
    ", 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
    ", myClolor1);
        
        myClolor1 = GRAY;
        printf("myClolor1: %d
    ", myClolor1);
        
        myClolor1 = 10;
        printf("myClolor1: %d
    ", 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
    ", sizeof(enum color1));
        printf("enum color2: %d
    ", 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定义的变量是不可以赋规定范围外的值的。这样为后期的调试带来了很多的便利之处。

  • 相关阅读:
    优化cocos2d/x程序的内存使用和程序大小
    cocos2d-x移植:xcode到eclipse
    程序员在编程工作中痛苦的压抑着自己某些强烈的情绪
    C++语言的一些问题
    基数排序-图非常清晰明了
    【Cocos2d-X(1.x 2.x) 修复篇】iOS6 中 libcurl.a 无法通过armv7s编译以及iOS6中无法正常游戏横屏的解决方法
    《C++ Primer》笔记-inline内联函数
    走出你的舒适区
    UDP广播与多播
    测试问题反馈需要包含内容总结
  • 原文地址:https://www.cnblogs.com/lcgbk/p/14101271.html
Copyright © 2011-2022 走看看