对于#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可以省去很多输入,本质上是有很大差别的,对于整型常量,两者也是可以替换着使用的。
使用的差别是enum的常量只能是整型常量或者单个字符值,
#define却可以 #define NAME "Amy"
后者仅仅是字符替换,如果需要定义一系列的常量,用enum可以省去很多输入,本质上是有很大差别的,对于整型常量,两者也是可以替换着使用的。
其次枚举常量则是在编译的时候确定其值的。在编译时期中能看出,枚举是类型安全的,define不是类型安全的。
#define宏定义常量和cosnt,enum的区别:
#define 宏定义常量,在开始预处理时就要被替换,所以定义的记号名不会进入记号表,当编译调试时,因为到时直接是一个数值,可能让人产生迷惑。 可以用const 和 enum 来代替宏。常量肯定会进入记号表,可以更容易跟踪,使用常量可能比使用#define导致较小量的码,因为编译器会盲目的将宏定义进行替换,而常量一般在内存中只有一份实体
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.
#define 宏定义常量,在开始预处理时就要被替换,所以定义的记号名不会进入记号表,当编译调试时,因为到时直接是一个数值,可能让人产生迷惑。 可以用const 和 enum 来代替宏。常量肯定会进入记号表,可以更容易跟踪,使用常量可能比使用#define导致较小量的码,因为编译器会盲目的将宏定义进行替换,而常量一般在内存中只有一份实体
当用常量替换#define时有两种特殊情况:
const char *const authorname = "Scott Meyers";
2.class专属常量,为了将常量的作用域限制于class内,必须让它成为class的一个成员;为了确保此常量只有一份实体,必须让它成为一个static成员:
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