区别一:类型和安全检查不同
const
定义的常数是变量,带类型,而#define
定义的只是个常数,不带类型。
const
有对应的数据类型,是要进行判断的,可以避免一些低级的错误,而#define
只是简单的字符串替换,没有类型检查,会导致边界效应,例如:
#define N 2+3 // 我们预想的 N 值是 5,我们这样使用
double a = N/2; // 我们预想的 a 的值是 2.5,可实际上 a 的值是 3.5
区别二:编译器处理不同
#define
是在编译的预处理阶段起作用,而const
是在编译、运行的时候起作用。
编译的预处理阶段是指对源代码的伪指令(以#
开头的指令)和特殊符号(例如含有双下划线的__LINE__
,表示当前行号的整数)进行处理。或者说是扫描源代码,对其进行初步的转换,产生新的源代码提供给编译器。预处理过程先于编译器对源代码进行处理。
从代码调试的方便程度而言,const
常量可以进行调试的,#define
是不能进行调试的,因为在预编译阶段就已经替换掉了。
区别三:存储方式不同
宏定义是直接替换,不会分配内存,存储于程序的代码段中;const
常量需要进行内存分配,存储于程序的数据段中,例如:
#define PI 3.14 // 预处理后占用代码段空间
const float PI=3.14; // 本质上还是一个 float,占用数据段空间
区别四:定义域及能否重定义
void f1()
{
#define N 2
const int n 3;
}
void f2()
{
cout<< N <<endl; //正确,N 已经定义过,不受定义域限制
cout<< n <<endl; //错误,n 定义域只在 f1 函数中
}
宏定义可以通过#undef
来使之前的宏定义失效,而const
常量定义后将在定义域内永久有效:
void f1()
{
#define N 2
const int n = 2;
#undef N //取消宏定义后,即使在 f1 函数中,N 也无效了
#define N 3 //取消后可以重新定义
}
区别五:是否可以作为函数参数
宏定义不能作为参数传递给函数,而const
常量可以在函数的参数列表中出现。