在学习C的同时,我得到了第一个主题是令牌。当我看到这段代码时很容易得到图片。
int main()
{
int x, y, total;
x = 10, y = 20;
total = x + y;
printf ("Total = %d \n", total);
}
到目前为止一直很好......现在我在这里看一下这个:
#include <stdio.h>
int main()
{
/* code */
printf("Hello C world! \n");
return 0;
}
我想知道#include
中的#include <stdio.h>
是否是令牌。如果是,它应该是关键字吗?
答案 0 :(得分:3)
在第
行#include <stdio.h>
#include
是预处理器指令。 <stdio.h>
是预处理器的附加信息。在这种情况下,它指定一个文件名stdio.h
,其内容将被准确地包含在正在处理的文件的编译位置。
包含前处理器指令的行由预处理器处理,编译器在从源代码创建目标代码时从未看到过。
答案 1 :(得分:1)
根据最新的online draft standard,第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节)的各个阶段,并重点强调了预处理程序指令:
物理源文件多字节字符在实现定义中映射 方式,源字符集(引入换行符) 如有必要,可以使用终端指标。 Trigraph序列被替换为 相应的单字符内部表示。
反斜杠字符(\
)的每个实例后面紧跟一个换行符
删除字符,拼接物理源行以形成逻辑源行。
只有任何物理源代码行的最后反斜杠才有资格成为其中一部分
这种拼接。非空的源文件应以换行符结尾,
在任何此类之前不得立即使用反斜杠字符
拼接发生。
源文件被分解为预处理标记 7) 和序列 空格字符(包括注释)。源文件不得以a结尾 部分预处理令牌或部分注释。每条评论都被替换为 一个空格字符。保留换行符。是否每个都是空的 新行以外的空白字符序列被保留或替换为 一个空格字符是实现定义的。
执行预处理指令,扩展宏调用,以及
执行_Pragma
一元运算符表达式。如果是一个字符序列那个
匹配通用字符名称的语法由token生成
连接(6.10.3.3),行为未定义。 #include
预处理
指令导致从阶段1处理命名的头文件或源文件
通过阶段4,递归。然后删除所有预处理指令。
每个源字符集成员和转义序列的字符常量和 字符串文字转换为执行字符的相应成员 组;如果没有相应的成员,则转换为实现定义的成员 除null(宽)字符以外的成员。 8)
连接相邻的字符串文字标记。
分隔标记的空白字符不再重要。的每个 预处理令牌转换为令牌。由此产生的代币是 语法和语义分析并翻译为翻译单元。
解析所有外部对象和函数引用。库组件是 链接以满足对未定义的函数和对象的外部引用 目前的翻译。所有这样的翻译器输出被收集到程序图像中 其中包含在其执行环境中执行所需的信息。
基本上,阶段1到阶段4描述了预处理器的动作。它基本上是在编译器翻译之前对源文本进行按摩。
您希望阅读第6.4节,以了解预处理程序令牌和常规令牌之间的区别。