摘要:本文主要向大家介绍了C++语言编译与链接 -- 浅谈内部链接与外部链接,通过具体的内容向大家展示,希望对大家学习C++语言有所帮助。
本文主要向大家介绍了C++语言编译与链接 -- 浅谈内部链接与外部链接,通过具体的内容向大家展示,希望对大家学习C++语言有所帮助。
C++编译与链接 -- 编译与链接过程,大家知道计算机使用的一系列的1和0
那个一个C++语言程序又是如何从一个个.h和.cpp文件变成包含1和0的可执行文件呢?
可以认为有以下的几个环节
源程序->预处理->编译和优化->生成目标文件->链接->可执行文件
1.预处理
C++的预处理是指在C++程序源代码被编译之前,由预处理器对C++程序源代码进行的处理。这个过程并不对程序的源代码进行解析。
这里的预处理器(preprocessor)是指真正的编译开始之前由编译器调用的一个独立程序。
预处理器主要负责以下的几处
1.宏的替换
2.删除注释
3.处理预处理指令,如#include,#ifdef
如我们有以下代码
temp.h
#ifndef _HEADERNAME_H
#define _HEADERNAME_H 1
#include <iostream>
inline void show(char *a)
{
std::cout << a<< std::endl;//annotation
}
#endif</iostream>
main.cpp
#include "temp.h"
#define MACRO "This is a macro"
extern int i;
int main()
{
std::cout<<i<<std::endl; pre=""><p>a.cpp</p><pre class="brush:java;">#include <iostream>
int i=100;</iostream></pre>
<br>
<p>*在vs2013中可以使用“VS2013 开发人员命令提示”</p>
<p><img alt="\" src="/uploadfile/Collfiles/20180502/20180502094759766.png" style="width: 250px; height: 102px;"></p>
<p>使用cl /P main.cpp只进行预编译生成main.i文件<br>
<br>
*g++中可以使用(在以下只使用g++进行演示)<br>
<br>
g++ –E main.cpp>main.i命令<br>
<br>
g++ –E a.cpp>main.i<br>
<br>
打开生成的A.i文件<br>
<br>
我们发现<br>
<br>
1、show函数中的注释已经被删掉了</p>
<p><img alt="\" src="/uploadfile/Collfiles/20180502/20180502094759768.png" style="width: 630px; height: 79.8347px;"></p>
<p>2、main函数中的MACRO宏被替成了"this is a macro”<br>
<br>
windows vs下</p>
<p><img alt="\" src="/uploadfile/Collfiles/20180502/20180502094800769.png" style="width: 361px; height: 84px;"></p>
<p>3、temp.h和main.cpp中的#include<iostream> 和#include “temp.h”也在相应位置被展开了</iostream></p>
<p><img alt="\" src="/uploadfile/Collfiles/20180502/20180502094800770.png" style="width: 290px; height: 297px;"></p>
<p><strong>2.编译和优化</strong></p>
<p><img alt="\" src="/uploadfile/Collfiles/20180502/20180502094800771.png" style="width: 417px; height: 241px;"></p>
<p>词法分析 -- 识别单词,确认词类;比如int i;知道int是一个类型,i是一个关键字以及判断i的名字是否合法</p>
<p><br>
语法分析 -- 识别短语和句型的语法属性;</p>
<p>语义分析 -- 确认单词、短语和句型的语义特征;</p>
<p>代码优化 -- 修辞、文本编辑;</p>
<p>代码生成 -- 生成译文。</p>
<p>内联函数的替换就发生在这一阶段</p>
<p>在g++中可以使用</p>
<p>g++ -S将预处理阶段生成的.i文件生成相应的汇编文件</p>
<p>g++ –S main.i main.s</p>
<p>g++ –S a.i a.s</p>
<p>生成的部分代码如下:</p>
<p><img alt="\" src="/uploadfile/Collfiles/20180502/20180502094800773.png" style="width: 630px; height: 395.182px;"></p>
<p><strong>3.生成目标文件</strong></p>
<p>汇编过程实际上指把汇编语言代码翻译成目标机器指令的过程。</p>
<p>在最终的目标文件中</p>
<p>除了拥有自己的数据和二进制代码之外,还要至少提供2个表:未解决符号表和导出符号表,分别告诉链接器自己需要什么和能够提供什么。</p>
<p>编译器把一个cpp编译为目标文件的时候,除了要在目标文件里写入cpp里包含的数据和代码,还要至少提供3个表:未解决符号表,导出符号表和地址重定向表。<br>
未解决符号表提供了所有在该编译单元里引用但是定义并不在本编译单元里的符号及其出现的地址。<br>
导出符号表提供了本编译单元具有定义,并且愿意提供给其他编译单元使用的符号及其地址。<br>
地址重定向表提供了本编译单元所有对自身地址的引用的记录。</p>
<p>g++中可以使用g++ -c命令</p>
<p>g++ –c main.s –o main.o</p>
<p>g++ –c a.s –o a.o</p>
<p><strong>4.链接</strong></p>
<p>由汇编程序生成的目标文件并不能立即就被执行,其中可能还有许多没有解决的问题。例如,某个源文件中的函数可能引用了另一个源文件中定义的某个符号(如变量或者函数调用等);在程序中可能调用了某个库文件中的函数,等等。所有的这些问题,都需要经链接程序的处理方能得以解决。</p>
<p>g++ a.o main.o –o main.out</p>
<p>最终运行结果如下</p>
<p>100</p>
<p>This is a macro</p>
</i<<std::endl;>
本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标编程语言C/C+频道!
您输入的评论内容中包含违禁敏感词
我知道了
请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号