C++ define宏定义的用法(附带实例)
宏定义又称为宏替换,简称“宏”。在 C++ 中,可以使用 #define 指令来定义一个宏:
定义好宏之后,可以在程序代码中使用这个宏来代替宏定义中的字符串。例如:
C++ 代码在最终参与编译之前会经过一个预处理过程,这个过程中如果遇到代码中使用了宏,就会将宏展开,也就是将宏名替换为宏定义中的字符串。因此,宏展开后,这段代码实际上成为:
另外,从这里也可以看到,宏的使用有效简化了代码—将长长的圆周率 3.1415926 替换为简单的 PI,更便于使用。因此,如果代码中有需要进行“替换”的地方,例如将那些长长的字符串常量替换为一个简短的宏,或者利用宏给某个字符串赋予一个更有意义的名字,就可以使用宏,如下图所示。

图 1 宏的“偷梁换柱”
除这种不带参数的宏外,还可以在宏定义中加入参数,让宏的使用更加灵活。其语法格式如下:
与函数参数不同,宏的参数并没有数据类型的概念,它只是一个占位符,用作宏展开时被实际参数替换。对带有参数的宏进行宏展开时,不仅要对宏标识符进行字符串替换,还必须进行参数的替换。
例如:
当进行宏展开时,这个宏首先进行字符串的替换,这行代码变为:
恰当地使用宏可以提高程序的通用性和可读性,减少不一致性、输入错误和修改量。因此,高手都喜欢使用它。然而,虽然宏的好处很多,但它可能带来不少麻烦。因为宏的本质只是简单地进行字符串替换,这可能会丢失有价值的变量符号名,而给调试工作带来一定困扰。
带参数宏的展开过于灵活,稍有不慎就可能出错。因此,更多时候,我们建议使用 const 常量来代替宏定义的标识符,或者使用 inline 内联函数来代替带参数的宏,尽量减少宏的使用。
#define 标识符 字符串其中,标识符就是所谓的符号常量,也称为“宏名”,其后的字符串可以是一个数字,也可以是一个字符串常量,甚至可以是一个复杂的表达式。
定义好宏之后,可以在程序代码中使用这个宏来代替宏定义中的字符串。例如:
// 定义一个宏,表示圆周率 #define PI 3.14159 // 利用定义的宏计算圆的面积 double fR = 5.0f; double fArea = PI * fR * fR;
C++ 代码在最终参与编译之前会经过一个预处理过程,这个过程中如果遇到代码中使用了宏,就会将宏展开,也就是将宏名替换为宏定义中的字符串。因此,宏展开后,这段代码实际上成为:
// 宏展开后的代码 double fArea = 3.14159 * fR * fR;从这里可以看到,宏的本质就是“替换”,即“偷梁换柱”:用宏定义中的字符串替换程序代码中的宏名。虽然在程序代码中使用的是宏,但经过预处理后最终参与编译的代码却是“替换”后的代码。
另外,从这里也可以看到,宏的使用有效简化了代码—将长长的圆周率 3.1415926 替换为简单的 PI,更便于使用。因此,如果代码中有需要进行“替换”的地方,例如将那些长长的字符串常量替换为一个简短的宏,或者利用宏给某个字符串赋予一个更有意义的名字,就可以使用宏,如下图所示。

图 1 宏的“偷梁换柱”
除这种不带参数的宏外,还可以在宏定义中加入参数,让宏的使用更加灵活。其语法格式如下:
#define 标识符(参数列表) 字符串其中,参数列表列出的就是这个宏的所有参数。
与函数参数不同,宏的参数并没有数据类型的概念,它只是一个占位符,用作宏展开时被实际参数替换。对带有参数的宏进行宏展开时,不仅要对宏标识符进行字符串替换,还必须进行参数的替换。
例如:
// 定义一个带参数的宏,取得两个数中比较大的一个数 #define MAX(a, b) ((a) > (b) ? (a) : (b)) // 使用宏取得 2 和 4 中较大的一个数 int nMax = MAX(2, 4);
当进行宏展开时,这个宏首先进行字符串的替换,这行代码变为:
int nMax = ((a) > (b) ? (a) : (b));接着,使用宏的实际参数替换宏定义中的参数,也就是用实际参数数字 2 替换形式参数 a,用数字 4 替换 b,最终这行代码变为:
int nMax = ((2) > (4) ? (2) : (4));经过一系列的替换,我们终于看到了这行代码的本来面目。其实就是这么简单。
恰当地使用宏可以提高程序的通用性和可读性,减少不一致性、输入错误和修改量。因此,高手都喜欢使用它。然而,虽然宏的好处很多,但它可能带来不少麻烦。因为宏的本质只是简单地进行字符串替换,这可能会丢失有价值的变量符号名,而给调试工作带来一定困扰。
带参数宏的展开过于灵活,稍有不慎就可能出错。因此,更多时候,我们建议使用 const 常量来代替宏定义的标识符,或者使用 inline 内联函数来代替带参数的宏,尽量减少宏的使用。