枚举enum中的枚举元素与宏定义冲突错误及解决方法

问题描述及原因

c语言代码中,如果出现枚举元素与宏定义命名相同,则编译会出现错误,例如下述.h文件中,用 typedef 关键字为 枚举数据类型 enum{FALSE=0, TRUE=!FALSE} 起了一个新的名字 bool.

typedef enum {FALSE = 0, TRUE = !FALSE} bool;

typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus, BitStatus, BitAction;

typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;

typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus;

如果代码工程中,同时出现如下的宏定义与枚举变量重名,则编译会报错。原因是:

  1. 枚举数据类型中的枚举元素是常亮,不是变量,因此枚举元素又称为枚举常量。如上述枚举数据类型bool中,枚举元素 FALSE=0, 因此FALSE就是常量0,是有值的。
  2. 既然系统已经在声明枚举类型时,指定了FALSE是一种枚举元素(常量0),则如果在对其进行宏定义 #define FALSE 0 就会出现编译错误。
//#ifndef TRUE
//#define         TRUE             1
//#endif

//#ifndef FALSE
//#define         FALSE            0
//#endif

//#ifndef SUCCESS
//#define         SUCCESS             1
//#endif

//#ifndef ERROR
//#define         ERROR               0
//#endif

//#ifndef ENABLE
//#define         ENABLE              1
//#endif
//
//#ifndef DISABLE
//#define         DISABLE             0
//#endif

枚举数据类型的用法:定义及变量声明

枚举是一种数据定型

  1. 可以先进行定义,然后由该数据类型来声明变量
enum DAY
{
      MON=1, TUE, WED, THU, FRI, SAT, SUN
};

enum DAY tomorrow; //变量 tomorrow的类型为枚举( 数据类型)型enum DAY
enum DAY good_day, bad_day; //变量good_day和bad_day的类型均为枚举类型enum DAY
  1. 也可以类型定义与变量声明同时进行:
enum //跟第一个定义不同的是,此处的标号DAY省略,这是允许的。
{
    saturday,
    sunday = 0,
    monday,
    tuesday,
    wednesday,
    thursday,
    friday
} workday; //变量workday的类型为枚举型enum DAY
  1. 还可以用typedel关键字来重命名枚举数据类型,并利用该别名进行变量声明:
typedef enum DAY // 此处DAY枚举类型名可省略
{
    saturday,
    sunday = 0,
    monday,
    tuesday,
    wednesday,
    thursday,
    friday
} workday; //此处的workday为枚举型enum DAY的别名

枚举数据类型的易错概念

(1) 枚举型是一个集合,集合中的元素(枚举成员)是一些命名的整型常量,元素之间用逗号,隔开。
(2) DAY是一个标识符,可以看成这个集合的名字,是一个可选项,即是可有可无的项。
(3) 第一个枚举成员的默认值为整型的0,后续枚举成员的值在前一个成员上加1。
(4) 可以人为设定枚举成员的值,从而自定义某个范围内的整数。
(5) 枚举型可替代预处理指令#define
(6) 类型定义以分号;结束。
(7) 同一个程序中不能定义同名的枚举类型,不同的枚举类型中也不能存在同名的命名常量。即枚举类型的枚举元素无论如何(对本工程文件内部而言)也不能重名。
(8) 对枚举型的变量赋整数值时,需要进行类型转换

enum DAY { MON=1, TUE, WED, THU, FRI, SAT, SUN };//枚举数据类型定义
enum DAY yesterday, today, tomorrow;//枚举变量声明
yesterday = TUE; //枚举变量赋值
today = (enum DAY) (yesterday + 1); //强制类型转换
tomorrow = (enum DAY) 3; //类型转换
 //tomorrow = 3; //错误

(9)既然枚举元素是常量,因此可用于函数返回

unsigned char func_test(void)
{
 //user's code
 return TRUE; //TRUE为枚举类型bool的枚举常量
}

补充知识: 宏定义、const、枚举常量的比较

  1. 编译器处理方式不同

#define是在预处理阶段对所定义的常量进行替换展开;
const是在编译运行阶段使用;
enum是程序运行时起作用;

  1. 分配内存不同

#define宏定义仅仅是替换和展开,并不进行内存的分配(宏定义不分配内存,常量的定义分配内存);
const常量编译器会分配内存,在堆或者栈;
enum常量存储在内存数据段的静态存储区。

延伸:在C语言里,const的含义是被称为一个不能被改变的普通变量,而在C++中其含义就不尽相同。C++中的const常量,C++编译器都会尽量避免const 常量的内存分配,只有当不得已的时候才会分配具体的内存空间给const变量。

  1. 类型检查

#define宏定义没有类型检查和安全检查,所以会导致边际效应,出现不可预知的错误;
const在编译阶段进行类型检查和安全检查;
enum在编译阶段进行类型检查,但是只能进行整形的定义;

  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值