【转帖】C++编译原理 资料

摘要:
好吧,综上所述,我们可以大致认为编译阶段分为两个步骤:第一步是检查函数或变量是否有它们的声明;第二步是检查语句是否符合C++语法。标准C和C++将编译过程定义为9个阶段:1。字符映射文件中的物理源字符映射到源字符集,包括替换三个字符运算符和替换控制字符。在C++程序中,任何不在基本源字符集中的字符都会被其通用字符名替换。C++双字符运算符被识别为标记。上述四个阶段统称为预处理阶段。

转自:http://blog.csdn.net/shiwenbin333/article/details/5157797

首先是预编译,这一步可以粗略的认为只做了一件事情,那就是“宏展开”,也就是对那些#***的命令的一种展开。

      例如define MAX 1000就是建立起MAX和1000之间的对等关系,好在编译阶段进行替换。

      例如ifdef/ifndef就是从一个文件中有选择性的挑出一些符合条件的代码来交给下一步的编译阶段来处理。这里面最复杂的莫过于include了,其实也很简单,就是相当于把那个对应的文件里面的内容一下子替换到这条include***语句的地方来。

      其次是编译,这一步很重要,编译是以一个个独立的文件作为单元的,一个文件就会编译出一个目标文件。(这里插入一点关于编译的文件的说明,编译器通过后缀名来辨识是否编译该文件,因此“.h”的头文件一概不理会,而“.cpp”的源文件一律都要被编译,我实验过把.h文件的后缀名改为.cpp,然后在include的地方相应的改为***.cpp,这样一来,编译器就会编译许多不必要的头文件,只不过头文件里我们通常只放置声明而不是定义,因此最后链接生成的可执行文件的大小是不会改变的)

      清楚编译是以一个个单独的文件为单元的,这一点很重要,因此编译只负责本单元的那些事,而对外部的事情一概不理会,在这一步里,我们可以调用一个函数而不必给出这个函数的定义,但是要在调用前得到这个函数的声明(其实这就是include的本质,不就是为了给你提前提供个声明而好让你使用吗?至于那个函数到底是如何实现的,需要在链接这一步里去找函数的入口地址。因此提供声明的方式可以是用include把放在别的文件中的声明拿过来,也可以是在调用之前自己写一句void max(int,int);都行。),编译阶段剩下的事情就是分析语法的正确性之类的工作了。好啦,总结一下,可以粗略的认为编译阶段分两步:    

        第一步,检验函数或者变量是否存在它们的声明;

        第二步,检查语句是否符合C++语法。

最后一步是链接,它会把所有编译好的单元全部链接为一个整体文件,其实这一步可以比作一个“连线”的过程,比如A文件用了B文件中的函数,那么链接的这一步会建立起这个关联。链接时最重要的我认为是检查全局空间里面是不是有重复定义或者缺失定义。这也就解释了为什么我们一般不在头文件中出现定义,因为头文件有可能被释放到多个源文件中,每个源文件都会单独编译,链接时就会发现全局空间中有多个定义了。

标准C和C++将编译过程定义为9个阶段(Phases of Translation):

1.字符映射(Character Mapping)

    文件中的物理源字符被映射到源字符集中,其中包括三字符运算符的替换、控制字符(行尾的回车换行)的替换。许多非美式键盘不支持基本源字符集中的一些字符,文件中可用三字符来代替这些基本源字符,以??为前导。但如果所用键盘是美式键盘,有些编译器可能不对三字符进行查找和替换,需要增加-trigraphs编译参数。在C++程序中,任何不在基本源字符集中的字符都被它的通用字符名替换。

2.行合并(Line Splicing)

    以反斜杠/结束的行和它接下来的行合并。

3.标记化(Tokenization)

    每一条注释被一个单独的空字符所替换。C++双字符运算符被识别为标记(为了开发可读性更强的程序,C++为非ASCII码开发者定义了一套双字符运算符集和新的保留字集)。源代码被分析成预处理标记。

4.预处理(Preprocessing)

    调用预处理指令并扩展宏。使用#include指令包含的文件,重复步骤1到4。上述四个阶段统称为预处理阶段。

5.字符集映射(Character-set Mapping)

    源字符集成员、转义序列被转换成等价的执行字符集成员。例如:'/a'在ASCII环境下会被转换成值为一个字节,值为7。

6.字符串连接(String Concatenation)

    相邻的字符串被连接。例如:"""hahaha""huohuohuo"将成为"hahahahuohuohuo"。

7.翻译(Translation)

    进行语法和语义分析编译,并翻译成目标代码。

8.处理模板

    处理模板实例。

9.连接(Linkage)

    解决外部引用的问题,准备好程序映像以便执行。

免责声明:文章转载自《【转帖】C++编译原理 资料》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇CentOS 7下Cloudera Manager及CDH 6.0.1安装过程详解uboot和内核波特率不同下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Delphi7中 string, AnsiString, Utf8String,WideString的区别分析(转)

Windows系统上的 Notepad.exe 打开文件后,点击“文件”菜单中的“另存为”命令,会跳出一个对话框,在最底部有一个“编码”的下拉条。里面有四个选项:ANSI,Unicode,Unicode big endian 和 UTF-8。1)ANSI是默认的编码方式。对于英文文件是ASCII编码,对于简体中文文件是GB2312编码(只针对Windows...

截断字符串,取指定长度字符(中英文通用)

vs2008 设计页:                                           <asp:TemplateField>                                                <ItemTemplate>                               ...

字符串、对象、数组操作方法、json方法

1.字符串操作方法                 1.charAt               *     作用              *         通过索引找字符              *     语法              *         字符串.charAt(index)              *     参数   ...

性能分析工具gprof介绍

转载自: http://blog.chinaunix.net/uid-25194149-id-3215487.html 还有另外一个介绍的博客: http://blog.csdn.net/cbbbc/article/details/44629171 Ver:1.0目录1.    GPROF介绍    42.    使用步骤    43.    使用举例  ...

Autoit安装及启动

1、Autoit下载:   官网下载地址:https://www.autoitscript.com/site/autoit/downloads/   提供百度网盘下载:https://pan.baidu.com/s/17l5fOlz_ZHjoHxnQwiQBYA(如果链接失效,请在评论中索要,会在评论中再次给出) 2、Autoit安装:   安装教程一般百...

安装caffe碰到的坑(各种.so未找到)

./include/caffe/common.hpp:4:32: fatal error: boost/shared_ptr.hpp: 没有那个文件或目录 所有类似于上面的错误,都可以用如下格式来解决: 解决方案:出现该错误的原因是少了依赖。 在命令行输入: $ sudo apt-get install --no-install-recommends li...