C程序的源代码中的宏也叫做编译指令,也称为预处理命令,宏严格意义上不属于源代码语言的一部分,因此也可以理解为它扩展了C程序设计的环境。

标准宏

ANSI标准定义的C语言预处理程序包括下列命令:#define,#error,#include,#if,#else,#elif,#endif,#ifdef,#ifndef,#undef,#line,#pragma等。

宏的使用场景

#include引入头文件

最常见的宏,嵌入包含文件,即引用头文件的方法。后面如果是包括显式的路径名,则只搜索路径内;若仅文件名可以用""或者<>括起来,区别在于文件检索顺序上。

  1. #include "" 当前工作目录->已经include的文件所在的文件夹内搜索->编译器设置的include路径->系统的INCLUDE环境变量内搜索
  2. #include <> 编译器设置的include路径->系统的INCLUDE环境变量内搜索

编译开关

可以使用不同的编译指定编译出不同的软件版本,以提供给不同的顾客,或者经常控制编译出DEBUG版本,比如下面使用DEBUG宏控制是否输出调试信息,在编译时可以用过指令来控制生成时否包含宏包含的代码。

#ifdef __DEBUG__
        printf("[debug]sum= %d\n", sum);
#endif

定义常量

代码中经常的用的一些常量可以用宏定义,宏定义的值在编译器第一次用到时引入并一直有效,且无视命名空间,因此,在编译中不能重复定义。

// 定义圆周率
#define PI 3.14159265

简单宏函数

使用宏可以定义简单的单行宏函数

#define MUL(x, y) x * y
int ret = MUL(2, 3);   ==> int ret = 2 * 3;

上面定义了MUL(x, y)可以求两个数的乘积,宏是在编译期进行的符号替换,所以在运行时,不会带来额外的时间和空间开销,但是如果使用函数会在运行时执行压栈出栈的操作,实参到形参的复制,形参和局部变量的初始化等函数调用的开销,因此在需要重复大量调用且简单的函数可以创建宏函数,但是常常在这种情况下更推荐使用内联函数替代宏函数。

多行宏函数

多行宏函数的基本原理和单行宏函数类似,只是宏的简单替换展开。程序中经常出现很多相似的代码块,如果抽象成函数则需要传入很多参数,这时候如果很多参数的名字可以通过字符串拼接,这时候特别适合使用宏可以简化代码,另外,合理使用也可以提高可读性,使得各个代码段中重要的信息可以集中在一起,只是在调试时无法进入宏因此常常受人诟病。

#define ADD(x, y) do { int sum = (x) + (y); return sum; } while (0)
// 宏的内容比较长,也没有缩进,易读性较差,因此转为多行
#define ADD(x, y) \
do \
{\
    int sum = (x) + (y);\
    return sum;\
} while (0)
分类: C++

0 条评论

发表评论

电子邮件地址不会被公开。 必填项已用*标注