自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 从C到C++语法过度1

本文介绍了C++相较于C语言在语法层面的主要改进:1)引入原生字符串类型string,简化了字符串操作;2)新增引用类型作为变量别名;3)提供更安全的新式类型转换(static_cast、const_cast等);4)赋予auto关键字自动类型推导功能。这些特性使C++代码更简洁、安全和高效,尤其体现在字符串处理、类型转换和模板编程中。文章通过代码示例详细对比了新旧语法差异,展示了C++对C语言的扩展与优化。

2025-06-08 13:51:01 1042

原创 C++概念以及基础框架语法

C++是由C语言发展而来的高性能编程语言,诞生于1983年,兼具C语言的高效特性和面向对象等现代编程范式。它在游戏、动画、浏览器、数据库、操作系统等性能敏感领域广泛应用。C++学习曲线陡峭但威力强大,其基础程序结构包含头文件、名字空间和标准输入输出等要素。使用g++或交叉工具链编译C++程序,可直接操作硬件并获得卓越性能。作为计算机编程领域的"重装武器",C++在底层系统和算法核心开发中扮演着不可替代的角色。

2025-06-08 13:34:48 485

原创 数据结构与算法-AVL树

这棵“畸形”的二叉树虽然依旧是一棵标准的BST,但却已经明显左轻右重了,事实上这棵二叉树已经退化成了一条链表,在这棵BST中搜索某一节点的时间复杂度跟链表是一样的。这种“左轻右重”或者“左重右轻”的长短腿的情形,就是所谓的不平衡,一棵树如果不平衡,那么他的搜索性能将会受到影响,具体来讲:当树保持平衡时,其搜索时间复杂度是𝑂(𝑙𝑜𝑔2𝑛)Olog2​n),当树退化成链表时,其搜索时间复杂度变成𝑂(𝑛)On),其他情况下树的平均搜索时间复杂度就介于这两者之间。

2025-05-08 20:25:47 802

原创 数据结构与算法-树、二叉树与BST

对于BST而言,插入一个节点主要是要保持其“小-中-大”的逻辑不变,因此插入的节点的逻辑可以从根节点开始,一步步寻找新节点的“最终归宿”,比如在如下BST中,要插入新节点16,最终应该插入到节点17的左孩子处。由于在顺序存储,数据元素之间的逻辑关系是用物理位置来表达的,而二叉树中每一个节点都有一个对应的标号,因此可以使用标号来作为数组的下标,但除非是完美或者完全二叉树,否则会浪费存储空间,如下图所所示。其中8是根节点,14是10的右孩子(因为二叉树是有序树,因此严格区分左右),而13则是14的左孩子。

2025-05-07 22:44:01 822

原创 数据结构与算法-栈和队列

顺序存储的队列之所以被称为循环队列,是因为可以利用更新队头队尾的下标信息,来循环地利用整个数组,出队入队时也不必移动当中的数据。从上图可以看到,链式队列主要控制队头和队尾,由于管理结构体中保存了当前队列元素个数size,因此可以不必设计链表的头节点,初始化空队列时只需要让队头队尾指针同时指向空即可。不管是顺序栈,链式栈,栈的操作逻辑都是一样的,但由于存储形式不同,代码的实现是不同的。队列是最常见的概念,日常生活经常需要排队,仔细观察队列会发现,队列是一种逻辑结构,是一种特殊的线性表。

2025-05-07 21:26:28 335

原创 数据结构与算法-内核链表

因为对每一种不同的数据,所构建出来的链表都是跟这些数据相关的,所有的操作函数也都是数据密切相关的,换一种数据节点,则所有的操作函数都需要一一重写编写,这种缺陷对于一个具有成千上万种数据节点的工程来说是灾难性的。在普通链表的节点设计中,不同的链表所使用的指针不同,就直接导致操作函数的参数不同,在C语言的环境下,无法统一这些所有的操作,这给编程开发带来了很大的麻烦,尤其在节点种类众多的场合。接着,将这样的不含任何数据的链表,镶嵌在具体要用串起来的数据节点之中,这样一来,就可以将任何节点的链表操作完全统一了。

2025-04-26 18:02:46 735

原创 数据结构与算法-容器中的双向链表

在链表中查找某个节点也是一种常规操作,但查找操作与上述的增删操作有个很大的不同,节点的比对是跟节点本身数据密切相关的,比如整型数据可以直接使用等号来判断是否一致,而字符串则需要通过特定的函数才能判断,至于结构体,则无法使用任何现成的方式去判定,只能由用户根据其实际数据去判定。由于C语言没有类,也不支持重载,受语言本身特性的限制,一般不使用第一种办法来设计通用容器,但在一些小型程序中,C语言也是可以实现通用性的,关键在于:让用户提供数据的类型。由于增删操作都涉及用户具体的数据,因此需要对之前的操作作出修改。

2025-04-17 22:02:45 968

原创 数据结构与算法-双链表

数据结构与算法双链表

2025-04-16 21:09:50 1242

原创 数据结构与算法-单链表

链式存储中,所有节点的存储位置是随机的,他们之间的逻辑关系用指针来确定,跟物理存储位置无关。增删数据都非常迅速,不需要移动任何数据。另外,又由于位置与逻辑关系无关,因此也无法直接访问某一个指定的节点,只能从头到尾按遍历的方式一个个找到想要的节点。由于头结点是不存放有效数据的,因此如果空链表中带有头结点,那么头指针 head 将永远不变,这会给以后的链表操作带来些许便捷。由于链表中的各个节点被离散地分布在各个随机的内存空间,因此销毁链表必须遍历每一个节点,释放每一个节点。

2025-04-15 23:03:19 1163

原创 数据结构与算法-顺序表

顺序表的基本概念、基本操作以及优缺点。

2025-04-14 23:10:02 795

原创 并发编程--线程调度及优先级与信号处理

由于多线程程序中的线程的执行状态是并发的,因此当一个进程(注意不是线程)收到一个信号时,那么究竟由进程中的哪条线程响应这个信号就是不确定的,取决于哪条线程刚好在信号达到的瞬间被调度,这种不确定性在程序逻辑中一般是不能接收的。在Linux中,线程是系统的调度实体,Linux是抢占式内核,意味着线程在占用CPU运行时并不是高枕无忧的,而是可以被所谓高优先级的其他任务抢占,这就引出了优先级的基本概念。系统默认的静态优先级是0,即普通任务,如果要将程序将默认的优先级设置为非零,那么启动是必须加。

2025-04-13 09:00:00 1745

原创 并发编程--线程池

一个基本事实是,线程的创建和销毁都是需要额外的系统资源的,如果线程的生命周期很短,那么相对于实际干活的时间,来回重复创建和销毁就显得很不划算,但也不能让线程执行完任务之后耗着不走,因此就需要一个比较科学合理的布局,来管控线程,一个比较成熟的方案是:在上述情况下,将线程放入一个类似缓冲区的。线程池的基本想法,是将许多线程,放置一个池子中(实际就一个结构体),只要有任务,就将任务投入池中,这些线程们通过某些机制,及时处理这些任务。而任务都被放入一个链表,被互斥锁保护起来。

2025-04-13 09:00:00 1449

原创 并发编程--条件量与死锁及其解决方案

在许多场合中,程序的执行通常需要满足一定的条件,条件不成熟的时候,任务应该进入睡眠阻塞等待,条件成熟时应该可以被快速唤醒。上述做法实际上相当于现实生活中的立遗嘱,因为人去世之后是无法再做任何事情的,因此为了防止死亡在关键阶段意外到来,可以在提前立遗嘱,万一不幸遇到该情况就有了预案(注意,上述表述中,条件和条件量是两个不同的东西,所谓条件就是指程序要继续运行所需要的前提条件,比如文件是否读完、内存是否清空等具体的场景限定。死锁指的是由于某种逻辑问题,导致等待一把永远无法获得的锁的困境。

2025-04-12 21:07:53 894

原创 并发编程--互斥锁与读写锁

互斥与同步是最基本的逻辑概念:使得多线程间互斥运行的最简单办法,就是增加一个互斥锁。任何一条线成要开始运行互斥区间的代码,都必须先获取互斥锁,而互斥锁的本质是一个二值信号量,因此当其中一条线程抢先获取了互斥锁之后,其余线程就无法再次获取了,效果相当于给相关的资源加了把锁,直到使用者主动解锁,其余线程方可有机会获取这把锁。定义互斥锁是一个特殊的变量,定义如下:一般而言,由于互斥锁需要被多条线程使用,因此一般会将互斥锁定义为全局变量。初始化与销毁未经初始化的互斥锁是无法使用的,初始化互斥锁有两种办法:静态

2025-04-12 20:54:41 1169 2

原创 并发编程--POSIX信号量

并发编程中的POSIX信号量

2025-04-11 22:28:25 1068

原创 并发编程--线程的属性

由于线程属性众多,因此需要的时候不直接设置,而是先将它们置入一个统一的属性变量中,然后再以此创建线程。这些属性可以在创建线程的时候,通过属性变量统一设置,有少部分可以在线程运行之后再进行设置(比如分离属性),下面介绍属性变量如何使用。默认情况下,线程启动后处于可接合状态(即未分离),此时的线程可以在退出时让其他线程接合以便释放资源,但若其他线程未及时调用。因此,若线程退出时无需汇报其退出值,则一般要设置为分离状态,处于分离状态下的线程在退出之后,会自动释放其占用的系统资源。分离状态下的线程是无法被接合的。

2025-04-11 19:00:00 655

原创 并发编程--线程基本API

并发编程中线程基本API以及使用

2025-04-10 18:14:28 1214

原创 并发编程--守护进程编写步骤

守护进程(Daemon)也被翻译为精灵进程、后台进程,是一种旨在运行于相对干净环境、不受终端影响的、常驻内存的进程,就像神话中的精灵拥有不死的特性,长期稳定提供某种功能或服务。

2025-04-10 09:00:00 1253

原创 并发编程--守护进程

在编写守护进程的过程中,会跟如下诸多概念打交道:进程组、前台进程组、后台进程组、会话、控制终端等,下图简略地反应了它们之间的关系:系统调度的最小单位是进程(或称任务,task)若干进程可组成一个进程组,若干进程组可组成一个会话,可见这几个概念都只是进程的组织方式,之所以要构造进程组和会话,其根本目的是为了便于发送信号:我们可以通过给进程组或会话发送信号,便可使得其内所有的进程均可收到信号。

2025-04-09 17:52:32 851

原创 并发编程--信号量组SEM

信号量组非常类似于停车场的卡牌,想象一个有N个车位的停车场,每个车位是立体的可升降的,能停n辆车,那么我们可以用一个拥有N个信号量元素,每个信号量元素的初始值等于n的信号量来代表这个停车场的车位资源——某位车主要把他的m辆车开进停车场,如果需要1个车位,那么必须对代表这个车位的信号量元素申请资源,如果n大于等于m,则申请成功,否则不能把车开进去。对于信号量而言,最重要的作用就是用来表征对应资源的数量,所谓的P/V操作就是对资源数量进行 +n/-n 操作,既然只是个加减法,那么为什么不使用普通的整型数据呢?

2025-04-09 17:43:38 1028

原创 并发编程-消息队列MSG

并发编程中的消息队列MSG

2025-03-28 18:20:07 800

原创 并发编程--共享内存SHM

并发编程中的共享内存SHM

2025-03-28 18:01:15 1091

原创 并发编程--信号的基本概念与标准信号处理

信号的基本概念与标准信号处理

2025-03-23 17:25:41 1245

原创 并发编程--具名管道

具名管道是跟匿名管道相对而言的,从外在形态上来看,具名管道更接近普通文件,有文件名、可以open打开、支持read()/write()等读写操作。具名管道通常又被称为FIFO(First In First Out),这其实所所有管道的基本特性,那就是放入的数据都是按顺序被读出,即所谓先进先出的逻辑。先进先出的具名管道与PIPE一样不支持定位操作lseek()与PIPE一样秉持相同的管道读写特性使用专门的接口来创建:mkfifo()(匿名管道是pipe())

2025-03-16 20:59:04 384

原创 并发编程--进程间通信(IPC)概览以及匿名管道

进程间通信(IPC)概览以及匿名管道的基本逻辑、函数接口、匿名管道的读写特性、匿名管道的阻塞特性

2025-03-14 17:13:08 1567

原创 并发编程--僵尸进程

僵尸进程的概念、产生原因以及释放僵尸进程

2025-03-14 16:55:38 599

原创 并发编程--进程基本API

进程基本API,进程创建、进程回收、加载并执行指定程序

2025-03-11 22:49:31 590

原创 并发编程--进程与程序基础

而其余的进程,从上述pstree命令的执行效果可见,都是系统初始进程的直接或间接的后代进程。在Linux中,程序文件的格式都是ELF,这些文件在被执行的瞬间,就被载入内存,所谓的载入内存,如上图所示,就是将数据段、代码段这些运行时必要的资源拷贝到内存,另外系统会再分配相应的栈、堆等内存空间给这个进程,使之成为一个动态的实体。在Linux系统中,除了系统的初始进程之外,其余所有进程都是通过从一个父进程(parent)复刻(fork)而来的,有点像人类社会,每个个体都是由亲代父母繁衍而来。

2025-03-11 22:28:58 623

原创 C语言-预处理中的条件编译和头文件

C语言预处理中的条件编译和头文件

2025-03-10 21:00:00 1329

原创 C语言-预处理中的宏定义

C语言预处理中的宏定义

2025-03-09 21:00:00 2092

原创 C语言-结构体、联合体、枚举

c语言中的结构体、联合体、枚举的定义、语法以及应用

2025-03-08 21:00:00 1884

原创 C语言-作用域与存储期

C语言中的作用域与存储期

2025-03-07 21:00:00 1909

原创 C语言-函数指针与指针函数的区别

函数指针与指针函数的区别

2025-03-06 21:30:00 550

原创 C语言-字符串函数调用

C语言中字符串函数的调用

2025-03-06 21:00:00 528

原创 C语言-指针

C语言-指针

2025-03-05 20:59:30 1033

原创 C语言-内存管理

C语言内存管理:栈内存、静态数据、数据段、程序段、堆内存

2025-03-04 19:40:43 1232

原创 C语言综合案例-学生成绩管理系统

1.存储最多50名学生的信息(不使用结构体)

2025-02-27 22:43:15 1525

原创 C语言综合案例-猜拳游戏

​ 1.选择对手​ 2.自己出拳​ 3.对手出拳​ 4.双方比较​ 5.退出游戏。

2025-02-27 15:48:41 368

原创 C语言综合案例-简易图书管理系统(控制台输出结果)

简易图书管理系统,在控制台输出,实现添加图书、显示所有图书信息、查找图书、借阅图书、归还图书、退出系统等功能。

2025-02-26 20:55:24 504

原创 C语言-函数的递归调用、数组做函数的参数

函数的递归调用、数组做函数的参数

2025-02-20 19:19:54 864

空空如也

空空如也

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

TA关注的人

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