`
xinklabi
  • 浏览: 1591964 次
  • 性别: Icon_minigender_1
  • 来自: 吉林
文章分类
社区版块
存档分类
最新评论

C/C++编译过程理解

阅读更多

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

 

1.字符映射(Character Mapping)

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

 

2.行合并(Line Splicing)

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

 

3.标记化(Tokenization)

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

 

4.预处理(Preprocessing)

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

 

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

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

 

6.字符串连接(String Concatenation)

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

 

7.翻译(Translation)

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

 

8.处理模板

    处理模板实例。

 

9.连接(Linkage)

 

理解:

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

l        一直对这块内容都很怵头,因为它看不到摸不着,我们只能盯着最后编译链接之后的结果是成功或是失败,但是却不知道编译器内部是如何操作的;

l        每当编译器给出错误时我们都只是单纯的去处理错误,却不知道编译器是如何找出来的;

l        我们都很熟悉许多编译错误,但是却不大熟悉链接错误,对链接错误产生的原因也不大清楚。

 

今天,通过自己的努力终于对C/C++的编译过程有了个粗略的了解,毕竟不想去翻《编译原理》这样的大部头书籍,但是又急于对编译的过程有个大概的了解,唉,这么多年来一直在苦苦挣扎,今天总算是对这个过程有了个大概的了解了。下面就说说我了解到的一些东西:

    
首先是预编译,这一步可以粗略的认为只做了一件事情,那就是宏展开,也就是对那些#***的命令的一种展开,例如define MAX 1000就是建立起MAX1000之间的对等关系,好在编译阶段进行替换。例如ifdef/ifndef就是从一个文件中有选择性的挑出一些符合条件的代码来交给下一步的编译阶段来处理。这里面最复杂的莫过于include了,其实也很简单,就是相当于把那个对应的文件里面的内容一下子替换到这条include***语句的地方来。

其次是编译,这一步很重要,编译是以一个个独立的文件作为单元的,一个文件就会编译出一个目标文件。(这里插入一点关于编译的文件的说明,编译器通过后缀名来辨识是否编译该文件,因此“.h”的头文件一概不理会,而“.cpp”的源文件一律都要被编译,我实验过把.h文件的后缀名改为.cpp,然后在include的地方相应的改为***.cpp,这样一来,编译器就会编译许多不必要的头文件,只不过头文件里我们通常只放置声明而不是定义,因此最后链接生成的可执行文件的大小是不会改变的)清楚编译是以一个个单独的文件为单元的,这一点很重要,因此编译只负责本单元的那些事,而对外部的事情一概不理会,在这一步里,我们可以调用一个函数而不必给出这个函数的定义,但是要在调用前得到这个函数的声明(其实这就是include的本质,不就是为了给你提前提供个声明而好让你使用吗?至于那个函数到底是如何实现的,需要在链接这一步里去找函数的入口地址。因此提供声明的方式可以是用include把放在别的文件中的声明拿过来,也可以是在调用之前自己写一句void max(int,int);都行。),编译阶段剩下的事情就是分析语法的正确性之类的工作了。好啦,总结一下,可以粗略的认为编译阶段分两步:第一步,检验函数或者变量是否存在它们的声明;第二步,检查语句是否符合C++语法。

 

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

分享到:
评论

相关推荐

    高级C C++编译技术_[美]斯特瓦诺维奇著

    总之,《高级C/C++编译技术》是一本深度剖析C/C++编译过程和相关技术的书籍,对于想要提升编程技能、深入理解底层机制的开发者来说,是一本不可多得的参考文献。通过阅读这本书,读者不仅可以掌握编译器的工作原理,...

    C/C++ DevTools Support (DWARF)

    在C/C++编程中,DWARF信息使得开发者能够更容易地理解代码执行过程,追踪变量状态,定位错误源,以及进行复杂调试任务。 首先,我们需要理解DWARF的作用。DWARF信息嵌入在编译后的可执行文件或动态库中,包含了源...

    适合大一初学者的c/c++编译软件

    对于大一初学者来说,选择一个合适的C/C++编译软件是学习编程旅程的重要第一步。C和C++语言是计算机科学的基础,广泛应用于系统编程、游戏开发、嵌入式系统和高性能计算等领域。本资源包提供了简单易用的编译环境,...

    C/C++程序设计学习与实验系统

    这个安装包包含了所有必要的组件,使得用户可以在自己的计算机上建立一个功能完备的C/C++开发环境,进行程序编写、编译、调试和运行。 首先,我们要理解C和C++两种编程语言的基础。C语言是一种结构化的、低级的编程...

    反编译工具(DLL 转c/c++ 工具)

    标题中的“反编译工具(DLL 转 c/c++ 工具)”是指一类能够将动态链接库(DLL)文件转换为C或C++源代码的软件工具。DLL是Windows操作系统中的一种共享库,它包含可由多个程序同时使用的函数和资源。这种转换过程在...

    各种c/c++编译编译软件

    标题中的“各种C/C++编译器软件”指的是用于将C或C++源代码转换为可执行程序的工具。在编程领域,编译器是至关重要的...初学者可以通过尝试这些不同的编译器,找到最适合自己的那一个,从而更好地理解和掌握C/C++编程。

    Dev-cpp5.4.0及API帮助文档 2018年蓝桥杯C语言/c++

    【Dev-Cpp5.4.0】是一款轻量级的C/C++集成开发环境,它为程序员提供了方便的代码编辑、编译、调试等一体化功能。这个版本在2018年的蓝桥杯编程竞赛中被广泛使用,帮助参赛者进行C语言和C++程序的编写。 【C++API....

    ActiveMQ C/C++ 编译库需要的文件

    标题 "ActiveMQ C/C++ 编译库需要的文件" 提到的是关于使用ActiveMQ中间件在C或C++环境中构建通信库所需的一些关键组件。ActiveMQ是Apache软件基金会的一个开源消息传递系统,它实现了Java消息服务(JMS)规范,并...

    C/C++ 标准库函数 (中文版)

    预处理是C/C++编译过程的一个阶段,它在源代码被实际编译之前进行处理。预处理命令可以帮助程序员在程序编译前执行宏替换、条件编译、文件包含等操作。例如,#define命令用于宏定义,可以创建宏常量或宏函数。宏定义...

    android上安装c/c++编译环境

    总结一下,在Android设备上搭建C/C++编译环境涉及以下几个关键步骤: 1. 下载并安装Android NDK。 2. 配置环境变量,使系统能够找到NDK工具。 3. 在Android设备上安装Termux和必要的开发工具(GCC, G++)。 4. 如需...

    c/c++帮助文档中文

    这份"c/c++帮助文档中文"提供了丰富的中文资源,帮助开发者深入理解和掌握这两种语言。 C语言是最早由Dennis Ritchie在贝尔实验室设计的,它是一种底层语言,强调过程化编程,对内存管理有极高的控制权。C语言的...

    编程及C/C++初学者 FAQ

    - **高效性**:C/C++编译后的代码运行效率高,适用于对性能有较高要求的应用场景。 - **灵活性**:C/C++提供了底层硬件访问的能力,可以进行精细控制。 - **广泛应用**:许多操作系统、应用程序和游戏引擎都基于C/...

    C/C++程序编译Turbo C3.0

    下面我们将深入探讨C/C++程序编译过程以及Turbo C 3.0的使用方法。 一、C/C++编程基础 C语言是一种强大的、通用的、结构化的编程语言,它的语法简洁明了,适合编写系统级和应用级软件。C++则是在C语言的基础上增加...

    Mysql Connector C/C++ VS2013 编译(win32/win64)(附带示例代码)

    通过这个过程,你不仅学会了如何编译MySQL Connector/C++,还了解了如何在C++项目中使用这个库进行数据库操作。这将对你的C++数据库编程技能大有裨益,尤其是在Windows平台上。同时,这也为你提供了基础,以便将来能...

    C/C++程序员面试宝典

    在追求理想的职位过程中,深入理解和掌握C/C++语言的核心概念及应用技巧是至关重要的。 C/C++是两种广泛应用于系统级编程、游戏开发、高性能计算等领域的编程语言。C语言以其简洁高效著称,而C++则在此基础上增加了...

    linux c/c++基础学习资料(百度云链接和提取码)

    同时,理解环境变量、编译链接过程、动态库静态库的使用也是编程环境搭建的关键。此外,学会使用版本控制系统如Git进行代码管理也是现代开发者的必备技能。 然后是C/C++基础知识。C++是C语言的扩展,支持面向对象...

    精通Matlab与C/C++混合程序设计(第三版) 配套光盘

    它们是编译后的C/C++代码,可以直接在Matlab环境中运行,提供比Matlab内置函数更高的性能。学习创建和使用MEX文件是混合编程的基础。 3. **数据类型转换**:在Matlab与C/C++之间传递数据时,理解数据类型的转换至关...

    Microsoft(R) C/C++, Version 7.0

    《Microsoft(R) C/C++, Version 7.0:探索编程语言的里程碑》 在计算机科学领域,编程语言的发展历程犹如一部丰富多彩的历史长卷,而Microsoft(R) C/C++, Version 7.0无疑是其中浓墨重彩的一笔。这款在1990年代初期...

Global site tag (gtag.js) - Google Analytics