C++ #define宏定义用法详解(附带实例)

2025-11-15 11:48:50

宏定义是预处理命令的一种,它提供了一种可以替换源代码中字符串的机制。简单来说,宏定义指令 #define 用来定义一个标识符和一个字符串,以这个标识符来代表这个字符串,在程序中每次遇到该标识符时就用所定义的字符串替换它。

宏定义的作用相当于给指定的字符串起了一个别名。

C++不带参数的宏定义

不带参数的宏定义一般形式如下:

#define 宏名 字符串

“#”表示这是一条预编译命令;

宏名是一个标识符,必须符合 C++ 语言标识符的规定;

字符串可以是常数、表达式、格式字符串等。

例如,下面的宏定义中用 3.14159 替代 PI。编译预处理时在源程序中遇到 PI,会自动用 3.14159 代替:

#define PI 3.14159

使用 #define 进行宏定义的好处是:当需要改变一个常量时,只需改变 #define 命令行,整个程序的常量都会改变,大大提高了程序的灵活性。

宏名要简单且意义明确,一般习惯用大写字母表示,以便与变量名相区别。

注意,宏定义不是 C++ 语句,不需要在行末加分号。

宏名定义后,即可成为其他宏名定义中的一部分。例如,下面的程序代码定义了正方形的边长 SIDE、周长 PERIMETER 及面积 AREA 的值:

#define SIDE 5

#define PERIMETER 4*SIDE

#define AREA SIDE*SIDE

前面强调过,宏替换是以字符串代替标识符。因此,如果希望定义一个标准的邀请语,可编写如下程序代码:

#define STANDARD "You are welcome to join us."

printf(STANDARD);

编译程序遇到标识符 STANDARD 时,就会用字符串“You are welcome to join us.”替换。

以上编译程序,与 printf 语句的如下形式是等效的:

printf("You are welcome to join us.");

关于不带参数的宏定义,要强调以下几点:

1) 当字符串中含有宏名时,不进行替换。例如:

#include

#define TEST "this is an example"

int main()

{

char exp[30] = "This TEST is not that TEST"; // 定义字符数组并赋初值

printf("%s\n", exp);

}

程序运行结果为:

This TEST is not that TEST

可见字符串中的 TEST 并没有被“this is an example”替换。

2) 当字符串长于一行时,可在行尾用反斜杠“\”续行。

3) #define 命令出现在程序中函数的外面,宏名的有效范围为定义命令之后到此源文件结束。

注意,实际开发中,一般将所有 #define 都统一放在文件开始代码处,或放在一个独立的文件中,而不会将它们分散到整个程序中。

4) 可以用 #undef 命令终止宏定义的作用域。例如:

#include

#define TEST "this is an example"

int main()

{

printf(TEST);

#undef TEST

}

运行结果为:

this is an example

5) 宏定义用于预处理命令,它不同于定义的变量,只进行字符替换,不分配内存空间。

C++带参数的宏定义

带参数的宏定义不是简单的字符串替换,它还要进行参数替换。一般形式如下:

#define 宏名(参数表)字符串

【实例】求两个数的乘积。使用带参数的宏实现求两个数的乘积。具体代码如下:

#include

#define MUL(x,y) ((x)*(y)) //定义两个数的乘积

int main()

{

int a,b,c;

printf("请输入两个整数:\n");

scanf("%d%d",&a,&b);

c=MUL(a,b); //调用宏定义

printf("两数乘积为:%d\n",c);

return 0;

}

程序运行结果为:

请输入两个整数:

3 4

两数乘积为:12

当编译该程序时,由 MUL(x,y) 定义的表达式被替换,a 和 b 用作操作数,即“c=MUL(a,b);”语句被代替后变为如下形式:

c=((a)*(b));

用宏替换的一个好处是,因为不存在函数调用,所以可提高代码的速度。但提高速度也有代价,因为重复编码会增加代码的长度。

对于带参数的宏定义要强调以下几点:

1) 宏定义时参数要加括号。如不加括号,有时结果是正确的,有时结果便是错误的。

如前面的实例程序中,当参数 a=8,b=9 时,在参数不加括号的情况下调用 MUL(a,b),可以正确地输出结果;当 a=8,b=5+4 时,若参数不加括号,即定义成 #define MUL(a,b) a*b,这种情况下调用 MUL(a,b),则输出的结果是错误的。此时调用的 MUL(a,b) 执行情况如下:

c=8*5+4;

此时计算的结果是 44,而实际上希望得出的结果是 72。为了避免出现上面这种情况,在进行宏定义时,一定要在参数外面加上括号。

2) 宏扩展必须使用括号来保护表达式中低优先级的操作符,以确保调用时达到想要的效果。

例如,有如下宏定义:

#define SUB(x,y) (x)+(y)

通过如下代码调用该宏定义时:

5*SUB(x,y);

则会被扩展为:

5*(x)+(y);

而本意是希望得到:

5*((x)+(y));

解决的办法是宏扩展时加上括号,此时就能避免这种错误发生。

3) 对带参数的宏的展开,只是将宏名后面括号内的实参字符串代替 #define 命令行中的形参。

4) 在宏定义时,宏名与带参数的括号之间不能加空格,否则将空格以后的字符都作为替代字符串的一部分。

5) 在带参宏定义中,形式参数不分配内存单元,因此不必做类型定义。