- 博客(47)
- 收藏
- 关注
原创 【Linux】——文件(上)
在系统层面来说,文件就是。我们的所有文件操作其实就是对文件的内容和属性进行操作。。,自然其他语言也会有相似的概念,因为这是操作系统所支持的,而不是某个语言所独有的。文件在没有被访问时,是存储在磁盘上的,访问时,在内存中,为什么不在磁盘直接访问呢,还要跑到内存里?。因为,所以加载时,加载的就是。
2025-03-29 21:23:55
649
1
原创 【Linux】——进程(下)
它的第一个参数就是路径,第一个参数到最后一个参数之间的参数叫做可变参数列表,也就是说可以有多个,它和我们在命令行使用的命令是一样的,只不过我们命令行的分隔是空格,而这里的分隔是逗号和引号,最后一个参数必是NULL,表示该表的末尾边界。//options == WNOHANG,若pid指定的子进程没有结束,则waitpid直接返回0,不等待,若正常结束,则返回子进程pid。在之前的父子进程关系中,当子进程还未退出时,父进程通常处于阻塞状态,这个期间父进程不能进程其他操作。但是,我们可以采取非阻塞等待的方式。
2025-03-26 20:18:27
864
1
原创 【Linux】——环境变量与进程地址空间
进程地址空间是进程可以使用的全部线性地址的集合,就是程序地址空间那张图,它是抽象的,其实它屏蔽了物理存储器的实际大小和分布细节,使进程得以在一个看似连续且足够大的存储空间中存放进程映像。子进程不一定会使用父进程的所有数据,并且在子进程不对数据进行写入的情况下,没有必要对数据进行拷贝,我们应该按需分配,在需要修改数据的时候再分配(延时分配),提高空间利用率。如果我们是在同一个物理地址处获取的值,那必定值是相同的,而现在在同一个地址处获取到的值却不同,这只能证明我们打印出的地址并不是物理地址。
2025-03-20 19:53:48
681
1
原创 【Linux】——进程(上)
可执行程序加载到内存后就形成了进程,进程里包含了代码数据,运行状态等信息。操作系统通过管理进程控制块PCB(task_struct)来管理可执行程序,进程担当分配系统资源(CPU时间,内存)的任务。所以,只要可执行程序加载到内存,操作系统就会创建PCB将其管理,最后就形成了进程。操作系统将每个PCB通过双向链表的方式链接起来,创建了一个新进程就直接将对应的PCB链入双向链表中,退出就是将PCB删除。
2025-03-16 18:28:55
651
1
原创 【Linux】——初识操作系统
我们现在所使用的计算机就是冯-诺依曼体系结构。存储器就是内存。由下图可知,寄存器最快,为啥不用寄存器呢?因为越快价格就最贵,冯诺依曼体系结构的诞生,极大降低了计算机的价格。冯诺依曼结构的原理是,在CPU进行计算的时候,内存已经接收外部输入设备输入的数据并存储,在CPU进行完计算后将结果取出,然后将结果放到输出设备,再把输入的数据交给CPU进行计算所以这就是为什么程序运行前要先加载的内存!通过冯-诺依曼体系结构去理解何为操作系统。内存怎么读数据?输入数据以后怎么从缓冲区输出到输出设备的?操作系
2025-03-07 21:02:34
740
1
原创 【Linux】——必须掌握的开发工具
PHONY是一个伪目标,用来告诉make哪些目标不是真正的文件名,我的clean是为了删除文件,保持工作目录的整洁,如果不加.PHONY,而且项目中存在一个clean文件,clean文件万一比依赖文件更新,make就会认为clean文件是最新的,从而不会执行make clean。最终在最后一次的依赖关系中找到myproc.c,再出栈依并执行,做到了从上到下扫描,从下到上执行,最终形成myproc目标文件。所以在将clean定义为伪目标时,它会告诉make,clean总是被执行,不用考虑其他。
2025-03-04 19:15:58
1020
1
原创 【Linux】——权限
但是有时候我们并不知道root用户的密码,但是又需要root用户去执行某条指令,那么这时就需要输入指令sudo 指令,这条指令就可以提升我们要执行指令的权限,即让root用户执行。如果仔细观察就可以发现,其一共有十个字符,除开第一个代表文件的类型外,后九个每三个为一组,分别代表拥有者,所属组,其他用户的可读,可写,可执行的权限。但是这种情况就会导致一个非常严重的问题,那就是:拥有可读权限的人可以删除文件,这是不可取的,因为这个文件不一定是你创建的,你不可能去删除别人的文件。所以这时候就需要我们切换用户。
2024-12-16 18:51:44
740
4
原创 【Linux】——基础指令(下)
a详细输出所有信息,依次为内核名称,主机名,内核版本号,内核版本,硬件名,处理器类型,硬件平台类型,操作系统名称。tar指令也可以用来打包压缩和解压文件,并且可以实现不解开压缩包,直接查看里面内容的操作,以及只打包不压缩等操作。功能: 用于查看日历等时间信息,如只有一个参数,则表示年份(1~9999),如有两个参数,则表示月份和年份。与more指令不同的是,less指令可以进行上翻操作,并且less指令在查看之前不会先加载整个文件。-f:使用档名,请留意,在f之后要立即接文档名,不要再加参数。
2024-12-03 19:55:01
966
5
原创 【Linux】——基础指令(上)
如果我们想指定删除某种类型的文件,比如说我们想删除后缀为.c的文件,可以这样使用rm ./*.c。-r 或 -R 递归处理,将指定目录下的文件与子目录一并处理,若源文件或目录的形态不属于目录或符号链接,则一律视为普通文件处理。我们先要清楚,Linux的目录结构是一颗多叉树。可以是一个路径名称,此时若路径中的某些目录不存在,加上此选项后,系统将自动建立好那些不存在的目录,即一次可以建立多个目录。-i 或 --interactive 如果文件不存在,则复制文件,如果文件存在,则覆盖文件,覆盖之前先询问用户。
2024-11-22 20:10:51
871
4
原创 【C++】——用哈希封装unordered_set和unordered_map
在迭代器中应该有两个参数,一个就是节点指针,另一个就是我们的哈希表的指针,因为我们可能需要遍历哈希表的下一个桶的位置。为了同时支持const迭代器与普通迭代器,我们需要三个模版参数,第一个模版参数T代表数据存储类型,第二个模版参数Ref代表存储类型的引用,第三个模版参数Ptr代表存储类型的指针。我们的比较除了用仿函数替换以外,以及需要将key通过对应的转换函数转换以外,还需要将返回值改造了,返回值是pair类型,第一个参数是迭代器,第二个是bool值。为了更加灵活,我们把哈希表的模版参数定义为T。
2024-11-09 20:21:13
409
5
原创 【C++】——哈希
哈希是一种特殊的存储结构,该结构能够通过某种函数使元素的存储位置与它的关键码之间能够建立映射的关系。哈希方法中使用的转换函数称为哈希(散列)函数,构造出来的结构称为哈希表(散列表)。
2024-11-07 17:23:55
1030
7
原创 【C++】——红黑树
在我的上篇博客中介绍了AVL树,红黑树其实就是在AVL树的基础上进行改进的。红黑树的特点每个节点不是黑色就是红色根节点是黑色如果⼀个结点是红⾊的,则它的两个孩⼦结点必须是⿊⾊的,也就是说任意⼀条路径不会有连续的红⾊结点。对于任意⼀个结点,从该结点到其所有NULL结点的简单路径上,均包含相同数量的⿊⾊结点空节点NIL(取自算法导论NIL)一定为空节点,或者直接称为NULL节点满足以上性质,就能保证最长路径不会超过最短路径的两倍,以达到接近平衡状态,能够减少旋转效果。
2024-11-01 20:45:57
922
7
原创 【C++】——AVL树
插入数据要更新平衡因子,如果高度差大于一,就需要通过旋转平衡。和二叉搜索树相似,AVL树多了一个平衡因子。AVL树是在平衡二叉树的基础上改进的。
2024-10-09 19:31:44
561
4
原创 【C++】——set和map的使用
multimap的find返回底层搜索树中序的第一个值为key的元素的迭代器,而map返回的是key元素的迭代器。并且由于multimap支持键值冗余,所以其成员函数没有[]运算符重载,因为一旦键值冗余,根本不知道该返回哪个键值的value。从返回结果中还可以看出:无论插入成功还是失败,都会返回指向key的迭代器,那么就意味着,insert不仅仅可以插入,还有查找功能。类似这样,把两个值传给pair,pair再自己构造一个匿名对象进行返回,所以可以省略参数类型。需要注意的是,有两个pair,一个是。
2024-09-24 16:14:55
928
6
原创 【C++】——多态
必须通过基类的指针或者引用才能调用虚函数,这是因为只有基类的指针或引用能够同时指向基类和派生类的对象,从而实现多态的效果。被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写。1public:virtual void BuyTicket() // 虚函数cout << "全价票" << endl;public:virtual void BuyTicket() // 虚函数重写cout << "半价票" << endl;
2024-09-19 16:57:07
830
4
原创 【C++】——继承与虚继承
下⾯我们看到Person是基类,也称作⽗类。Student是派⽣类,也称作⼦类。(因为翻译的原因,所以既叫基类/派⽣类,也叫⽗类/⼦类)继承基类成员访问⽅式的变化基类的private成员只是不可访问,但是派生类还是得到了继承public和protected的区别public:protected:public:// 可以访问基类的public成员// 可以访问基类的protected成员Derived d;// 正确:可以通过Derived实例访问public成员。
2024-09-18 21:15:22
980
1
原创 【C++】——优先级队列和容器适配器
stack是一种后进先出的特殊线性数据结构,因此只要具有push_back()和pop_back()操作的线性结构,都可 以作为stack的底层容器,比如vector和list都可以。queue是先进先出的特殊线性数据结构,只要具有 push_back和pop_front操作的线性结构,都可以作为queue的底层容器比如:list。优先级队列是一种特殊的队列,他的元素出队列顺序并不按照先进先出原则,而是根据元素的优先级来。deque容器是什么,stack和queue为什么在底层设计时用deque来实现?
2024-09-17 17:59:41
853
4
原创 【C++】——vector模拟实现和迭代器失效问题
插入元素:在vector末尾插入元素,除了指向最后一个元素的迭代器以外,其他迭代器依旧有效如果在其他位置插入,则指向该插入位置的迭代器和其之后的所有迭代器失效删除元素:删除元素后,被删除和删除之后的所有迭代器都会失效重新分配:当vector的大小超过当前容量时,它可能分配需要更大的空间进行存储元素,这种重新分配会导致所有迭代器、指针、引用失效注意:vector的迭代器失效也和编译器环境有关,有关指报错和运行。
2024-09-13 18:26:05
569
4
原创 【C++】——vector
vector是一个动态数组,可以根据需求变大变小vector支持随机访问vector会自动管理内存分配和释放vector在尾部添加和删除的效率非常高,中间和头部插入较慢,因为内存是连续的,除了尾部的增删以外都需要挪动被处理数据之后的全部数据。
2024-09-12 19:23:02
590
5
原创 【C++】——string(模拟实现)
这篇博客中构造、拷贝构造、析构、还有一些短小频繁调用的函数就不用做函数和定义分离,因为在类中,这种函数会默认是内联函数。
2024-09-11 16:01:30
755
5
原创 【C++】——初识模版
/为每一个类型都编写一个重载版本这种方法的缺点是显而易见的:随着需要交换的类型的增加,你需要不断地编写新的重载函数。这不仅繁琐,而且不灵活,因为它不能自动适应未来可能出现的新类型。函数模板提供了一种更加灵活和通用的解决方案。你可以定义一个模板函数,该函数可以接受任意类型的参数,并在编译时根据传入的参数类型生成相应的函数版本。
2024-07-23 16:00:47
796
16
原创 【C++】——new和delete
new会自动调用构造函数delete会自动调用析构函数new和delete不同的是:new/delete申请和释放的是单个元素空间,new[]和delete[]申请的是连续空间,而且new在申请空间失败时会抛异常,malloc则是返回NULLfree和malloc不会调用析构函数和构造函数,所以new和delete主要使用在自定义类型。
2024-07-21 21:17:02
815
10
原创 【C++】——类的对象(下)
因为那些你不在初始化列表初始化的成员也会走初始化列表,如果这个成员在声明位置给了缺省值,初始化列表会用这个缺省值初始化。如果你没有给缺省值,对于没有显示在初始化列表初始化的内置类型成员是否初始化取决于编译器,C++并没有规定。对于没有显示在初始化列表初始化的自定义类型成员会调用这个成员类型的默认构造函数,如果没有默认构造会编译错误。每个成员变量在初始化列表中只能出现一次,语法理解上初始化列表可以认为是每个成员变量定义初始化的地方。,跟成员在初始化列表出现的的先后顺序无关。希望这篇博客能帮助到你!
2024-07-19 16:11:37
776
15
原创 【C++】——类和对象(中)
3.没有显式实现时,编译器会自动生成一个默认赋值运算符重载,默认赋值运算符重载行为跟默认拷贝构造函数类似,对内置类型成员变量会完成值拷贝/浅拷贝(一个字节一个字节的拷贝),对自定义类型 damen成员变量会调用他的拷贝构造。赋值运算符重载是一个默认成员函数,用于完成两个已经存在的对象直接的拷贝赋值,这里要注意跟拷贝构造区分,拷贝构造用于一个对象拷贝初始化给另一个要创建的对象。通过使用引用,特别是常量引用,我们避免了这种递归调用,因为引用只是对象的别名,不需要创建对象的副本。希望这篇博客对你有所帮助!
2024-07-15 22:18:19
1044
8
原创 【C++】——类和对象(上)
类是一个用户定义的类型,它封装了数据(称为属性或成员变量)和操作这些数据的方法(称为成员函数或方法)。类可以看作是创建对象的蓝图或模板,它定义了对象的行为(能做什么)和状态(有什么)。C++中的类和C语言中的结构体struct是非常相似的,C语言结构体中只能定义变量,在C++中,结构体内不仅可以定义变量,也可以定义函数。比方说我创建栈(stack)和队列(list),在c语言中,他们的定义必须分开,否则编译器就无法判断他们同一功能的同名函数到底谁是谁的push,谁的top等等…
2024-07-15 16:22:10
910
5
原创 【C++】——入门基础
const引用是一种特殊的引用,它允许你引用一个对象但不允许通过这个引用来修改该对象的内容。函数重载是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同,常用来处理实现功能类似数据类型不同的问题。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。函数重载的主要目的是让同一个函数名能够根据不同的参数类型或数量执行不同的功能,这样既可以提高代码的可读性,又可以让函数调用更加灵活。权限可以缩小,不能放大。
2024-07-14 21:05:14
1158
8
原创 【数据结构】——链表经典OJ(leetcode)
如果反转前半部分,那么找中间值的条件就为fast->next && fast->next->next不为空,我选择反转后半部分,相对更容易理解。当fast和slow相遇后,我们将meet点设为新的起点,然后head点和meet点往后走,终究会相遇,相遇的点就是环的入口。这题需要注意返回新链表的头节点,所以新链表创建两个节点来记录头和尾节点最方便。这题两个选择,反转前半部分再对比,或者反转后半部分再对比。先看代码,这题的代码很简单,但是要明白所以然。先记录链表长度,再找到要删除节点的上一个节点。
2024-06-26 16:12:49
762
4
原创 贪吃蛇——c语言版
前面提到如何定位光标位置,在每一页打印完以后暂停,并且清理该页,才会接着打印下一页printf("欢迎来到贪食蛇小游戏");printf("用↑ . ↓ . ← . → 分别控制蛇的移动,F1为加速,");printf("F2为减速,加速将得到更高的分数");
2024-06-20 19:55:55
1016
9
原创 c语言——扫雷游戏(简易版)
什么是扫雷游戏?游戏目标是在最短的时间内根据点击格子出现的数字找出所有非雷格子,同时避免踩雷,踩到一个雷即全盘皆输。这个游戏对于c语言的初学者来说难度还是挺大的,那我就实现一个初学者也能快速学会的初级版扫雷游戏。
2024-06-16 20:32:04
856
5
原创 【数据结构】——二叉树的创建
2.遇到第一个空节点就开始判断,如果后面全是空,那就是完全二叉树,如果后面还有非空,就不是完全二叉树。再层序遍历之前,我们先把队列的val设置为树节点的指针。希望这篇博客对你有所帮助!1.层序遍历走,空也进队列。
2024-06-03 15:53:46
559
6
原创 【数据结构】二叉树和堆
二叉树,作为一种重要的数据结构,由节点组成,每个节点可以有两个子节点,通常称为左子节点和右子节点。二叉树是有序的,树中包含的各个节点的度不能超过2,即只能是0、1或者2。特殊二叉树满二叉树一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是说,如果一个二叉树的层数为K,且结点总数是 2的k次方-1,则它就是满二叉树。完全二叉树完全二叉树,作为一种效率很高的数据结构,是由满二叉树衍生出来的。
2024-05-26 17:47:17
1049
10
原创 数据结构——时间复杂度和空间复杂度
我们先要知道什么是算法算法(Algorithm)是指用来操作数据、解决程序问题的一组方法。对于同一个问题,使用不同的算法,也许最终得到的结果是一样的,但在过程中消耗的资源和时间却会有很大的区别。如何衡量一个算法的好坏呢,一般是从时间和空间两个维度来衡量,即时间复杂度和空间复杂度。通俗一点的说,我的代码实现这个功能使用的时间是30毫秒,占用内存20M别人是1秒,占用内存40M时间复杂度的定义:在计算机科学中,算法的时间复杂度是一个函数,它定量描述了该算法的运行时间。
2024-05-17 21:24:55
838
5
原创 C语言——栈和队列
ps->a我们有两种初始化方法,一种是直接malloc一个空间,可以是四个或者八个对象的空间,也可以像我一样,先不开,等会入栈的时候再开。栈是一种特殊的线性表,限定仅在表尾进行插入和删除的线性表。在进行入栈以前,先把top指向为栈顶的下一个数据,如果指向栈顶数据的话,初始化就不能为0。队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。栈的实现一般使用数组或者链表,因为cpu高速缓存的原因,使用数组也非常ok。希望这篇博客对你有所帮助!头文件:Queue.h。
2024-05-14 09:14:26
608
6
原创 C语言——环形链表详解
在一个单链表中,链表中存在环形结构。在链表中的某个节点,可以连续通过next指针再次到达,则链表中存在环。无论slow走几步,fast走几步,追击问题关系的不是走几步,而是速度差,因为他们最终都会进环。我们回到原来的问题,fast和slow到底会不会错过。当fast走三步,slow走一步时为例:如果同时存在N是奇数且C是偶数,那么将永远追不上。但是,有没有一个可能,这种情况不存在。我们使用数学来证明一下。假设slow进环时fast跟slow的距离为Nslow走的距离为L。
2024-05-12 23:23:13
1015
7
原创 c语言——整数和浮点数在内存中的存储(图解)
整数的二进制表达方式有三种:原码、反码、补码。有符号整数的三种表示方法均有符号位和数值位两部分,2进制序列中,最高位的1位是被当做符号位,剩余的都是数值位。符号位都是⽤0表示“正”,⽤1表示“负”。原码:直接将数值按照正负数的形式翻译成⼆进制得到的就是原码。反码:将原码的符号位不变,其他位依次按位取反就可以得到反码。补码:反码+1就得到补码 反码得到原码也是可以使用:取反,+1的操作。前⾯说过, 1≤M<2 ,也就是说,M可以写成 1.xxxxxx 的形式,其中 xxxxxx 表示小数部分。
2024-03-27 20:17:43
1322
3
原创 c语言字符串函数和内存函数(图文详解)
在编程的过程中,我们经常要处理字符和字符串,为了⽅便操作字符和字符串,C语⾔标准库中提供了⼀系列库函数,在介绍字符串函数之前,我先来给这些个字符串函数分一下类:功能:获取的字符串长度,不包括’\0’。返回字符串的长度。实例:模拟实现:二、 长度不受限的字符串函数:1.strcpy功能:将源指向的字符串复制到目标指向的数组中,包括’\0’,并返回目标数组起始地址。模拟实现:2. strcat功能:将源字符串的副本追加到目标字符串尾部。目标字符串中的’\0’被源字符串的第一个字符覆盖,并且在目标
2024-03-24 17:04:58
1001
1
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人