c/c++ #define const enum浅析

本文对比分析了C/C++中的#define宏定义、const限定符及enum枚举类型的使用特点与区别,探讨了它们在编译、运行过程中的特性及适用场景,并给出了具体的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对于#define,const, enum在编写一些c/c++代码的初学者在概念上可能会有所模糊。

今天我们来浅析一下三者之间的在编译,运行,与试用场景上的区别。首先让我们先逐个说说他们。

1.#define:被定义为“宏”的标识符称为“宏名”。在编译预处理时,对程序中所有出现的“宏名”,都用宏定义中的字符串去代换,这称为“宏代换”或“宏展开”。宏的替换是由预处理程序自动完成的。宏定义的作用范围仅限于当前文件。在c/c++语言中,宏又分为有参宏和无参宏两种  

宏定义不是说明或语句,在行末不必加分号,如加上分号则连分号也一起置换

无参宏定义的一般形式为:#define标识符 字符串
其中的“#”表示这是一条预处理命令。凡是以“#”开头的均为预处理命令。“define”为宏定义命令。“标识符”为所定义的宏名。“字符串”可以是常数、表达式、格式串等。
如:#define MIN 30  在预处理阶段用30去替换标识符MIN。

c语言允许宏带有参数。在宏定义中的参数称为形式参数,在宏调用中的参数称为实际参数。
带参宏定义的一般形式为:#define 宏名(形参表) 字符串
如:#define MAX(a,b) ((a>b)?(a):(b))
对于带参宏下面我们再看这个例子。
#define MAX(x,y) (++x)>(y)?(++x):(y);
int x = 10,y = 2;
MAX(10,2);
cout <<"x:"<<x<<endl;
这种表达式存在副作用,输出为x:12 在编写程序是也要特别注意。尽量避免这样的行为。

使用宏定义的有点:
(1) 方便程序的修改
使用简单宏定义可用宏代替一个在程序中经常使用的常量,这样在将该常量改变时,不用对整个程序进行修改,只修改宏定义的字符串即可。

(2) 提高程序的运行效率
使用带参数的宏定义可完成函数调用的功能,又能减少系统开销,提高运行效率。

2.const:限定符,它把一个对象转换成一个常量。
对于这个限定符如果要细说的话可就多了。这里我们只研究其三者之间的区别,对于const在以后会将它单独拿出来说明的。
但与#define有什么不同呢? const关键字是在编译时期进行处理的,而#define是在预处理时期进行处理的,所以C中常用:“ #define 变量名 变量值”定义一个值替代,然而却有个致命缺点:缺乏类型检测机制,这样预处理在C++中成为可能引发错误的隐患,于是引入const.。这是在编译的不同。
const与define。两者都可以用来定义常量,但是const定义时,定义了常量的类型,所以更精确一些。#define只是简单的文本替换,除了可以定义常量外,还可以用来定义一些简单的函数,有点类似内联函数。const和define定义的常量可以放在头文件里面。

3.enum:计算机编程语言中的一种数据类型。枚举类型。
这里enum可以用来声明一系列整型常量,同时也能声明为枚举类型,用来定义枚举变量。
使用的差别是enum的常量只能是整型常量或者单个字符值,
#define却可以 #define NAME "Amy"
后者仅仅是字符替换,如果需要定义一系列的常量,用enum可以省去很多输入,本质上是有很大差别的,对于整型常量,两者也是可以替换着使用的。
其次枚举常量则是在编译的时候确定其值的。在编译时期中能看出,枚举是类型安全的,define不是类型安全的。

#define宏定义常量和cosnt,enum的区别:

#define 宏定义常量,在开始预处理时就要被替换,所以定义的记号名不会进入记号表,当编译调试时,因为到时直接是一个数值,可能让人产生迷惑。 可以用const 和 enum 来代替宏。常量肯定会进入记号表,可以更容易跟踪,使用常量可能比使用#define导致较小量的码,因为编译器会盲目的将宏定义进行替换,而常量一般在内存中只有一份实体

当用常量替换#define时有两种特殊情况


1.定义常量指针:常量定义一般放在头文件,因此要将指针声明为const,

const char *const authorname = "Scott Meyers";


2.class专属常量,为了将常量的作用域限制于class内,必须让它成为class的一个成员;为了确保此常量只有一份实体,必须让它成为一个static成员:


class GamePlayer{
private:
static const int NumTurns;      //常量声明式
int scores[NumTurns];            //使用该常量
};


const int GamePlayer::NumTurns = 5;


///或者可以如下:
class GamePlayer{
private:
enum{NumTurns = 5};
int scores[NumTurns];
}

我们无法利用#define创建一个class专属常量,因为#define并不重视作用域。

取一个const地址是合法的,但取一个enum的地址是不合法的,取一个#define的地址也不合法

请记住:
1.对于单纯常量,最好以const对象或enums替换#defines.
2.对于形似函数的宏,最好改用inline函数替换#define.

参考文献:百度文库
优快云博客:http://blog.youkuaiyun.com/wjxxaut/article/details/52118577

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值