自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 进程的信号

首先,要把信号和信号量分别开,信号是用来通知进程发生了一些事件,而信号量是用来解决同步与互斥问题的。可以通过kill -l查询信号和对应的编号:比较常见的是前31个,其中,2号SIGINT就是Ctrl+C发出的信号,9号SIGKILL用来强制杀死进程(不可被屏蔽),15号SIGTERM是kill的默认信号,17号SIGCHILD是子进程退出以后向父进程发出的信号。这四个相对更常见,而9号和19号SIGSTOP都是不可被屏蔽的信号,什么是信号屏蔽后面再解释。

2025-12-06 23:50:31 906

原创 进程间通信

进程与进程间的数据是不共享的,回忆一下,通过fork()创建子进程的时候,父进程会以自己的代码为蓝本,创建出一个拥有和自己相同代码的另一个进程,而通过进程替换就可以修改子进程运行的代码。那么,如果我们需要在父进程和子进程直接交换数据,例如:父进程fork()出多个子进程进行for循环的并行运算,这个可以通过分割数组范围实现,但是如何将子进程加和的结果归约到父进程中呢?这就需要用到进程间通信。

2025-12-02 12:20:45 593

原创 文件描述符与文件系统

虚拟内存,顾名思义就是虚拟的内存,在程序的角度来看,确实得到的是一片连续的内存空间,而实际上申请到的物理内存并不是程序看上去那样,因此称之为虚拟内存。那么虚拟内存和物理内存是如何联系起来呢?靠的就是一张表,我们称之为页表,当我们使用指针寻找数据时,操作系统就会根据指针的内存,结合每个程序独有的一张页表找到对应的数据所在的物理内存的地址,从而实现虚拟内存与物理内存的对应。到这里其实还有问题,在程序启动之初,页表是空的,又要如何找到对应的数据呢?

2025-09-23 22:44:21 869

原创 Linux的进程替换

进程简单来说就是正在执行的程序的实例,在C++中我们接触过实例化这一概念,在这里也是一样的,进程本质上就是以代码为蓝图,放到CPU上运行,分配资源之后就成为了进程。因此,不同的进程可以拥有相同的代码段,但是只拥有相同的代码段不能称为同一个进程。而进程在本质上,其实是一个结构体,这个结构体会记录属于进程的资源,进程代码段的存储位置,以及进程的状态等信息。而区分不同进程的就是PID,每个进程都有唯一的PID,同时,除了init进程(PID=1),所有进程都有父进程,而记录父进程PID的就是PPID。

2025-09-02 09:38:18 517

原创 Linux的环境变量

在运行命令时,我们会发现,运行自己写的命令时,需要写出命令的路径,而系统的命令则不需要。而在写命令路径时,也会使用到相对路径,而当前工作目录也不需要我们手动去设置。这些都涉及到Linux的环境变量。那么什么是环境变量呢?环境变量就是操作系统或运行中的程序用来存储配置信息和系统参数的一种键值对,本质上是一个字符串数组,char**。需要注意的是,当fork子进程时,子进程只会继承父进程的环境变量,而并不能反过来影响父进程的环境变量。

2025-08-29 22:15:31 910

原创 如何在Linux系统下进行C语言程序的编写和debug测试

vim通常会用到三个模式,分别是普通模式、插入模式和命令行模式:普通模式就是使用vim打开文件后默认进入的模式,此时并不能直接进行文件的编写工作,需要一些特定的指令来进行删除、复制等操作。在普通模式下按i键即可进入插入模式,这个时候就可以正常编写文件了,要退回到普通模式按Esc键。要从普通模式进入到命令行模式则使用Shift+;键,就可以进入命令行模式,再使用Esc就可以退回到普通模式。

2025-07-29 22:42:08 783

原创 Linux的基本操作以及文件的权限

生活中,我们应该听过windows、安卓和IOS等名词,这些名词指的就是不同的操作系统。其中windows系统是我们比较常见的电脑操作系统,而Linux就是另一种操作系统,相比windows的图形化交互界面,Linux的操作界面就全是文字,因此使用起来有一定的门槛。但是由于其开源、安全、稳定等特征,使得Linux在开发中使用更加广泛。那么,如何拥有一个安装了LInux的电脑呢?

2025-07-28 15:51:39 888

原创 C++的特殊类

单例模式,是一种创建型设计模式,确保一个类只有一个实例,并提供一个全局访问点来获取该实例。要确保只有一个实例,关键就是要ban掉构造函数以及拷贝构造和赋值拷贝,防止出现更多实例。在ban掉构造函数以后,要如何创建出唯一的一个实例呢?只能从静态变量这个角度来想办法解决。从单例模式的应用场景入手,单例模式通常用来统一写入日志文件、对共享设备统一管理等。

2025-06-30 19:18:10 287

原创 智能指针及核心功能的实现

这种智能指针是最早出现的,但是由于其缺陷,已经很少使用了。缺陷是什么呢?if (a1.get() == nullptr) cout << "a1失效" << endl;return 0;运行以后,我们得到的结果就是a1失效,如果此时对a1进行解引用就会报错,这就是其缺陷。

2025-06-26 00:17:38 729

原创 C++11的一些特性

左值与右值最大的区别就是,左值可以取地址,而右值不能取地址。例如:1;//常量10 + 2;//表达式A();//匿名对象还有将亡值,也就是超出作用域将要被销毁掉的值以上这些都是右值,不能取地址。那么什么是右值引用呢?与左值引用类似,右值引用用来引用右值。区别于左值引用只使用一个“&”,右值引用需要使用“&&”与左值引用进行区分。右值引用不能绑定左值,但是如果使用move可以将左值转化为右值被右值引用,但是这个时候右值引用绑定的是左值的拷贝,并不是左值本身。

2025-06-21 19:08:09 907

原创 位图与布隆过滤器

布隆过滤器底层是以位图为基础实现的,但是由于要处理非整型的数据,相比整型需要多一步非整型数据对整型数据的映射操作,然后再使用位图存储映射出来的整型数据。但是为什么叫布隆过滤器而不是叫位图呢?原因就出在映射上,不同的数据有概率映射到同一个比特位上面,而这是不能避免的,我们能做的就是降低映射到同一个位置上的概率。如果数据查出来不存在,那么一定不存在;如果数据查出来存在,只能说可能存在。因此,布隆过滤器可以过滤掉一定不存在的数据,对于可能存在的数据还是要到数据库中进行查找,但是这样也能提高查找的效率。

2025-06-15 17:40:15 1006

原创 哈希表与unordered_set和unordered_map的实现

哈希是能将关键字通过映射方式直接映射成存储地址,从而使得查找效率提高到O(1)。例如:将每个值取模,再将取模得到的值直接作为存储在数组的位置:这样,如果要查找12,12%10 = 2, a[2] = 12,从而使查找效率达到O(1)。这只是一个例子,只需要有对应的映射函数,即可。例如,可以将string类型的数据,每个字符的ascii码直接相加,形成一个整型值。

2025-06-10 23:39:49 755

原创 基于红黑树的插入功能,对Set和Map部分功能进行封装实现

在上一篇中,对红黑树的插入功能进行了实现,但是要封装出set和map,还需要实现出红黑树的迭代器。

2025-06-05 16:19:47 722

原创 红黑树与红黑树的插入——用C++实现

红黑树是二叉搜索树的一种,区别于二叉平衡树,红黑树的平衡并不以平衡因子为依据进行平衡的调整而是以五条规则对红黑树进行定义,从而达成树的最长路径最多是树的最短路径的两倍长。:每个节点只能是红色或黑色。:树的根节点永远是黑色的。:所有叶子节点(空指针,通常用统一的哨兵节点NULL表示)都是黑色的。:如果一个节点是红色的,那么它的两个子节点都必须是黑色的(即:从任意一个节点出发,到达其所有后代叶子节点(NULL)的路径上,包含的。

2025-06-03 23:40:12 1065

原创 AVL树简介与部分实现

AVL树也就是二叉平衡树,首先需要满足二叉搜索树的要求,也就是,左子树的值小于根值小于右子树的值,同时,所有子树也满足要求。但是由于二叉搜索树并不能总是达到理想状态——完全二叉树或者满二叉树,从而使得查找效率达不到o(logN)。AVL树由此而来,之所以被叫做平衡树,是因为要保持树的平衡因子——右子树高度减去左子树高度,使平衡因子的绝对值小于等于一。同时,树的所有子树也要满足平衡的要求。通过平衡的办法,就能使得树保持一个相对理想的状态,使搜索效率大大提升。

2025-05-24 23:13:41 859

原创 C++之set与map介绍

set是一种存储唯一元素的集合,具有有序性和自动排序的特性,底层是由红黑树实现,按键值排序。因为支持迭代器,在使用范围for按顺序输出元素时,默认得到的是按键值升序的序列。

2025-05-20 23:38:20 898

原创 二叉搜索树简介与实现

V _value;这里,key的作用就是搜索时的关键字,而value是结点内存储的其他附带数据。

2025-05-19 01:22:04 292

原创 C++之多态

多态,简单来说,就是不同类型的对象调用同一个接口,表现出不同的行为。主要通过继承和虚函数的机制来实现。

2025-05-17 00:46:13 1036

原创 C++继承的基本概念

C++是面向对象编程,而类就是主要的表现形式,一个类就能封装一类对象的数据和相关的函数。而对象与对象之间并不是没有关联的,继承就是其中一种关系。举个例子进行说明,我们知道,一个人有许多的信息,例如姓名、性别等,当另一个对象,学生出现时,学生相对于人这个类,就是继承,学生是人,就可以继承人这个类中的数据和相关函数,并且额外加上学生特有的数据和函数,例如成绩、班级等。

2025-05-11 00:36:08 720

原创 stack和queue

在学C语言的时候,我们写栈通常底层使用的是动态数组或者链表,在C++中,同样可以使用vector或者list,借助这两个容器来实现class stack的接口。为了能适配两种类型的容器以应对不同的需求,这里使用了一个Container容器模板参数,并给了一个默认的容器类型deque<T>。由此,可以不指定特定的容器完成stack的功能,也可以在实例化时指定stack<int, vector<int>> 的实现容器类型。

2025-04-29 21:19:59 576

原创 std::list的使用和复现

其中,list3两个参数是两个迭代器。

2025-04-29 16:19:50 376

原创 std::vector简介

vector是STL里常用的一个容器,类似于动态数组,可以动态扩容,并且由于连续存储的特性支持高效的随机访问。且可以通过模板参数指定元素类型。

2025-04-23 00:17:37 359

原创 string:从基础使用到底层实现

std::string是C++标准库提供的字符串类,封装了字符序列的操作,支持动态内存管理和丰富的字符串处理方法。作为basic_string<char>的别名,它是开发中最常用的容器之一。

2025-04-19 14:27:49 700

原创 C++模板简介

只需要使用关键字template然后在<>内定义typename T或者class T,就可以将函数中的数据类型全部替换成T,从而达成使用模板的目的。编译器在调用函数时,会自动识别数据类型,并且结合模板生成对应的函数,如果是int型则将T替换成int类型再生成函数,如果是double类型,则将T替换成double类型再生成函数。这样就能实现int和double类型数据的相加函数,那么typename和class类型有什么区别呢?

2025-04-14 16:16:10 379

原创 C++内存管理

在C语言中,我们在申请内存时通常都会使用malloc、calloc和realloc函数,然后,就需要对函数返回的指针进行判断查看是否出了异常。而在C++中,operator new函数的使用与malloc函数相似,但是不需要判断返回的指针,而是使用try catch处理异常。两者有什么关系呢?事实上,malloc函数是被封装进了operator new函数中,然后将我们在C语言中判断指针是否为空的动作,换成了抛出异常,从而使用try catch处理异常。

2025-04-13 22:43:28 366

原创 初始化列表

这样,a和b就不用在函数内部构造了。那么初始化列表和构造函数有什么区别呢?首先就是初始化的时机不同,初始化列表在对象构造时就直接将其初始化了,而构造函数会先默认构造,在对其进行赋值操作,因此初始化列表的效率会更高一些。其次,就是一些成员变量类型,导致不支持先默认构造,再进行赋值,例如:const成员,引用成员,无默认构造函数的类成员等,需要在初始化列表中进行初始化。在对这样一个类进行初始化时,会首先对b进行初始化,由于a此时还没有初始化,因此b的值是一个随机值,然后才会对a进行初始化。

2025-04-11 10:55:58 334

原创 关于运算符重载

在编程的过程中,常常会使用到诸如:+,-,*,/,<,>等运算符。在C++中,能否让这些运算符对我们自己定义的类生效呢,答案是可以的。这也就是运算符重载,本质上是针对我们自定义的类去写符合运算符意义的函数,但是可读性相比调用函数好太多。

2025-04-10 21:20:43 353

原创 类和对象简介

在C语言中有结构体,使我们可以自己定义数据结构,在C++中同样有结构体,并在C 语言的基础上,加入了成员函数,使结构体能完成更复杂的任务。但是C++并没有止步于结构体,而是更进一步,产生了类,形成了面对对象编程。首先,struct变成了class,然后多出了private和public进行修饰。与struct最大的不同就是private和public,这两个修饰分别有什么用呢?public,公共的,也就是说,放在public下的函数或变量是可以像struct一样直接访问的。

2025-04-10 17:02:22 591

原创 C++命名空间,引用,inline,函数重载以及缺省参数

namespace分割不同程序员对函数或变量的命名在使用w内部的变量a和b,以及函数add时都需要加上w::但是这样命名空间的分割作用会失去作用,当两个命名空间内有变量使用相同的名称,并且命名空间都开放,就会报错,因为不清楚使用的是哪个命名空间内的变量。或者这样使用,就能部分开放命名空间内的函数或变量,所以相比上面开放所有,下面这种方法更推荐。

2025-04-10 14:53:16 394

原创 排序算法简介

另外,如果遇到topK的问题时,可考虑使用堆排序的方式,例如,要在一百万个数据里选取最大的10个数,那么只需建立一个大小为10的小根堆,每次将堆顶的元素与数据中的元素进行比较,若堆顶元素小于该元素,则将该元素放入堆顶,再调整小根堆,然后再进行堆顶元素和数据的比较,循环往复,直至遍历完数据,那么小根堆中的10个数据即为最大的十个数据。堆排序就是利用堆的特点,将堆建成以后,取其根结点的值,然后用堆底的元素取代根结点的位置,再经过调整形成新的堆,再取其根结点的值,循环往复,直至堆中只剩一个元素。

2024-06-02 23:22:59 1026

原创 二叉树的初步认识

二叉树是一种特殊的树形结构,主要的特点是每个结点最多有两个子树,且二叉树的子树有左右之分,次序不能颠倒。几种特殊的树:1.满二叉树高度为h,结点总数为2^h-1个结点的二叉树就是满二叉树,如果对满二叉树进行层序编号(自上而下,自左而右,从1开始),那么对于一个编号为i的结点,其双亲结点的编号为i/2向下取整,若有左孩子则编号为2i,右孩子为2i+1.2.完全二叉树其每个结点的编号与满二叉树的编号一一对应则是完全二叉树,各结点与其双亲结点和孩子结点的编号关系同上。3.二叉排序树。

2024-05-21 23:47:02 314 1

原创 栈与队列与构造

栈作为一种数据结构,只能在栈的一端进行数据的插入和删除,因此产生了先入后出的特征。由此,栈可运用于递归函数,以及正反括号的检查等。而,一组数据顺序入栈,其出栈的顺序却并不是固定的,其有着多种可能。假设有n个数据顺序入栈,那么出栈的可能性有上面这个式子就是卡特兰数,具体证明,感兴趣可以搜索一下。

2024-04-18 16:05:07 346

原创 关于双向带头链表

双向带头链表是链表的一种,一个结点由数据部分、指向前一个结点的指针和指向后一个结点的指针三部分组成。尽管看起来双向链表的结构较单向链表更为复杂,但是操作更为简便。双向链表相比单向链表在尾插、某个结点之前加入新结点、删除某结点等操作上,更加方便。而头结点的存在,能减少对输入结点为空情况的检查,使操作更方便。

2024-04-07 23:37:18 369 1

原创 C语言程序的编译与链接

当我们将代码写出来以后,文件的后缀通常是.c或者.h,计算机并不能直接运行这两个后缀的文件。那么我们的代码是如何经过编译和链接形成计算机能够运行的程序呢?我们已经知道,一个项目中,包括许多不同的.c文件和.h文件。这些文件相互之间,通过声明引用联系在一起,而把这些声明引用链接在一起就需要链接器,这个过程就是链接,这个过程也会涉及一些库函数,我们把这些运行时库或第三方库称为链接库。而链接器并不能识别.c和.h文件,我们需要将这些文件转化成链接器能识别的.obj文件,也叫目标文件,这个转化的过程就是编译。

2024-01-17 01:08:36 687

原创 文件与文件操作

为了防止数据的丢失,我们想对数据进行持久化的保存,文件也就出现了,例如我们写的代码就会以文件的形式保存在电脑中,下次打开时就不会丢失写出来的代码。在程序设计中,一般从文件功能的角度对文件进行分类:程序文件和数据文件。首先是程序文件,例如我们以.c为后缀保存的文件就是程序文件,程序文件包括源程序文件,目标程序文件和可执行程序文件。其次是数据文件,程序在运行过程中需要输入数据和输出内容到文件上,这样的文件就是数据文件。

2023-12-24 17:02:11 1826

原创 结构体类型数据

例如,一个学生拥有姓名和年龄两种信息,就可以通过结构体类型对一个学生相关的两个变量进行描述。结构体在声明时,可以不对结构体类型进行重命名,例如省略上面代码中的stu,这样做的后果就是匿名的结构体类型只能用一次。

2023-12-23 18:11:29 796 1

原创 整数与浮点数在内存中的储存

由于内存中存储数据时只会储存二进制数,在储存整数时,需要考虑的仅仅是整数是否会过大而溢出内存,而在储存浮点数的时候则需要考虑浮点数的精确度,那么在精确度和浮点数所占空间内存之间就需要做出取舍。

2023-12-11 22:55:06 142

原创 字符串函数的使用

在敲代码的过程中,经常需要操作字符串,为了方便这一过程,对字符串函数的使用熟练度就显得尤为重要,接下来就介绍几个常用的字符串函数。

2023-12-07 00:08:59 122

原创 对指针的理解

指针个人理解为指向某个特定数据存储地址的变量。

2023-12-03 23:18:18 106 1

原创 扫雷小游戏的简单实现

首先需要一个进入游戏的菜单,可以选择进入游戏或退出游戏。然后进入游戏后,映入玩家眼帘的游戏界面,由于技术手段有限,选择打印出二维数组,并且二维数组的字符全部设置为“ * ”号。而游戏界面的背后需要有地雷埋入这9x9的方格中,我们选择另外设立一个二维数组,避免数据存储在同一个数组中,使得游戏界面一开始就将地雷位置显示出来。然后地雷的摆放需要随机,这里就涉及到随机函数。

2023-10-30 23:28:47 104 1

空空如也

空空如也

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

TA关注的人

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