C++编程思想——编译与连接
2014-11-06 09:14
127 查看
编译与链接
昨天去面试的时候真心被好好的鄙视了一下,我感觉对不起编译原理的老师,发现我有太多的不懂,好好的做个总结。编译器
将源代码转化为汇编语言或机器指令。其实质是分为两步:1)对与处理过的代码进行词法分析、语法分析,生产语法树。
2)将语法树中的每个节点都转化为汇编语言或机器代码。也就是生产目标模块,以.o或者.obj为拓展名的文件。
拓展点:1)预处理。在C或者是C++中,都要对源代码进行预处理,利用程序员定义好的模式替换代码中的模式,主要是用来节省输入,增加代码的可读性。
2)在第一步与第二步中间会使用全局优化器生产更短、更快的代码。
3)这里注意声明与定义的区别,声明是告诉编译器函数或者变量的名字,而定义的话,编译器将会其分配空间。那么头文件就是一个含有某个库的外部声明函数和变量的文件。定义有的时候我们int a对于变量使用extern说明它只是一个声明。
链接器
将一组目标模块链接成一个可执行为文件,也就是操作系统可以装载和运行它。当某个目标模块中的函数要引用另一个目标模块中的函数或变量时,由链接器来处理这种引用。注意由于早期的链接器对目标文件和库文件只查找一次,因此目标文件和库文件的顺序特别重要。那么链接器如何查找库的呢?当C或C++要对函数和变量进行外部引用时,链接器如果还未遇到过这个函数或变量的定义,则将它的标识符加到“未解决的引用”列表中,那么它将会去查找库,对库的查找使用的是索引方式,它只浏览索引。然后将整个目标模块链接到可执行程序中,只是需要的模块,并不是整个库文件。对于已经遇到过的函数或者变量,就是已经解决的引用。
拓展:
1)链接器会添加一个目标模块来完成程序的启动任务。在创建应用程序项目时,集成开发环境会设置各种连接器开关,使得连接器将子系统的正确类型嵌入到最终生成的可执行文件中。操作系统会在链接时使用-entry:命令行选项来设置一个C/C++运行时的启动函数,该函数将初始化C/C++运行库,如此才能够使用malloc等函数。调用crtexe.c文件中的4个启动函数,其用途为:a.获取指向进程的完整命令行的一个指针;b.获取指向新进程的环境变量的一个指针;c.初始化运行库的全局变量;d.初始化C运行库内存分配函数和其它底层I/O例程使用的堆;e.调用所有全局和静态C++类对象的构造函数。
2)对于static以及extern分别使用内部链接以及外部链接。内部链接只对正被编译的文件创建存储空间,因此别的文件可以使用相同的标识符或者全局变量。每个标识符有单独的存储空间,它们之间并不会发生冲突。外部链接为所有编译过的文件创建一片单独的存储空间。全局变量和函数名有外部链接。当然你可以是用static强制它们具有内部链接。在调用函数时,局部变量知识存在堆栈中,链接器不知道自动变量,也就没有链接。
3)说说static作用:a.在函数体中其值不变;b.在模块内,被声明为静态的变量只能被模块内的函数访问。C.在模块内,声明为静态的函数只被该模块的其它函数调用
4)Static可以强制全局变量有内部链接,它就是一个static全局变量,只初始化一次,防止其在其它文件单元中被引用。它与普通函数的区别是,下一次会更根据上一次的结果,由上面的分析我们也不难得出。Static函数在内存中只有一份,而普通的函数在每个被调用中都维持一份复制品。
.
相关文章推荐
- C++编程思想--编译与解释
- C语言中的类模拟(C++编程思想)
- C++编程思想笔记之二
- C++编程思想(第2卷)之查找内存泄漏
- vc++程序编译连接时出现了unresolved external symbol错误
- C++编程思想VOL1
- Red Hat 9 Linux下编译sqlite-3.3.8并在QT3.1下连接全过程详细记录
- C++编程思想(第2卷)之深入探索string
- C++学习体会--预处理,编译过程,连接过程
- 《扩展和嵌入python解释器》1.5 编译和连接
- C++编程思想笔记之一
- Delphi中的包(一):关于exe的编译、连接和执行
- C++编程思想之SmartPoint
- C++编程思想(第2卷)之异常
- C++ 常见编译连接错误的解决!
- c++编程中的调试技巧(C++编程思想)
- 由2个和尚打水想到的---如何学习VB编程思想喝C++编程思想
- C语言中的类模拟(C++编程思想)(好文收藏)
- winarm可以编译连接调试了
- VC的一些编译连接选项