预处理 命令可以改变程序设计环境,提高编程效率,它们并不是 C 语言本身的组成部分,不能直接对 它们进行编译,必须在对程序进行编译之前,先对程序中这些特殊的命令进行“预处理” 。经过预处理后,程序就不再包括预处理命令了,最后再由编译程序对 预处理 之后的源程序进行 编译 处理,得到可供执行的目标代码。C 语言提供的预处理功能有三种,分别为 宏定义、文件包含和条件编译。

如果想知道预处理后最终的代码,可以通过 GCC 来查看。

0x01 测试用的代码

  1. 文件名为 main.c
1
2
3
4
5
6
7
8
9
#define MAXN 100

int main() {
int a[MAXN];
for (int i = 0; i < MAXN; i++) {
scanf("%d", &a[i]);
}
return 0;
}

0x02 用 gcc 命令对测试用的代码进行预处理(不编译)

  1. 通过以下指令对 main.c 文件进行预处理,并输出到 test.log 中。

    1
    gcc -E main.c -o test.log
  1. test.log 中的内容

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    # 1 "main.c"
    # 1 "<built-in>" 1
    # 1 "<built-in>" 3
    # 362 "<built-in>" 3
    # 1 "<command line>" 1
    # 1 "<built-in>" 2
    # 1 "main.c" 2


    int main() {
    int a[100];
    for (int i = 0; i < 100; i++) {
    scanf("%d", &a[i]);
    }
    return 0;
    }

    能看到 main.c 源文件中的 MAXN 都被替换成了 100

0x03 来点稍微复杂的预处理看看

  1. 源程序文件名为 main.c

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #define MAXN 100
    #define FOR(id,size) for(int id = 0; id < (size); id++)
    #define MUL(i,j) i*j
    #define MUL2(i,j) (i)*(j)

    int main() {
    int a[MAXN];
    FOR(i, MAXN) {
    scanf("%d", &a[i]);
    }
    MUL(2,3+4);
    MUL2(2,3+4);
    return 0;
    }
  2. 接下来看看预处理之后的源代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    # 1 "main.c"
    # 1 "<built-in>" 1
    # 1 "<built-in>" 3
    # 362 "<built-in>" 3
    # 1 "<command line>" 1
    # 1 "<built-in>" 2
    # 1 "main.c" 2





    int main() {
    int a[100];
    for(int i = 0; i < (100); i++) {
    scanf("%d", &a[i]);
    }
    2*3+4;
    (2)*(3+4);
    return 0;
    }
  3. 分析: 这里我们发现,预处理其实就是对 C 语言的源程序进行替换。预处理只是编译时的东西,而不是运行时的。而且这里仅仅是对文本进行替换,就算程序不能通过编译,也可以通过预处理的。