编译 C 程序——幕后
预处理器是一种系统软件(一种设计用于在计算机硬件和应用程序上运行的计算机程序)。它执行高级语言(HLL)的预处理。预处理是语言处理系统的第一步。语言处理系统将高级语言翻译成机器级语言或绝对机器码(即机器可以理解的形式)。
- 预处理器不知道 C 的范围规则。像#define 这样的预处理器指令在看到它们后立即生效,并一直有效到包含它们的文件末尾;程序的块结构无关紧要。
预处理器主要对 HLL 代码执行三个任务:
- 删除注释:它删除所有注释。只为人们理解代码而编写注释。因此,很明显它们对机器没有用处。因此,预处理器将它们全部删除,因为它们在执行中不需要并且也不会被执行。这是如何在 linux 中查看已删除注释的文件):
编写 C 代码(让文件名为prog.c)。使用命令gcc -E prog.c对其进行预处理
您将看到没有注释的代码的输出。
- 此文件以“.i”扩展名 (prog.i) 保存,该扩展名将输入到编译器。
- 文件包含:包括我们程序需要的库中的所有文件。在 HLL 中,我们编写#include,它是预处理器的指令,告诉它包含指定的库文件的内容。例如,#include
将告诉预处理器包含库文件 stdio.h 中的所有内容。
这也可以使用双引号来编写 – #include “stdio.h”
注意:如果文件名包含在尖括号内,则在标准编译器包含路径中搜索文件。如果文件名包含在双引号中,则搜索路径将扩展为包括当前源目录。 - 宏扩展:宏可以作为小函数调用,处理开销不大。如果我们必须编写一个需要递归调用(一次又一次)的函数(定义很小),那么我们应该更喜欢宏而不是函数。
因此,定义这些宏是由预处理器完成的。
#define SI 1000
是一个简单的宏示例。
- 有两种类型的宏:类对象(不带参数)和类函数(可以带参数)
// object-like macro
#define
// function-like macro
#define ()
您可以使用#undef 删除宏定义:
// 删除宏
# undef我们可以写出类似函数的多行宏,但每条语句都以“\”结尾。
#include <stdio.h>
#define MACRO(num, str) {\
printf("%d", num);\
printf(" is");\
printf(" %s number", str);\
printf("\n");\
}