C++面试题整理:1.声明与定义的区别,内部链接与外部链接,静态链接与动态链接

引言

从源码到可执行程序,经过了编译、链接这两个过程

  • 编译:将用户的源码编译成若干目标模块;展开来讲编译分为三步编译预处理(处理一些#定义的命令或语句)、编译(语法语义分析)、汇编(汇编指令翻译成机器指令)
  • 链接:将若干目标模块和所需的库函数链接在一起,生成可执行程序

二者的区别:

  • 编译过程,检查程序的语法以及函数、变量是否声明,如果函数未声明,编译器会给出警告,但是会生成目标文件
  • 链接过程,在目标文件中找寻函数的实现,如果未找到就会报链接错误码

1 声明 与 定义

1.1声明

将一个名称引入程序。

1.声明一个函数:void fun(int a, int b);
2.声明一个变量:extern int a;
3.声明一个类:class A;
4.声明一个类的静态成员变量:class A{…;static int a;…}
5.声明类型的别名:typedef int INT;

1.2定义

提供了一个实体在程序中的唯一描述。

1.定义一个类的静态成员变量:int A::a = 0;
2.定义一个类的(非内联)成员函数:int A::fun(){return a;}

1.3声明和定义同时存在

大多数情况下声明和定义是同时存在的

1.int a;
2.extern int a = 0;

1.4 声明和定义的区别

在一个给定的作用域内,声明可以有多次,定义只能有一次。但是类中的函数和静态成员变量只能声明一次

2 内部链接与外部链接

2.1编译单元

当一个c或者cpp程序在编译时,会递归其头文件,形成一个含有必要信息的源文件,这个源文件就是一个编译单元。

2.2内部链接

如果一个名称对于它的编译单元而言是局部的,不与其他编译单元相同的名称冲突,那么这个名称具有内部链接。
下面的名称是内部链接:

1.所有的声明
2.命名空间中的静态自由函数(自由函数是指该函数不是类的成员函数,也不是友元函数)、静态友元函数、静态变量的定义
3.枚举定义
4.内联函数的定义
5.类的定义
6.命名空间中const常量定义
7.union定义

2.3 外部链接

在一个多文件程序中,如果一个名称在链接时可以与其他编译单元交互,那么这个名称就有外部链接。
外部链接的名称:

1.类的非内联函数,包括类的成员函数和静态成员函数
2.类的静态成员变量定义。(一定要和声明区分开,声明都是内部链接)
3.命名空间中的非静态自由函数、非静态友元函数、非静态变量

2.4 总结

1.inline函数总有内部链接,不论这个函数是什么函数,在类中的函数也是如此,所以inline函数最好放在头文件中,每一个包含头文件的函数都能够找到inline函数
2.类定义总有内部链接,而非inline类成员函数总有外部链接,不论这个成员函数是静态、虚拟还是一般成员函数,类的静态数据成员定义总有外部链接
3.命名空间中的静态自由函数,静态友元函数,静态变量,const常量定义都有内部链接
4.声明、enum定义、union定义有内部链接

3 静态链接 和 动态链接

二者的区别在于链接的时机不一样,

  • 静态链接:在形成可执行程序之前
  • 动态链接:在程序执行的过程中

3.1 静态链接

将需要调用的函数或者过程链接到可执行文件中,成为可执行程序的一部分,也就是说函数和过程的代码就在exe文件中,该文件包含了运行中的全部代码。

优缺点:

  • 浪费空间,因为每个可执行程序中都有一份其所需目标文件的拷贝,如果多个可执行程序对同一个目标文件有依赖,那该目标文件在内存中就有多个副本
  • 更新困难,如果库函数的代码修改了,就需要重新编译链接形成可执行程序
  • 运行速度快,因为可执行程序中已经具备了程序运行需要的所有东西

3.2 动态链接

动态链接就是为了解决静态链接存在浪费空间、更新困难的弊端而出现的。
动态链接是将程序按照模块拆分成相对独立的部分,在程序运行时,才将他们链接在一起形成完整的程序

优缺点:

  • 同一个目标文件在内存中只有一份
  • 更新方便,只需将原来的目标文件替换即可,无需将所有的程序重新链接
  • 运行速度会降低,因为在运行可执行程序的过程中需要进行链接

3.4 如何选择

如果系统中有多个应用程序使用这个库,就把它编译成动态库,这样在启动的时候加载比较慢,但是多任务的时候会节省内存;
如果系统中只有一到两个应用程序使用该库,并且使用的API比较少,就编译成静态库,这样应用程序可能会比较大,但是启动速度快。

参考:
https://blog.51cto.com/zhanglianpin/1675069

https://blog.csdn.net/kang___xi/article/details/80210717?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章