一文说清:C静态库与动态库的区别

一 前言

大家在用C语言编程时,一定会遇到各种库,它们为开发者提供了大量的预编译函数和数据结构,从而极大地提高了软件开发的效率。

在C语言中,库主要分为两种类型:

  • 静态库(Static Library):通常具有.a或.lib的扩展名。
  • 动态库(Dynamic Library):在Windows系统中通常具有.dll(Dynamic Link Library)的扩展名,在类Unix系统中则通常具有.so(Shared Object)的扩展名。

这两种库在程序链接、加载和执行过程中有着不同的行为和特点。本文将详细探讨C语言中静态库和动态库的区别。
以printf函数作为库为例。

二 区别

区别1

静态库在目标文件链接成可执行文件阶段,库函数(库函数本身有一个代码段)链接进可执行文件(代码段)中,占了很大的内存空间。

而使用动态库时,只是在链接时做了一个printf的标记,当可执行程序运行时才会加载这段printf(从库路径中加载动态链接库.so文件),这样就节省了可执行程序的空间,只有在运行这段很短的时间会占用可执行程序的空间。

可以做个测试,写一个输出hello world的小程序,一般是Linux下gcc中是默认是使用动态库的,可以看到可执行程序a.out的大小只有7千多k,而使用静态库,链接后生成可执行程序时把printf也链接到了可执行程序中,这时候可执行程序就有700多K了。

区别2

使用动态库对库的依赖性太强,一般发布的话需要库文件(库文件要放在相应的库路径中)也发布。

静态链接库对库的依赖性不会有那么强。

静态库就像房车,出门旅游不用依赖住房,但是房车占空间。
动态库就像小车,出门旅游依赖要住酒店,但是小车省空间。

实际上使用动态库在运行的时候加载printf也会占用可执行程序,在运行时占用可执行程序的空间其实是跟静态库是一样的。

但是试想:一个可执行程序a.out中有多个文件(如a应用程序,b应用程序,c文件程序),a,b,c都需要调用printf。

使用静态库时,链接时就链接了三份printf,运行时就加载三份printf,产生多分副本,白白浪费内存。

而使用动态库时,链接时,只是将printf的标记链接进了可执行程序a,out,运行时printf只用加载一份,a调用时就是调用这一份printf,b调用时也是调用这一份printf。这才是动态库相对于静态库真正的优势!

三 总结

1 静态库

  • 链接时将程序放进可执行程序
  • 会产生多份副本
  • 不依赖程序运行

2 动态库

  • 程序运行时,才去加载动态库找函数
  • 多进程共享
  • 依赖程序运行

大家是不是清晰一些了?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/886240.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux服务器定时执行jar重启命令

1. sh脚本编写 appNamecvcp-weather PIDps -ef |grep java | grep $appName | grep -v grep | awk {print $2} if [ "$PID" "" ]; thensleep 1;echo "no process";elseecho "process exsits";kill -9 $PID fi sleep 2s nohup /usr/l…

eclipse mat leak suspects report和 component report的区别

在 Eclipse Memory Analyzer Tool (MAT) 中,Leak Suspects Report 和 Component Report 是两种不同的分析报告,用于帮助开发者查找和诊断内存问题,但它们关注的方面有所不同: 1. Leak Suspects Report: • 主要用于识…

5G CPE:为什么活动会场与商铺的网络成为最新选择

在快节奏的现代社会中,无论是举办一场盛大的活动还是经营一家繁忙的商铺,稳定的网络连接都是不可或缺的基石。然而,面对复杂的布线难题或高昂的商业宽带费用,许多场所往往陷入两难境地。幸运的是,5G CPE(Cu…

React-redux 实战案例,自定义useSelector

创建一个新的 React 工程,并配置 Redux 和 Ant Design,你可以按以下步骤操作。我将使用 create-react-app 脚手架工具来快速创建一个基于 TypeScript 的 React 项目 1. 创建新项目 使用 create-react-app 创建一个新的 React 项目,带 TypeS…

vue 获取摄像头拍照,并旋转、裁剪生成新的图片

描述&#xff1a; vue项目中&#xff0c;获取摄像头进行拍照&#xff0c;并对拍摄的图片进行旋转、裁剪等处理 html部分 <!-- 摄像头列表 --> <el-select v-model"autoVal" size"small" change"change(auto, true)"><el-option…

【C++】list 类深度解析:探索双向链表的奇妙世界

&#x1f31f;快来参与讨论&#x1f4ac;&#xff0c;点赞&#x1f44d;、收藏⭐、分享&#x1f4e4;&#xff0c;共创活力社区。 &#x1f31f; 如果你对string&#xff0c;vector还存在疑惑&#xff0c;欢迎阅读我之前的作品 &#xff1a; 之前文章&#x1f525;&#x1…

uniapp如何i18n国际化

1、正常情况下项目在代码生成的时候就已经有i18n的相关依赖&#xff0c;如果没有可以自行使用如下命令下载&#xff1a; npm install vue-i18n --save 2、创建相关文件 en文件下&#xff1a; zh文件下&#xff1a; index文件下&#xff1a; 3、在main.js中注册&#xff1a…

VScode-Java开发常用插件

中文——界面易读 字体主题——代码可观 头注释——项目信息明了 java开发包——java必备 git协作开发——版本控制

面向对象入门

面向对象 面向对象&#xff1a;编程思维 python一切皆对象 17.1 面向对象思想 编程思维2种 面向过程 代表语言&#xff1a;C语言 优点&#xff1a;对于小型程序开发效率非常高 缺点&#xff1a;不适应当前的主流大型项目当需要解决一个问题的时候&#xff0c;更关注开发的每…

前端(3)——快速入门JaveScript

参考&#xff1a; 罗大富 JavaScript 教程 | 菜鸟教程 JavaScript 教程 1. JaveScript JavaScript 简称 JS JavaScript 是一种轻量级、解释型、面向对象的脚本语言。它主要被设计用于在网页上实现动态效果&#xff0c;增加用户与网页的交互性。作为一种客户端脚本语言&#…

redis7.x源码分析:(1) sds动态字符串

sds(Simple Dynamic String)是redis中最基础也是最重要的数据结构之一&#xff0c;其内部使用的key、协议、回复等等都会用它来存储。sds主要设计被用来替代C原生字符串 char *&#xff08;数组&#xff09;&#xff0c;以便更便捷、更高效、更安全的进行字符串操作管理。其实它…

FRP 实现内网穿透

如何通过 FRP 实现内网穿透&#xff1a;群晖 NAS 的 Gitea 和 GitLab 访问配置指南 在自建服务的过程中&#xff0c;经常会遇到内网访问受限的问题。本文将介绍如何利用 FRP&#xff08;Fast Reverse Proxy&#xff09;来实现内网穿透&#xff0c;以便在外网访问群晖 NAS 上的…

我们来学mysql -- EXPLAIN之select_type(原理篇)

EXPLAIN之select_type 题记select_type 题记 书接上文《 EXPLAIN之ID》2024美国大选已定&#xff0c;川普剑登上铁王座&#xff0c;在此过程中出谋划策的幕僚很重要&#xff0c;是他们决定了最终的执行计划在《查询成本之索引选择》中提到&#xff0c;explain的输出&#xff0…

uni-app快速入门(五)--判断运行环境及针对不同平台的条件编译

一、判断运行环境 在实际项目开发中&#xff0c;经常需要进行开发环境和生产环境的切换&#xff0c;uni-app可根据process.env.NODE_ENV判断当前运行环境是开发环境和生产环境&#xff0c;根据不同的环境调用不同的后台接口&#xff0c;具体实现方式: 在项目的static目录下建…

北京大学c++程序设计听课笔记101

基本概念 程序运行期间&#xff0c;每个函数都会占用一段连续的内存空间。而函数名就是该函数所占内存区域的起始地址&#xff08;也称“入口地址”&#xff09;。我们可以将函数的入口地址赋给一个指针变量&#xff0c;使该指针变量指向该函数。然后通过指针变量就可以调用这个…

离散:消解与归结规则的使用 例子详细分析

我们来详细分析一下这个逻辑表达式&#xff1a; \[(p \vee r) \land (q \vee r)\] 首先&#xff0c;我们回顾一下析取&#xff08;OR&#xff09;和合取&#xff08;AND&#xff09;运算的基本性质&#xff1a; 1. **析取&#xff08;OR&#xff09;**: \(A \vee B\) 为真当且…

构建客服知识库:企业效率提升的关键步骤

客服知识库是企业提升客户服务效率和质量的重要工具。它不仅帮助客服团队快速准确地回答客户问题&#xff0c;还能通过数据分析来优化服务流程和提升客户满意度。 1. 明确知识库的目标和范围 构建客服知识库的第一步是明确其目标和范围。这包括确定知识库的主要用户群体、需要…

Linux运维工程师推荐学习的开发语言

前言&#xff1a;会开发的运维和不会开发的运维可以说是两个世界的运维。 个人推荐python和go&#xff0c;前者可以做自动化运维&#xff0c;后者可以深挖k8s&#xff1b;最近就不先演示运维服务技术的部署和架构搭建了&#xff0c;在深挖自动化运维&#xff0c;为了让现在的工…

整合seata遇到的问题

自己遇到的问题&#xff0c;记录一下。 1、版本问题 我seata用的是1.7&#xff0c; 数据库驱动是 <dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>8.0.31</version><scope>…

Android View 调用基础 通用属性基础 方法场景说明

调用基础 一般常用的方法和属性说明一下情况1.坐标系getX和getY 相对于父布局getTranslationX和getTranslationY 偏移量getRawX和getRawY 相对于屏幕原点 2.margin3.setTag 存储额外的数据 我都有哪些场景需要使用 简单记录下1.更新所有Viewgroup下的View 一般常用的方法和属性…