自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(51)
  • 收藏
  • 关注

原创 动态链接与动态库加载——程序世界的构建艺术

本文深入解析程序链接和内存管理的核心机制。静态链接部分揭示目标文件如何通过重定位表"相亲成功",将未识别的函数调用地址在链接时修正。虚拟地址机制展示了编译器与操作系统如何协作,通过ELF文件预先规划逻辑地址,并在进程创建时初始化内存结构。动态链接部分则呈现了共享库的精妙设计:地址无关代码、GOT/PLT协作机制实现延迟绑定,ld-linux作为"图书管理员"协调库共享,通过写时复制和缓存优化性能。这些机制共同构建了现代程序高效运行的基石,如同精心规划的城市系统,在资源

2025-07-13 02:33:33 738

原创 程序编译链接全景解析:从源代码到可执行文件

摘要:ELF文件是Linux系统下编译过程中的关键中间产物,主要包括可重定位文件(.o)、可执行文件、共享目标文件(.so)和内核转储文件。ELF文件由ELF头、程序头表、节头表和节区组成,其中.text节存储代码、.data节保存初始化变量、.bss节为未初始化变量预留空间。在链接过程中,多个.o文件的相同节区会被合并,最终形成可执行文件的段(segment)。操作系统加载程序时,会根据程序头表将不同权限的段映射到内存。理解ELF文件结构有助于解决编译和链接问题,通过readelf、objdump等工具可

2025-07-05 23:38:26 722

原创 程序库:代码复用的“魔法宝箱“——静态库与动态库

【程序库:开发者的魔法工具箱】程序库就像软件开发者的"魔法宝箱",提供可复用的代码工具,避免重复造轮子。静态库(.a/.lib)将代码打包进程序,独立性强但体积大;动态库(.so/.dll)运行时加载,节省空间但依赖环境。制作静态库需编译.o文件后用ar打包,动态库则需-fPIC位置无关码和-shared选项。使用库文件需指定路径(-L)和库名(-l),动态库还需设置LD_LIBRARY_PATH或放置到系统目录。合理运用库能显著提升开发效率,是程序员必备技能。

2025-07-04 14:42:16 883 1

原创 Linux--迷宫探秘:从路径解析到存储哲学

本文深入解析Linux文件系统的路径管理机制。首先揭示路径解析的递归本质:访问文件需从根目录逐层打开各级目录,形成完整路径。系统通过dentry结构在内存中构建路径缓存树,加速文件访问。其次探讨多分区挂载原理,说明跨分区路径统一性是通过挂载机制实现的。最后对比软硬链接的本质差异:硬链接共享inode,适用于防误删;软链接存储路径字符串,支持跨分区灵活管理。文章还分析了进程如何通过内核结构体维护文件系统视图,并解答了根目录inode编号为2等设计细节。整个文件系统设计体现了"共享与隔离"的

2025-06-21 14:18:56 623 1

原创 Linux--深入EXT2文件系统:数据是如何被组织、存储与访问的?

本文围绕 Linux 的 ext2 系列文件系统展开,先介绍文件系统需格式化硬盘才能存储文件,ext2 是常⻅类型,将分区划分为块组 。接着详述块组内部构成,含超级块、GDT、块位图等组件及功能 。还讲解 inode 和数据块映射、文件增删查改原理,以及目录与文件名的关系,阐明访问文件需通过目录文件映射inode号来实现,展现了 ext2 文件系统高效可靠的管理机制。

2025-06-16 08:00:00 907

原创 Linux--存储系统探秘:从块设备到inode

📝 Linux存储系统核心概念摘要 本文以生动比喻解析Linux存储系统的关键概念: 1️⃣ 块(Block) - 数据存储的基本单位(通常4KB),像乐高积木般组合文件内容,提升读写效率,即使小文件也至少占用一个块。 2️⃣ 分区(Partition) - 物理磁盘的逻辑划分,类比切蛋糕(如Windows的C/D盘),通过柱面编号确定边界,使用fdisk -l可查看分区详情。 3️⃣ inode - 文件的"身份证",存储元数据(大小、权限、时间戳等)而非文件名,每个inode号唯一

2025-06-15 19:35:49 882 3

原创 Linux--磁盘寻址:从 CHS 到 LBA 的深度解码之旅

本文聚焦 Linux 磁盘的 CHS 与 LBA 地址,先阐释文件系统核心作用及理解 Ext 文件系统的意义。从硬件世界(磁盘、服务器、机柜、机房)的协同,讲解磁盘物理结构,介绍 CHS 寻址的扇区、磁头、磁道、柱面概念,再引出 LBA 线性寻址,说明 CHS 与 LBA 相互转换公式及逻辑,展现磁盘寻址从物理到逻辑抽象的演进,帮助理解 Linux 磁盘数据存储与访问机制 。

2025-06-14 22:42:23 1156 5

原创 Linux--虚拟地址空间(一个故事理解)

本文深入解析了C语言程序中的虚拟地址空间布局及其管理机制。通过代码示例验证了程序运行时内存的五大分区:代码区(存储指令和常量)、数据区(全局/静态变量)、堆(动态分配内存)、栈(局部变量)以及命令行参数区。重点揭示了虚拟地址的本质——进程视角的地址与实际物理地址通过页表映射分离,解释了父子进程相同虚拟地址对应不同物理地址的现象。文章还通过"富豪与子女"的比喻生动说明了虚拟地址空间的工作原理,并详细介绍了Linux内核中mm_struct和vm_area_struct结构体的组织方式。最后

2025-06-13 00:37:00 578

原创 缓冲区(C语言缓冲区+内核缓冲区)一个例子解释他们的关系和作用!!!

本文详细探讨了C语言I/O操作中的缓冲区机制,通过代码示例解释了缓冲区对程序执行顺序的影响。主要内容包括:1. 缓冲区概念:类比菜鸟驿站解释缓冲区作用,包括用户空间缓冲区和内核缓冲区;2. 缓冲区类型:介绍全缓冲、行缓冲和无缓冲三种方式及其应用场景;3. FILE结构体:分析其作为用户空间与内核桥梁的关键字段和作用;4. 缓冲区刷新:通过fork示例说明不同设备(显示器和文件)的缓冲区差异;5. 实践验证:设计简化版libc库验证缓冲区机制。文章揭示了缓冲区如何优化I/O性能,以及理解缓冲区对调试程序的重要

2025-06-11 23:12:47 856

原创 Linux--基础IO(理解文件与用户之间交互的底层原理,小白都能学会)

本文围绕文件操作展开,先探讨printf输出本质,指出Linux下一切皆文件,文件操作本质是进程通过系统调用对硬件的IO操作。接着从狭义和广义角度解释文件概念,说明文件由内容和属性构成,空文件也占磁盘空间。然后介绍C语言文件接口,包括打开、读写文件等操作,以及stdin、stdout、stderr三个默认输入输出流。再阐述位图传递标记法及其优势,引出系统文件I/O接口,对比系统调用和库函数的区别。最后解释文件描述符fd的概念、分配规则和重定向原理,强调Linux“一切皆文件”的理念。

2025-06-10 21:24:59 606

原创 Linux--命令行参数和环境变量

摘要: 本文介绍了Linux命令行参数和环境变量的核心概念。命令行参数分为位置参数(无符号)和选项参数(-短选项/--长选项),并通过C语言示例展示了如何通过argc和argv获取参数。环境变量(如PATH、HOME)是系统级全局变量,用于配置运行环境,可通过echo、export等命令管理。重点解释了环境变量的继承机制:父进程(如bash)的环境变量表会传递给子进程,需用export设置全局变量。此外,程序可通过main的env参数、getenv()函数或全局变量environ获取环境变量。文中还探讨了P

2025-06-08 01:50:22 1050

原创 Linux--进程的调度

1.进程切换1.进程切换CPU上下⽂切换:其实际含义是任务切换, 或者CPU寄存器切换。当多任务内核决定运⾏另外的任务时, 它保存正在运⾏任务的当前状态, 也就是CPU寄存器中的全部内容。这些内容被保存在任务⾃⼰的堆栈中, ⼊栈⼯作完成后就把下⼀个将要运⾏的任务的当前状况从该任务的栈中重新装⼊CPU寄存器,并开始下⼀个任务的运⾏, 这⼀过程就是context switch。时间⽚:当代计算机都是分时操作系统,没有进程都有它合适的时间⽚(其实就是⼀个计数器)。

2025-06-07 01:26:47 632

原创 Linux--进程优先级

Linux进程优先级管理摘要:Linux系统中通过优先级(PRI)和nice值(NI)管理进程执行顺序。PRI越小优先级越高,NI作为修正值影响PRI(PRI(new)=80+NI),取值范围-20至19。用户可通过ps -l查看进程信息,使用renice或top命令调整NI值。系统支持多进程的竞争性(资源竞争)、独立性(互不干扰)、并行(多CPU同时运行)和并发(单CPU分时切换)特性。合理设置进程优先级和CPU绑定能显著提升系统性能。

2025-06-06 00:58:01 398

原创 Linux--进程的状态

本文摘要:进程状态模型包含创建、就绪、运行、阻塞、结束等核心状态,其转换受时间片耗尽、I/O等待等条件触发。Linux通过进程控制块(task_struct)管理进程信息,使用运行队列组织就绪进程。当内存不足时,系统会挂起进程或使用swap机制。进程状态包括运行(R)、睡眠(S)、磁盘休眠(D)、停止(T)等,可通过ps命令查看。僵尸进程(Z)是子进程退出后未被父进程回收的状态,会造成内存泄漏;孤儿进程则由init进程自动回收。文章详细阐述了进程状态转换、管理机制及其在Linux中的具体实现。

2025-06-06 00:43:11 922

原创 Linux--进程的程序替换

问题导入:前面我们知道了,fork之后,子进程会继承父进程的代码和“数据”(写实拷贝)。那么如果我们需要子进程完全去完成一个自己的程序怎么办呢?进程的程序替换来完成这个功能!

2025-06-04 02:12:43 879

原创 Linux--进程概念

本文摘要:进程是程序的执行实例,由内核分配系统资源。Linux系统通过PCB(task_struct结构体)管理进程,包含标识符、状态、优先级、程序计数器等信息。用户可通过/proc系统文件夹或工具(top、ps)查看进程信息。系统调用getpid()和getppid()可获取进程ID及其父进程ID。fork()系统调用用于创建子进程,具有两个返回值:父进程获取子进程PID,子进程获取0,便于区分执行逻辑。fork采用写时拷贝技术,父子进程共享代码但数据独立。

2025-06-02 21:32:26 1292 2

原创 Linux--操作系统(三个例子让你彻底理解操作系统!!!)

三个例子让你彻底理解操作系统!!!

2025-06-02 15:40:44 641

原创 Linux的调试器--gbd/cgbd

摘要:本文介绍了C程序调试的基本方法与技巧。首先说明在Linux下使用gcc/g++编译时需添加-g选项才能调试,对比了debug和release模式的区别。重点讲解了gdb/cgbd调试工具的使用,包括常用命令如list、run、next、step、breakpoint等操作说明,并分析了命令细节。文章还分享了三个调试技巧:1)使用watch监视变量变化;2)通过setvar修改变量值排查问题;3)设置条件断点的方法。最后通过求和程序示例演示了如何使用setvar修改标志位来验证程序逻辑。调试过程中保留调

2025-05-30 23:44:24 1202

原创 Linux 的编辑器--vim

本文介绍了Vim编辑器的基本使用与高级配置。主要内容包括:1)Vim与Vi的区别,Vim是Vi的升级版,支持语法高亮和多平台运行;2)Vim的三种基本模式(命令、插入、底行模式)及其切换方法;3)常用操作命令如光标移动、文本编辑、复制粘贴等;4)末行模式功能如查找替换、保存退出;5)批量注释技巧;6)针对C/C++开发的专业配置方案,包括插件管理、代码补全、调试工具等。通过系统配置,可将Vim打造成高效的编程IDE环境。

2025-05-25 22:42:23 2164

原创 C++ 11 (下)

本文介绍了C++11中的几个重要特性,包括可变参数模板、新的类功能、lambda表达式和包装器(function和bind)。可变参数模板允许定义接受任意数量参数的函数或类模板,通过参数包和包扩展机制实现。C++11新增了默认的移动构造函数和移动赋值运算符,并支持成员变量声明时提供缺省值。lambda表达式提供了一种简洁的匿名函数定义方式,支持捕捉外部变量,并可以用于替代仿函数和函数指针。包装器std::function和std::bind则提供了对可调用对象的统一封装和参数绑定功能,简化了代码的编写和维护

2025-05-20 00:27:40 892

原创 C++ 11 (上)

C++11是C++语言的一次重大更新,旨在解决C++98/03时代的局限性,如性能瓶颈、语法繁琐和并发支持缺失等问题

2025-05-15 23:30:58 963

原创 C++ 哈希表

哈希概念哈希概念哈希(hash)⼜称散列,是⼀种组织数据的⽅式。从译名来看,有散乱排列的意思。本质就是通过哈希函数把关键字Key跟存储位置建⽴⼀个映射关系,查找时通过这个哈希函数计算出Key存储的位置,进⾏快速查找。1 直接定址法当关键字的范围⽐较集中时,直接定址法就是⾮常简单⾼效的⽅法,⽐如⼀组关键字都在[0,99]之间,那么我们开⼀个100个数的数组,每个关键字的值直接就是存储位置的下标。

2025-05-10 22:21:56 1020

原创 C++ 红黑树

我们来介绍二叉搜索树家族的另一个成员,也是使用最广泛的成员。

2025-04-29 18:43:35 1404

原创 C++ AVL树的实现

在上一篇博客我们学习了二叉搜索树的实现,现在我们开始手动实现AVL树。

2025-04-27 23:52:19 747

原创 指针和数组

数组名是(地址不可修改),但比普通指针多出类型和长度信息的类型是int[5](包含元素类型和长度)在大多数表达式中退化为指针,值为&arr[0]怎么证明数组名是首元素的地址呢?这里我们做一个测试观察结果:可见这两个地址是相同的,所以得出数组名就是数组⾸元素(第⼀个元素)的地址。2.数组名和指针的区别由上面我们提到的,难道数组名和指针就是一样的吗?其实大多数情况下我们可以把数组名视为指针,但是有一些特殊情况我们需要举例出来。

2025-04-23 17:32:25 541

原创 二叉搜索树

树的结构中(结点)除了需要存储key还要存储对应的value,增/删/查还是以key为关键字⾛⼆叉搜索树的规则进⾏⽐较,可以快速查找到key对应的value。key/value的搜索场景实现的⼆叉树搜索树⽀持修改,但是不⽀持修改key,修改key破坏搜索树性质了,可以修改value。3.如果⽀持插⼊相等的值,插⼊值跟当前结点相等的值可以往右⾛,也可以往左⾛,找到空位置,插⼊新结点。替代N的意思就是N和R的两个结点的值交换,转⽽变成删除R结点,R结点符合情况2或情况3,可以直接删除。

2025-04-21 17:21:31 631

原创 Linux基础指令完全指南:从入门到熟练

Linux作为现代计算的核心操作系统之一,广泛应用于服务器、云计算、嵌入式设备及开发环境。掌握Linux基础指令是每个开发者、运维工程师和技术爱好者的必备技能。无论你是Linux初学者,还是希望巩固命令行操作的进阶用户,本文将带你系统学习最常用、最实用的Linux基础指令,涵盖:文件与目录操作(lscdmkdircpmvrm...)文本查看与编辑(catlessnanovim...)权限管理(chmodchownsudo...)进程与系统监控(pstophtopkill...)网络与工具(

2025-04-21 00:48:12 826

原创 C++ 多态

多态是面向对象编程的三大特性之一(封装、继承、多态),指同一操作作用于不同的对象时,会产生不同的行为。多态允许通过基类的接口操作派生类对象,实现代码的灵活扩展。

2025-04-15 15:25:21 864

原创 C++ 继承

场景举例:假设我们设计了两个类Student和Teacher,Student和Teacher都有姓名/地址/ 电话/年龄等成员变量,都有identity⾝份认证的成员函数,设计到两个类⾥⾯就是冗余的。当然他们也有⼀些不同的成员变量和函数,⽐如⽼师独有成员变量是职称,学⽣的独有成员变量是学号;学⽣的独有成员函数是学习,⽼师的独有成员函数是授课。下⾯我们公共的成员都放到Person类中,Student和teacher都继承Person,就可以复⽤这些成员,就不需要重复定义了,省去了很多⿇烦。1

2025-04-13 15:58:09 748

原创 C++ string类

先看begin和end他们是一个获取首位置,以获取尾位置,对于end来说它获取的位置为有效位的下一个。

2025-03-24 01:07:23 705

原创 C++ 模板初阶

1. 重载的函数仅仅是类型不同,代码复用率比较低,只要有新类型出现时,就需要用户自己增。函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生。如果类型不匹配,编译器会尝试进行隐式类型转换,如果无法转换成功编译器将会报错。2. 代码的可维护性比较低,一个出错可能所有的重载均出错。,那将会节省许多头发。巧的是前人早已将树栽好,我们只。类模板实例化与函数模板实例化不同,这叫做“麻烦道友,不麻烦贫道。,对于字符类型也是如此。函数的特定类型版本。,对于模板函数的使用,

2025-03-03 23:18:55 504

原创 C++ 内存管理

new/delete申请和释放的是单个元素的空间,new[]和delete[]申请的是连续空间,而且new在申。4. malloc的返回值为void*, 在使用时必须强转,new不需要,因为new后跟的是空间的类型。5. malloc申请空间失败时,返回的是NULL,因此使用时必须判空,new不需要,但是new需。3. malloc申请空间时,需要手动计算空间大小并传递,new只需在其后跟上空间的类型即可,

2025-03-02 23:42:12 841

原创 C++ 类和对象(下)

尽量使⽤初始化列表初始化,因为那些你不在初始化列表初始化的成员也会⾛初始化列表,如果这 个成员在声明位置给了缺省值,初始化列表会⽤这个缺省值初始化。静态成员变量不能在声明位置给缺省值初始化,因为缺省值是个构造函数初始化列表的,静态成员变量不属于某个对象,不⾛构造函数初始化列表。建议声明顺序和初始化列表顺序保持⼀致。C++11⽀持在成员变量声明的位置给缺省值,这个缺省值主要是给没有显⽰在初始化列表初始化的成员使⽤的。友元类的关系是单向的,不具有交换性,⽐如A类是B类的友元,但是B类不是A类的友元。

2025-02-24 21:54:58 912

原创 C++ 类和对象(中)

像Stack这样的类,虽然也都是内置类型,但 是_a指向了资源,编译器⾃动⽣成的拷⻉构造完成的值拷⻉/浅拷⻉不符合我们的需求,所以需要 我们⾃⼰实现深拷⻉(对指向的资源也进⾏拷⻉)。传值返回会产⽣⼀个临时对象调⽤拷⻉构造,传值引⽤返回,返回的是返回对象的别名(引⽤),没有产⽣拷⻉。没有显式实现时,编译器会⾃动⽣成⼀个默认赋值运算符重载,默认赋值运算符重载⾏为跟默认拷⻉构造函数类似,对内置类型成员变量会完成值拷⻉/浅拷⻉(⼀个字节⼀个字节的拷⻉),对⾃定义类型成员变量会调⽤他的赋值重载函数。

2025-01-22 17:22:02 1067

原创 数据在内存中的存储

具体的编译器),另外,对于位数⼤于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度⼤ 于⼀个字节,那么必然存在着⼀个如何将多个字节安排的问题。这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着⼀个字节,⼀个字节为8 bit 位,但是在C语⾔中除了8 bit 的 char。很多的ARM,DSP都为⼩端模式。是指数据的低位字节内容保存在内存的⾼地址处,⽽数据的⾼位字节内容,保存在内存的低地址处。是指数据的低位字节内容保存在内存的低地址处,⽽数据的⾼位字节内容,保存在内存的⾼地址处。

2025-01-13 21:11:59 700

原创 C语⾔内存函数

1.memcpy使⽤和模拟实现⽬录:1.memcpy使⽤和模拟实现2.memmove使⽤和模拟实现3.memset函数的使⽤4.memcmp函数的使⽤1.memcpy使⽤和模拟实现•函数memcpy从source的位置开始向后复制num个的数据到destination指向的内存位置。•这个函数在遇到 '\0'的时候并不会停下来。•如果source和destination有任何的重叠,复制的结果都是未定义的。对于重叠的内存,交给memmove来处理。2.

2025-01-12 20:56:56 375

原创 字符函数和字符串函数

C语⾔中有⼀系列的函数是专⻔做字符分类的,也就是⼀个字符是属于什么类型的字符的。上⾯的代码,我们将⼩写转⼤写,是-32完成的效果,有了转换函数,就可以直接使⽤。例题:写⼀个代码,将字符串中的⼩写字⺟转⼤写,其他字符不变。注意函数的返回值为 size_t,是⽆符号的( 易错 )。作为结束标志,strlen函数返回的是在字符串中。⽬标空间必须有⾜够的⼤,能容纳下源字符串的内容。⽬标空间必须⾜够⼤,以确保能存放源字符串。参数指向的字符串必须要以 '\0'会将源字符串中的 '\0'源字符串必须以 '\0'

2024-12-17 23:57:23 449

原创 C++ 类和对象(上)

再分析⼀下,对象中是否有存储指针的必要呢,Date实例化d1和d2两个对象,d1和d2都有各⾃独⽴的成员变量_year/_month/_day存储各⾃的数据,但是d1和d2的成员函数Init/Print指针却是⼀样的,存储在对象中就浪费了。这⾥需要再额外哆嗦⼀下,其实函数指针是不需要存储的,函数指针是⼀个地址,调⽤函数被编译成汇编指令[call 地址], 其实编译器在编译链接时,就要找到函数的地址,不是在运⾏时找,只有动态多态是在运⾏时找,就需要存储函数地址,这个我们以后会讲解。

2024-11-27 16:40:27 886

原创 C++ inline和nullptr

一 ,inline一 ,inline•⽤inline修饰的函数叫做内联函数,编译时C++编译器会在调⽤的地⽅展开内联函数,这样调⽤内联函数就需要建⽴栈帧了,就可以提⾼效率。•inline对于编译器⽽⾔只是⼀个建议,也就是说,你加了inline编译器也可以选择在调⽤的地⽅不展 开,不同编译器关于inline什么情况展开各不相同,因为C++标准没有规定这个。inline适⽤于频繁调⽤的短⼩函数,对于递归函数,代码相对多⼀些的函数,加上inline也会被编译器忽略。•。

2024-11-22 23:40:34 824

原创 C++(1)

在C/C++中,变量、函数和后⾯要学到的类都是⼤量存在的,这些变量、函数和类的名称将都存在于全 局作⽤域中,可能会导致很多冲突。使⽤命名空间的⽬的是对标识符的名称进⾏本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。c语⾔项⽬类似下⾯程序这样的命名冲突是普遍存在的问题,C++引⼊namespace就是为了更好的解决这样的问题。

2024-11-18 11:50:00 1045

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除