- C++ 程序编译过程
- 链接
- 联编
- 静态绑定和动态绑定
- C和C++的区别
- Java 和 C++ 的区别
- Python 和 C++ 的区别
编译过程分为四个过程:编译预处理、编译(编译、优化),汇编,链接。
- 编译预处理:预编译主要处理源代码中的伪指令,引入头文件,去除注释,处理所有的条件编译指令,宏的替换,添加行号,保留所有的编译器指令。
- 编译、优化:编译过程所进行的是对预处理后的文件进行语法分析,词法分析,语义分析,符号汇总,然后将源码 .cpp 文件翻译成 .s 汇编代码。
- 汇编:汇编过程将汇编代码转成二进制文件,二进制文件就可以让机器来读取。在这里会形成符号表,给这些符号会分配虚拟地址。将汇编代码 .s 翻译成机器指令 .o 文件。
- 链接:汇编程序生成的目标文件,即 .o 文件,并不会立即执行,因为可能会出现:.cpp 文件中的函数引用了另一个 .cpp 文件中定义的符号或者调用了某个库文件中的函数。那链接的目的就是将有关的目标文件彼此相连接,也即将在一个文件中引用的符号同该符号在另外一个文件中的定义连接起来,使得所有的这些目标文件成为一个能够被操作系统装入执行的统一整体。
静态链接:在编译的时候将库文件里面代码搬迁到可执行的文件中。代码从其所在的静态链接库中拷贝到最终的可执行程序中,在该程序被执行时,这些代码会被装入到该进程的虚拟地址空间中。
动态链接:执行的时候需要转换到库文件代码执行。代码被放到动态链接库或共享对象的某个目标文件中,链接程序只是在最终的可执行程序中记录了共享对象的名字等一些信息。在程序执行时,动态链接库的全部内容会被映射到运行时相应进行的虚拟地址的空间。
二者的优缺点比较:
- 静态的链接产生的可执行的文件体积比较的大,浪费空间、更新困难(每个可执行程序都会有目标文件的一个副本,这样如果目标文件进行了更新操作,就需要重新进行编译链接生成可执行程序);而动态链接的可执行文件的体积比较小,节省内存、更新方便。
- 动态的链接的编译的效率比较的高;静态链接相对较低。
- 静态链接的可执行的文件执行的效率高(因为可执行程序具备了程序运行的所有内容);动态链接相对较低(程序运行时,每次执行都需要链接,相比静态链接会有一定的性能损失)。
联编就是将模块或者函数合并在一起生成可执行代码的处理过程,同时对每个模块或者函数调用分配内存地址,并且对外部访问也分配正确的内存地址,它是计算机程序彼此关联的过程。
静态联编:是指在编译阶段就将函数实现和函数调用关联起来,也叫早绑定。在编译阶段就必须确定程序中的操作调用(如函数调用)与执行该操作代码间的关系(束定)。静态联编对函数的选择是基于指向对象的指针或者引用的类型。其优点是效率高,缺点是灵活性差。C语言中,所有的联编都是静态联编。
动态联编:是指在程序执行的时候才将函数实现和函数调用关联,也叫运行时绑定或晚绑定。动态联编对函数的选择不是基于指针或者引用,而是基于对象类型,不同的对象类型将做出不同的编译结果。优点是灵活性强,缺点是效率低。
C++中一般情况下联编也是静态联编,但是一旦涉及到多态和虚函数就必须要使用动态联编了。动态联编规定,只能通过指向基类的指针或基类对象的引用来调用虚函数,其格式为:指向基类的指针变量名->虚函数名(实参表)或基类对象的引用名.虚函数名(实参表)。
实现动态联编需要同时满足以下三个条件:
- 必须把动态联编的行为定义为类的虚函数。
- 类之间应满足父子型关系,通常表现为一个类从另一个类公有派生而来。
- 必须先使用基类指针指向子类型的对象,然后直接或者间接使用基类指针调用虚函数。
静态类型和动态类型:
- 静态类型:变量声明时的类型,在编译阶段确定。静态类型不能更改。
- 动态类型:目前所指对象的类型,在运行阶段确定。动态类型可以更改。
静态绑定和动态绑定:
- 静态绑定是指程序在 编译阶段 确定对象的类型(静态类型)。
- 动态绑定是指程序在 运行阶段 确定对象的类型(动态类型)。
静态绑定和动态绑定的区别:
- 发生的时期不同:如上。
- 对象的静态类型不能更改,动态类型可以更改。
对于类的成员函数,只有虚函数是动态绑定,其他都是静态绑定。
C和C++的区别面向对象和面向过程:
面向过程的思路:分析解决问题所需的步骤,用函数把这些步骤依次实现。
面向对象的思路:把构成问题的事务分解为各个对象,建立对象的目的,不是完成一个步骤,而是描述某个事务在解决整个问题步骤中的行为。
区别和联系:
- 语言自身:C 语言是面向过程的编程,它最重要的特点是函数,通过 main 函数来调用各个子函数。程序运行的顺序都是程序员事先决定好的。C++ 是面向对象的编程,类是它的主要特点,在程序执行过程中,先由主 main 函数进入,定义一些类,根据需要执行类的成员函数,过程的概念被淡化了(实际上过程还是有的,就是主函数的那些语句),以类驱动程序运行,类就是对象,所以我们称之为面向对象程序设计。面向对象在分析和解决问题的时候,将涉及到的数据和数据的操作封装在类中,通过类可以创建对象,以事件或消息来驱动对象执行处理。
- 应用领域:C 语言主要用于嵌入式领域,驱动开发等与硬件直接打交道的领域,C++ 可以用于应用层开发,用户界面开发等与操作系统打交道的领域。
- C++ 既继承了 C 强大的底层操作特性,又被赋予了面向对象机制。它特性繁多,面向对象语言的多继承,对值传递与引用传递的区分以及 const 关键字,等等。
- C++ 对 C 的“增强”,表现在以下几个方面:类型检查更为严格。增加了面向对象的机制、泛型编程的机制(Template)、异常处理、运算符重载、标准模板库(STL)、命名空间(避免全局命名冲突)。
二者在语言特性上有很大的区别:
- 指针:C++可以直接操作指针,容易产生内存泄漏以及非法指针引用的问题;Java并不是没有指针,虚拟机(JVM)内部还是使用了指针,只是编程人员不能直接使用指针,不能通过指针来直接访问内存,并且Java增加了内存管理机制。
- 多重继承:C++支持多重继承,允许多个父类派生一个类,虽然功能很强大,但是如果使用的不当会造成很多问题,例如:菱形继承;Java不支持多重继承,但允许一个类可以继承多个接口,可以实现C++多重继承的功能,但又避免了多重继承带来的许多不便。
- 数据类型和类:Java 是完全面向对象的语言,所有函数和变量部必须是类的一部分。除了基本数据类型之外,其余的都作为类对象,包括数组。对象将数据和方法结合起来,把它们封装在类中,这样每个对象都可实现自己的特点和行为。而 C++ 允许将函数和变量定义为全局的。
垃圾回收:
- Java语言一个显著的特点就是垃圾回收机制,编程人员无需考虑内存管理的问题,可以有效的防止内存泄漏,有效的使用空闲的内存。
- Java 所有的对象都是用 new 操作符建立在内存堆栈上,类似于 C++ 中的 new 操作符,但是当要释放该申请的内存空间时,Java 自动进行内存回收操作,C++ 需要程序员自己释放内存空间,并且 Java 中的内存回收是以线程的方式在后台运行的,利用空闲时间。
应用场景:
- Java 运行在虚拟机上,和开发平台无关,C++ 直接编译成可执行文件,是否跨平台在于用到的编译器的特性是否有多平台的支持。
- C++ 可以直接编译成可执行文件,运行效率比Java高。
- Java 主要用来开发 Web 应用。
- C++ 主要用在嵌入式开发、网络、并发编程的方面。
- 语言自身:Python 为脚本语言,解释执行,不需要经过编译;C++ 是一种需要编译后才能运行的语言,在特定的机器上编译后运行。
- 运行效率:C++ 运行效率高,安全稳定。原因:Python 代码和 C++ 最终都会变成 CPU 指令来跑,但一般情况下,比如反转和合并两个字符串,Python 最终转换出来的 CPU 指令会比 C++ 多很多。首先,Python 中涉及的内容比 C++ 多,经过了更多层,Python 中甚至连数字都是 object ;其次,Python 是解释执行的,和物理机 CPU 之间多了解释器这层,而 C++ 是编译执行的,直接就是机器码,编译的时候编译器又可以进行一些优化。
- 开发效率:Python 开发效率高。原因:Python 一两句代码就能实现的功能,C++ 往往需要更多的代码才能实现。
- 书写格式和语法不同:Python 的语法格式不同于其 C++ 定义声明才能使用,而且极其灵活,完全面向更上层的开发者。



