动态库和静态库的区别:
库(Library)在编程中是指一组预先编译好的代码和资源的集合,可以包含函数、变量、类、常量以及其他程序所需的模块。
根据使用方式和实现方式的不同,库可以分为两种主要类型:静态库和动态库。
-
静态库(Static Library)是在编译时被链接到目标程序中的库,它会被完整地复制到目标程序中,因此生成的可执行文件会比较大。静态库的优点是使用简单,不依赖于外部环境,但缺点是当多个程序同时使用同一个静态库时,会造成冗余,增加了可执行文件的大小。
-
动态库(Dynamic Library),也称为共享库(Shared Library),是在程序运行时被加载到内存中并链接的库,可被多个程序共享。动态库的优点是节约内存空间,减小可执行文件的大小,并且允许动态更新库的版本,但缺点是在运行时需要动态链接器加载库文件。
库的使用可以帮助开发者组织代码、提高代码的复用性和可维护性,同时也方便了代码的分享和分发。在编程中,库是一个非常重要的概念,可以帮助开发者更高效地完成各种任务。
问题:为什么动态库不会占用内存或者造成读写的问题?
动态库不会造成读写问题的主要原因在于动态库的加载和链接是在程序运行时进行的,而不是在编译时将库的代码静态地复制到可执行文件中。这种动态加载和链接的机制使得每个程序都可以在内存中独立地加载动态库,从而避免了多个程序同时访问和修改同一个库所造成的读写冲突问题。
具体来说,动态库在被加载时会由操作系统的动态链接器(如 Linux 中的 ld.so 或 Windows 中的 DLL)将库文件映射到程序的虚拟地址空间中,每个程序都会有自己独立的内存空间来存放动态库的代码和数据。这样,即使多个程序同时使用同一个动态库,它们也会在各自独立的内存空间中加载该库,互相之间不会发生读写冲突。
另外,动态库在内存中的代码和数据是共享的,即使多个程序同时使用同一个动态库,它们实际上共享同一个内存中的库实例。这种共享机制可以节约内存空间,并且动态库的更新也可以通过更新库文件来实现,不会影响已经运行的程序。
总的来说,动态库不会造成读写问题的关键在于动态加载和链接机制确保了每个程序都有独立的内存空间加载库,并且共享同一个库实例,从而避免了多个程序之间对同一库的读写冲突。这种机制使得动态库成为一种灵活、高效且安全的代码共享和重用方式。
为什么动态库没有归档?
动态库与静态库之间的一个重要区别。具体来说:
-
动态库没有归档:动态库(也称为共享库)是一种在运行时被加载到内存中并链接到程序中的库,不像静态库那样在编译时被静态地复制到可执行文件中。因此,动态库没有归档文件(如静态库中的
.a
文件),而是以一种特定的格式(如.so
文件在 Linux 系统中)存在于磁盘上,需要在程序运行时由动态链接器加载。 -
在编译过程中就要生成符号表:由于动态库在编译时不会被静态地链接到可执行文件中,而是在运行时动态加载,因此在编译动态库时就需要生成符号表。符号表包含了库中定义的函数、变量以及其他符号的信息,帮助编译器和链接器在程序编译和链接时正确地定位和解析这些符号。
综合起来,这句话强调了动态库在编译时不会被归档到可执行文件中,而是以一种动态加载的方式存在,并且在编译过程中需要生成符号表来描述库中的符号信息,以确保在程序运行时能够正确地加载和链接动态库。
预处理阶段
在开发过程中会根据实际需要,在源程序文件(特殊代码)中写入一些具有特殊能力,提供特殊功能,编译系统会对这些代码预先处理的过程称为“预处理”
C+程序中预处理一般分为三种预处理方法:宏定义,文件包含,条件编译
宏定义:常见的如:define,
#include<iostream>
#define PI 3.1415
int main()
{
int circle;
int r;
std::cin>>r;
circle=pi*r**2;
return 0
}
#undef PI
void function1()
{
...
}
也可以把宏定义放到头文件中去,
文件包含:文件包含会增加文件的长度
条件编译:在生成可执行文件的过程中,源程序文件中的所有代码行都参加编译,但有时候希望对其中的一部分内容只在满足一定的条件下才进行编译,也就是对一部分内容指定编译的条件,也有的时候,希望当满足某条件时对一组语句进行编译,而当条件不满足时编译另外一组语句,这都叫条件编译。使用的情况,条件编译可以减少代码的编译量或者进行跨平台开发的时候使用