HaveFunWithEmbeddedSystem/Chapter2 C与C++/2.3 编译原理.md

38 lines
3.3 KiB
Markdown
Raw Normal View History

# 2.3 编译原理
2018-07-05 00:53:06 +08:00
很多人误以为编译是一个过程,实际上,编译一个 C/C++ 程序分为编译和链接两个过程。
## 2.3.1 编译与连接
编译型语言的源码是不能被直接执行的,只有满足特定处理器架构要求的机器码才能被 CPU 执行。将程序源码转变成机器码的过程称为编译,这个过程会生成扩展名为“.o”的目标文件。
2018-07-05 00:53:06 +08:00
通常,一个编译后的程序仍然是不能独立执行的,人们还引入了静态链接库、动态链接库、共享库等,程序需要依赖于这些库才能运行。更多的时候则是依赖于,来自于同一项目的其他源码文件所对应的目标文件。
2018-07-05 00:53:06 +08:00
+ 程序A
+ 目标文件1.o <- 源码1.cpp
+ 目标文件2.o <- 源码2.c
+ B.dll
+ C.dll
+ D.dll
一旦程序编译分为了两个步骤,我们就要区分在编译和链接过程中产生的问题,如果能定位到编译错误或者链接错误,将帮助我们缩小问题的范围。例如:在编译过程中,找不到某个符号的定义,那么很有可能是忘记了引用相关的头文件,或是忘记了声明;而如果是在链接过程中找不到某符号,则有可能是忘记告诉编译器要链接哪些额外的库了。
2018-07-05 00:53:06 +08:00
## 2.3.2 链接库
本文不打算更深入的讲解编译和链接的原理,但是静态库、动态库、共享库等内容确实值得进行一些介绍。
库程序的存在是有特殊意义的。首先,库程序极大的简化了开发程序的复杂度——你可以直接使用某些已经实现的功能,而不必亲自去编写它;其实,那些广泛使用的库程序,他们通常经过了严格的测试,和大量的验证,某些 bug 早已被发掘并修复,因此,库程序要比自己编写的相同功能的程序更稳定可靠;最后,库程序极大的减少了系统中程序的重复率,哪些经常要被很多程序使用到的功能,被封装到一个共享库中,这减少了程序所占的存储空间。
## 2.3.3 静态库、共享库和动态库
库可以有三种使用的形式:静态、共享和动态。
静态库的代码在编译和链接时就已复制到程序中,其执行不依赖于库文件的存在,执行效率高,但是生成的程序体积大;
共享库并没有被编译和链接到程序中,而是在程序运行时才载入,在编译时,只是简单地指定需要使用的库函数,程序的运行依赖于共享库,但其生成的程序体积相对较小;
动态库是共享库的另一种变化形式。动态库同样在程序运行时载入,但与共享库不同的是,库函数不是在程序运行开始就加载,而是在程序中的语句需要使用该函数时才载入,在程序执行完库函数后释放动态库,腾出内存空间供其它程序使用。动态库不仅优化了程序的存储空间,也优化了程序运行时所需的内存空间,但是其执行效率没有静态库高,并且程序的执行同样依赖于库文件。
2018-07-08 23:34:27 +08:00
## 练习
将个位数的加减乘除运算编写成动态库,每个库函数的输入是类似于"3+9=“这样的字符串。在另一个程序中调用这些库函数,记录并判断用户输入的合法性,将用户输入传递给库函数,得到库函数返回的结果后,调用输出程序将结果打印出来。