Fork me on GitHub

至简

Be simple

为了寻找你,我把自己搬进鸟的眼睛,经常盯着路过的风。


宏定义define和常量const的区别


区别一:类型和安全检查不同

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常量可以在函数的参数列表中出现。