在C++中,宏定义是一种预处理指令,用于在编译开始之前进行文本替换。宏定义由#define指令和宏名称组成,可以用于定义常量、函数宏和条件编译。
-
定义常量:可以使用#define指令定义常量,例如: #define PI 3.14159 在编译过程中,所有出现的PI都将被替换为3.14159。
-
定义函数宏:可以使用#define指令定义函数宏,例如: #define MAX(a, b) ((a) > (b) ? (a) : (b)) 在编译过程中,所有出现的MAX(a, b)将被替换为((a) > (b) ? (a) : (b))。
-
条件编译:可以使用宏定义来进行条件编译,例如: #define DEBUG #ifdef DEBUG // 调试代码 #endif 只有在定义了DEBUG宏的情况下,才会编译DEBUG宏下的代码。
宏替换:
//宏替换 在预处理期进行替换
#define A 10
当替换的代码段是多行的我们可以用 \ 来进行换行
\:作用 连接当前行和下一行
注意:\ 后不能有任何字符 包括(空格、注释、tab...)
#define B \
for (int i = 0; i < A; i++)\
{\
cout<<i<<" ";\
}cout << endl;
B //调用B函数
输出结果
也可以在宏定义的函数中自己添加参数
#define C(COUNT) \
for (int i = 0; i < COUNT; i++)\
{\
cout<<i<<" ";\
}cout << endl;
在替换的名字后加括号 然后在括号中加入参数 并且在替换的代码段中将想替换的代码换成参数
C(5)
输出结果
当然,我们还可以利用这个方法,去替换一些简单的函数
比如加减乘除操作
#define MUL(A,B) A*B
int mul(int AA, int BB)
{
return AA * BB;
}
cout << MUL(3, 4) << endl;
cout << mul(2, 3) << endl;
输出结果
在预处理期阶段替换 , 效率高,不会像函数参数一样,能够自动的计算
表达式的求解,没有类型的安全检查
cout << MUL(2, 2 + 5) << endl;
cout << mul(2, 2 + 5) << endl;
输出结果
下面是一些有关宏定义中的一些功能
#作用:将宏参数转化为字符串
#define D(ARG) #ARG
我们定义一些函数分别对应不同的参数列表,来测试功能
void fun(int a) { cout << "fun(int)" << endl; }
void fun(char a) { cout << "fun(char)" << endl; }
void fun(const char* a) { cout << "fun(const char *)" << endl; }
fun(D(10));
输出结果
#@作用:将宏参数转化为字符
#define E(ARG) #@ARG
fun(E(5));
输出结果
##作用:连接
#define F(ARG) int a##ARG=1;
这段代码相当定义了一个int a1=1
F(1)
cout << a1 << endl;
输出结果
在开始我们定义了一个A=10
如果我们想重新定义一个A可以使用
#undef A //取消宏定义
int A = 20;
cout << A << endl;
输出结果
同名的函数和宏 默认以宏为主,对于想使用函数来说,函数名加上()以区分
int (MUL)(int AA, int BB) { return AA * BB; }
cout << MUL(3, 5 + 2) << endl;
cout << (MUL)(3, 5 + 2) << endl;
输出结果
可以看到一个是调用了函数 一个是调用了宏
总的来说,宏在C++中是一种文本替换机制,可以用于定义常量、简化代码和编写通用代码。然而,宏的使用也需要小心,避免产生意想不到的结果。
优点 | 缺点 |
使用宏可以替换在程序中经常使用的常量或表达式,在后期程序维护时,不用对整个程序进行修改,只需要维护、修改一份宏定义的内容即可 | 不方便调试 |
宏在一定程度上可以代替简单的函数,这样就省去了调用函数的各种开销,提高程序的运行效率 | 没有类型安全的检查,对带参的宏而言,由于是直接替换,并不会检查参数是否合法,也不会计算求解,存在一定的安全隐患 |