虽然学习CI得到了我的第一个主题这是令牌。 当我看到这个代码是很容易得到的图片。
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>
是一个令牌。 如果是的话,它应该是一个关键词吧?
在行
#include <stdio.h>
#include
是预处理器指令。 <stdio.h>
是预处理器的附加信息。 在这种情况下,它指定一个文件名, stdio.h
,其内容将被包括在文件的正是该位置被处理编译。
包含亲处理器指令中的线由预处理器处理并从源代码创建对象代码时决不会被编译器看到。
这里的C关键字信息的列表,根据最新的在线标准草案 ,第6.4.1节:
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),与关于预处理指令一些加上强调的阶段:
物理源文件的多字节字符被映射,在一个实现定义的方式,向源字符集(引入终了行指标新行字符),如果必要的。 三字母序列是由相应的单字符的内部表示替换。
反斜线字符(的每个实例\
)紧跟一个新行字符被删除,拼接物理源极线,以形成逻辑源极线。 只有在任何物理源行的最后一个反斜杠有资格是这样一个接头的一部分。 源文件,它是不为空应在新行字符,这不应由反斜杠字符被立即前面任何这样的剪接发生之前结束。
源文件被分解成预处理标记7)和空白字符(包括注释)序列。 源文件不应在部分预处理标记或在部分评论结束。 每个注释都被一个空格字符替代。 换行字符将被保留。 是否比新行其他空白字符的每个非空序列被保持或由一个空格字符替换是实现定义。
预处理指令被执行,宏调用展开, _Pragma
一元运算符表达式的执行 。 如果一个通用字符名称的语法相匹配的字符序列通过令牌级联(6.10.3.3)中产生,则该行为是未定义的。 甲#include
预处理指令导致从第1阶段至第4阶段处理指定的头或源文件,递归。 然后,所有预处理指令都将被删除。
每个源字符集构件和逃避字符常数和字符串被转换为执行字符集的相应构件序列; 如果没有相应的部件,它被转换为比空(宽)字符以外的实现所定义的部件。 8)
相邻的字符串文字令牌是连接在一起。
空白字符分隔标记不再显著。 每个预处理标记转换成令牌 。 将得到的令牌语法和语义分析,并翻译成翻译单元。
所有外部对象和函数引用解决。 库组件链接到满足于功能的外部引用和对象不是在当前转换定义。 所有此类翻译输出被收集到含有所需的在其执行环境的执行信息的节目的图像。
基本上,级1到4描述了预处理器的操作。 这基本上按摩源文本之前,它是由编译器翻译。
你会想读第6.4节,了解预处理程序标记和普通标记之间的差异。