Professordeng's Blog

宏定义是一种批量处理的称谓。在 C 语言中,代码生成二进制程序需要经过如下几个主要过程:

  1. 预处理。宏展开就是在这步进行的,这里是主要将代码整合一下。也就是说,编译器并不处理宏。
  2. 编译。对预处理后的代码进行语义分析并优化,然后翻译为汇编语言。
  3. 汇编。机器并不能识别汇编语言,需要通过汇编器将汇编语言翻译成二进制语言。
  4. 链接。每个独立的源文件被经过第 3 步后,都会变成独立的目标文件,此时我们需要将所有目标文件链接起来形成可执行文件,这里涉及到目标文件中逻辑地址的变化。

学习宏,其实就是学习如何预处理代码,最常用的宏有如下几种情况。

  1. 引入头文件。

    #define <stdio.h>
    

    其实质是在预处理阶段,这个语句会被 stdio.h 中的内容所替代。

  2. 定义常量。

    #define O_RDONLY 1
    

    在操作系统的实现中,有很多标志位都是以宏定义的方式来定义的,预处理过程会用 1 替换所有的 O_RDONLY

除了以上两个用处,宏还可以实现很多特别实用的预处理功能,如果说代码实现功能,那么宏就是实现代码,做一些文本的替换工作。

1. 最值

有些代码写在一般语句里面影响阅读性,封装成一个函数又浪费性能。这时我们可以利用宏定义简化一下,例如求两个数之间的最值,如下

#define  MAX( x, y ) ( ((x) > (y)) ? (x) : (y) )
#define  MIN( x, y ) ( ((x) < (y)) ? (x) : (y) )

这里会将所有 MAX(x, y) 替换成 ( ((x) > (y)) ? (x) : (y) ),实现取最大值的功能。