#include是关键字类型的标记吗?

虽然学习CI让我的第一个主题是令牌。 当我看到这段代码时很容易得到图片。

int main() { int x, y, total; x = 10, y = 20; total = x + y; printf ("Total = %d \n", total); } 

到目前为止这么好……现在我在这里看一下这个:

 #include  int main() { /* code */ printf("Hello C world! \n"); return 0; } 

我想知道#include 中的#include 是否是一个令牌。 如果是的话,它应该是关键字吗?

在线

 #include  

#include是一个预处理器指令。 是预处理器的附加信息。 在这种情况下,它指定一个文件名stdio.h ,其内容将被准确地包含在正在处理以进行编译的文件的那个位置。

包含前处理器指令的行由预处理器处理,编译器在从源代码创建目标代码时从不会看到这些行。

以下是根据最新的在线草案标准第6.4.1节的C关键字列表:

 auto if unsigned break inline void case int volatile char long while const register _Alignas continue restrict _Alignof default return _Atomic do short _Bool double signed _Complex else sizeof _Generic enum static _Imaginary extern struct _Noreturn float switch _Static_assert for typedef _Thread_local goto union 

#include指令不是上述关键字的C语言语法的一部分; 它是一个预处理指令,在它被送入编译器之前从源文本中删除。

以下是将C代码从源文本转换为机器代码的过程(第5.1.1.2节),并对预处理程序指令进行了一些重点介绍:

  1. 如果需要,物理源文件多字节字符以实​​现定义的方式映射到源字符集(引入行尾指示符的换行符)。 Trigraph序列由相应的单字符内部表示替换。

  2. 将删除紧跟着换行符的每个反斜杠字符( \ )实例,拼接物理源行以形成逻辑源行。 只有任何物理源线上的最后一个反斜杠才有资格成为这种拼接的一部分。 非空的源文件应以换行符结尾,在进行任何此类拼接之前,该换行符不应立即以反斜杠字符开头。

  3. 源文件被分解为预处理标记7)和空白字符序列(包括注释)。 源文件不应以部分预处理标记或部分注释结束。 每个注释都被一个空格字符替换。 保留换行符。 是否保留或替换为新行以外的每个非空白字符序列是由实现定义的。

  4. 执行预处理指令,扩展宏调用,并执行_Pragma一元运算符表达式 。 如果通过标记连接(6.10.3.3)生成与通用字符名称的语法匹配的字符序列,则行为未定义。 #include预处理指令使得命名的头文件或源文件以递归方式从阶段1到阶段4进行处理。 然后删除所有预处理指令。

  5. 字符常量和字符串文字中的每个源字符集成员和转义序列都将转换为执行字符集的相应成员; 如果没有相应的成员,则将其转换为除null(宽)字符以外的实现定义的成员。 8)

  6. 相邻的字符串文字标记是连接的。

  7. 分隔标记的空白字符不再重要。 每个预处理令牌都转换为令牌 。 由此产生的标记在语法和语义上进行分析并翻译为翻译单元。

  8. 解析所有外部对象和函数引用。 链接库组件以满足对当前转换中未定义的函数和对象的外部引用。 所有这样的翻译器输出被收集到程序映像中,该程序映像包含在其执行环境中执行所需的信息。

基本上,阶段1到4描述了预处理器的动作。 它基本上在编译器翻译之前对源文本进行按摩。

您需要阅读第6.4节以了解预处理器令牌和常规令牌之间的区别。