C++宏定义
1、#define命令
#define命令时C语言中的一个宏定义命令,它将一个标识符定义为一个字符串,该标识符被称为宏名,被定义的字符串被称为替换文本。
1.1 不带参数的宏定义
格式:#define 标识符 字符串
例如:
#define PI 3.1415926
宏定义的功能在于预处理(预编译):将宏名替换为字符串。
说明:
- 宏名一般要大写
- 使用宏可提高程序的可读性,减少不一致性,减少输入错误和便于修改。例如:数组大小通常用宏定义
- 预处理时在编译之前的处理,而编译的工作任务之一就是检查语法,预处理不做语法检查
- 宏定义末尾不加分号
- 宏定义写在函数花括号外,并且在文件的最开头
- 可以用#undef命令终止宏定义的作用域
- 宏定义可以嵌套
1.2 带参数的宏定义
格式:#define 标识符(参数表) 宏体
例如:
#define N(x,y) x*y
若在程序中出现代码“area=N(3,3);” 则执行顺序为:先替换为“area=x*y;”,再替换为“area=3*3;”
说明:
- 实参如果是表达式容易出问题,例如:#define S(r) r*r 代码:area=S(a+b); 执行顺序:1.area=r*r 2.area=a+b*a+b 所以正确的宏定义为:#define S(r) ((r)*(r))
- 宏名和参数的括号之间不能有空格
- 宏替换只做替换,不做计算,也不做表达式求解
- 宏展开不占运行时间,只占用编译时间
下面继续看两个例子:
#define MAX(a,b) ((a)>(b)?(a):(b)) ... i_max = MAX(1+2,value);
替换成:((1+2)>(value)?(1+2):(value))
#define FUCT(a) "a" ... str = FUCT(234);
以上会被替换成“234”吗?答案是不会,无论是多少,都会被替换为“a”。想要实现“234”继续往下看。
1.3 有参数宏定义中#的用法
#define STR(str) #str
以上宏定义是将参数str两端加上字符串的“”,即str内容是什么就替换成相应的字符串。但是以下情况会出错:
- STR()),编译器不会把中间的“)”当作参数;
- STR(,),编译器不会把“,”当作参数;
- STR(a,b),如果参数多了,编译器会把多余的参数舍去;
- STR((a,b)),编译器会解读"(a,b)"为参数
1.4 有参数宏定义中##的用法
#define SUB(str) L##str
以上宏定义会在形参str前加上L。
比如代码:SUB("123")就会被替换为L"123"。再比如
#define FUN(a,b) vo##a##b() ... FUN(id ma,in);
以上会被替换为:void main()
要说明#和##区别,首先看如下代码:
1 #include <iostream>
2 #define t01(x) test##x
3 #define t02(y) #y
4
5 using namespace std;
6 int main() {
7 int test1 = 10;
8 cout<<t01(1)<<endl;
9 cout<<t02(test1)<<endl;
10 return 0;
11 }
输出为:
10 test1
##是链接符号,可用于参数连接,如代码行2所示;
#出现在宏定义中的#是将跟在其后的的参数转换成一个字符串,即字符串化,如代码行3所示。
1.5 条件编译
条件预处理器的结构与if选择结构很像。
#ifdef NULL #define NULL 0 #endif
可以只在调试时进行编译,调试开关可以使用一个宏来实现,如下所示:
#ifdef DEBUG cerr <<"Variable x = " << x << endl; #endif
如果在指令 #ifdef DEBUG 之前已经定义了符号常量 DEBUG,则会对程序中的 cerr 语句进行编译。您可以使用 #if 0 语句注释掉程序的一部分,如下所示:
#if 0 不进行编译的代码 #endif
示例:
1 #include <iostream> 2 using namespace std; 3 #define DEBUG 4 5 #define MIN(a,b) (((a)<(b)) ? a : b) 6 7 int main () 8 { 9 int i, j; 10 i = 100; 11 j = 30; 12 #ifdef DEBUG 13 cerr <<"Trace: Inside main function" << endl; 14 #endif 15 16 #if 0 17 /* 这是注释部分 */ 18 cout << MKSTR(HELLO C++) << endl; 19 #endif 20 21 cout <<"The minimum is " << MIN(i, j) << endl; 22 23 #ifdef DEBUG 24 cerr <<"Trace: Coming out of main function" << endl; 25 #endif 26 return 0; 27 }
输出:
Trace: Inside main function Trace: Coming out of main function The minimum is 30
1.6 预定义宏
C++提供了一些预定义宏:
| 宏 | 描述 |
| __LINE__ | 在程序编译时包含当前行号 |
| __FILE__ | 在程序编译时包含当前文件名 |
| __DATE__ | 包含一个形式为month/day/year的字符串,它代表源文件转换为目标文件的日期 |
| __TIME__ | 包含一个形式为hour:minute:second的字符串,它表示程序被编译的时间 |
示例:
1 #include <iostream> 2 using namespace std; 3 4 int main() { 5 cout << "Value of __LINE__ : " << __LINE__ << endl; 6 cout << "Value of __FILE__ : " << __FILE__ << endl; 7 cout << "Value of __DATE__ : " << __DATE__ << endl; 8 cout << "Value of __TIME__ : " << __TIME__ << endl; 9 10 return 0; 11 }
输出:
Value of __LINE__ : 5 Value of __FILE__ : /home/howardy/projects/CLion_Projects/Date0927/main.cpp Value of __DATE__ : Sep 27 2020 Value of __TIME__ : 20:57:57
转载自:C++中的宏定义详解

浙公网安备 33010602011771号