如何使用C语言预处理程序

122 阅读3分钟

预处理器是一个在用C语言编程时对我们帮助很大的工具,它是C标准的一部分,就像语言、编译器和标准库一样。

它解析我们的程序,确保编译器在继续工作之前获得所有需要的东西。

在实践中,它做了什么?

例如,它查找你用#include 指令包含的所有头文件。

它还会查看你用#define 定义的每一个常量,并用它的实际值进行替换。

这只是一个开始,我提到这两个操作是因为它们是最常见的。预处理器可以做的事情还有很多。

你是否注意到#include#define 在开头有一个# ?那是所有预处理器指令的共同点。如果某一行以# 开始,预处理器就会处理这个问题。

条件式

我们可以做的一件事是使用条件语句来改变我们的程序的编译方式,这取决于一个表达式的值。

例如,我们可以检查DEBUG 常数是否为0。

#include <stdio.h>

const int DEBUG = 0;

int main(void) {
#if DEBUG == 0
  printf("I am NOT debugging\n");
#else
  printf("I am debugging\n");
#endif
}

符号常量

我们可以定义一个符号常量

#define VALUE 1
#define PI 3.14
#define NAME "Flavio"

当我们在程序中使用NAME或PI或VALUE时,在执行程序前,预处理器会将其名称替换为数值。

符号常量非常有用,因为我们可以给数值命名,而不需要在编译时创建变量。

通过#define ,我们也可以定义一个。宏和符号常量之间的区别是,宏可以接受一个参数,通常包含代码,而符号常量是一个值。

#define POWER(x) ((x) * (x))

注意参数周围的圆括号,这是一个很好的做法,可以避免在预编译过程中替换宏的问题。

然后我们可以在我们的代码中这样使用它。

printf("%u\n", POWER(4)); //16

与函数最大的区别是,宏不指定其参数或返回值的类型,这在某些情况下可能很方便。

如果定义了

我们可以用#ifdef 来检查一个符号常量或宏是否被定义。

#include <stdio.h>
#define VALUE 1

int main(void) {
#ifdef VALUE
  printf("Value is defined\n");
#else
  printf("Value is not defined\n");
#endif
}

我们也有#ifndef 来检查相反的情况(宏未定义)。

我们还可以使用#if defined#if !defined 来完成同样的任务。

将一些代码块包裹在这样一个块中是很常见的。

来暂时阻止它的运行,或者使用一个DEBUG符号常量。

#define DEBUG 0

#if DEBUG
  //code only sent to the compiler
  //if DEBUG is not 0
#endif

你可以使用的预定义符号常量

预处理器还定义了一些你可以使用的符号常量,由名称前后的2个下划线标识,包括。

  • __LINE__ 翻译为源代码文件中的当前行
  • __FILE__ 翻译为文件的名称
  • __DATE__ 翻译为编译日期,格式为Mmm gg aaaa
  • __TIME__ 翻译为编译时间,格式为hh:mm:ss