- 博客(38)
- 收藏
- 关注
原创 Linux gcc/g++
1.gcc是c语言编译器,g++是c++/c语言编译器 2.因为c++兼容c语言所有g++可以编译c语言,不过还是以c++的方式进行编译 gcc编译的c语言所形成的二进制只更接近于c风格 3.gcc/g++使用选项完全一致,本文以gcc为例 4.选项: 4.1编译概念:将源代码翻译成二进制可执行程序的整个过程称作编译 4.2gcc/g++后面直接跟源文件默认是将源文件进行编译,最后形成的可
2025-12-04 09:18:43
572
原创 Linux vim
1.在windows中由于图形化界面外壳程序的原因,可以开发出对应的IDE(集成开发环境) 例如vs2022在其中可以写代码,编译代码,形成二进制文件,再进行链接,最后再形成 可执行二进制文件,也可以在vs2022中进行调试,进行构建 2.但是由于Linux中命令行模式外壳程序的原因,无法做出像vs2022一样的IDE,并不能 将开发工具同一集结起来,所以在Linux中开封工具都是独立的 3.Linux中的开
2025-12-01 21:10:29
960
原创 Linux权限
1.操作系统: (1)广义上的操作系统 == 操作系统内核 + 外壳程序(shell命令行、图像化界面) + 必要软件 (2)狭义上的操作系统 == 操作系统内核 2.shell外壳:本质上就是使用一个软件将操作系统进行了一次包装 3.为什么要有shell外壳以及shell外壳的作用? (1)为什么:如果要直接使用操作系统内核进行操作,使用起来是极其复杂的,我们并不擅 长直接和操作系统内核直接打交道,也就
2025-11-27 21:56:22
762
原创 Linux基本指令(三)
因为单写一个文件名操作系统会认为是一个指令那么就会去对应的/usr/bin路径下去寻找,4.在Linux操作系统中,单独写一段字符会被认为是指令,就会去指定的目录下去寻找该。5.Linux中的指令就是二进制可执行文件,当只写一段字符时就会去对应的路径需按照该。那么就可以单写这个文件名,是一个指令去/usr/bin路径下去寻找该二进制可执行文件。但是不要这样做,这样会污染系统的指令池,因为我们自己写的程序是没有测试过的,并且。指令,如果单独写一段文件路径会被认为该文件是一个二进制可执行文件,就会去对应的。
2025-11-09 20:30:26
996
原创 Linux基本指令(二)
称作管道,此时首先使用head提取出前2011行,然后将head的输出作为tail的输入,然后。4.2echo既然是将内容输出写入到屏幕文件上,那么屏幕是文件,我普通文件也是文件。此时我们不想让cat从键盘文件中提取输入内容,想让cat从其他文件中提取输入的内容。5.2输入重定向:将提取输入内容的方向进行转换,将提取输入内容的文件进行转换。对应一个指令,上一个指令的输出是当前指令的输入,当前指令的输出是下一个指令的输入。将不同的指令连接起来,上一条指令的输出作为下一条指令的输入,这就就可以将指令的。
2025-11-07 13:46:05
877
原创 Linux基本指令(一)
1.文件和文件夹(目录)的概念 (1)文件:存储数据(文本、程序、媒体等)的"容器",存储数据的内容单元 是计算机存储数据的基本单元 (2)文件夹(目录):存储文件/子文件夹(子目录)的"索引容器",存储文件和子文件夹(子目 录)的位置引用(或路径索引)(索引:快速查找数据的"目录/指针表") (位置引用本质上就是指向目标(文件/子目录)实际存储位置的"地址标记" 直白点就是:文件/目录的地址)
2025-11-06 12:23:06
269
原创 C++智能指针使用及其原理
下面的程序我们可以观测到Divide会抛异常,但是由于前面我们使用了new,最后也进行了 delete,但是new也会抛异常,如果此时new直接抛异常那么不会有什么问题内存不会泄露 但是如果是后续的Divide抛异常,那么后面的代码就不会继续执行,也就是指向不到delete 那么就会导致内存泄露,此时面对这种情况我们就需要额外在调用Divide的地方套一层try/ catch进行捕获Divide异常然后将new出的资源释放了,然
2025-10-24 11:55:27
858
原创 C++ 异常
C语言主要通过错误码的形式处理错误,错误码本质就是对错误信息进行分类编号,拿到错 误码以后还要去查询错误信息,比较麻烦 C++处理错误的方式是通过抛异常 异常就是抛出一个对象(可以抛任意类型的对象),这个对象可以包含更全面的各种信息 异常处理机制允许程序中独立开发的部分能够在运行时就出现的问题进行通信并做出相应 的处理 异常使得我们能够将问题的检测与解决问题的过程分开,程序的⼀
2025-10-22 21:52:40
899
原创 C++ 11
C++98支持数组使用{}进行初始化,也支持结构体和类使用{}进行初始化 (注意:只有当结构体和类的成员变量全部都是public时才可以使用{}进行初始化) 2.2内置类型支持,自定义类型也支持,自定义类型本质是类型转换,中间会产生临时 对象,最后优化了以后变成直接构造(自定义类型本质上是构造函数隐式类型转换) 也就是自定义类型想要实现{}进行初始化需要有对应的构造函数支持 2.3列表初始化的过程中
2025-10-21 20:38:53
902
原创 C++ 用哈希表封装unordered_set/map
1.unordered_set/map的底层是一个哈希桶,并且unordered_set/map底层共用一个哈希桶 但是unordered_set是一个key场景,unordered_map是一个key/value场unordered_set 底层需要存储一个key,unordered_map底层需要存储一个key和一个value,存储数据的个 数都是不相等的,那么如何实现呢?在底层的哈希桶当中可以设置为只存储一个数据的 哈希桶,对于uno
2025-10-16 19:18:11
693
原创 C++ Hash
1.unordered_set和unordered_map是c++11新增的两个容器,底层使用的是哈希表 unordered_set和unordered_map使用逻辑与方式和set、map一致 unordered_set是key场景,unordered_map是key_value场景 unordered_set和unordered_map不支持冗余 unordered_multiset和unordere
2025-10-15 21:17:08
1001
原创 C++ map_set封装
1.map_set底层都是红黑树,并且map和set是通过一个红黑树的类模板进行实例化复用 1.1 map是key/value场景,set是key场景,两个容器所存储的数据的个数都不一致,怎么 实现复用同一个类模板? 解决思路:使用pair将map的key和value两个值存储起来, 红黑树底层只需要存储一个pair类型对象就可以,不需要单独存储key和value 此时红黑树中只需要存储一个pair类型的对象
2025-09-20 16:57:22
1031
原创 Red_Black_Tree(C++ Version)
并且插入之前左右子树的黑色结点的个数为hb,插入旋转之后左右子树的黑色结点个数也是hb。当uncle为黑或者uncle不存在时,都需要进行旋转,旋转过后的树的根是黑色结点。所以路径上的黑色结点的个数是没有变化的并且根结点是黑色结点,所以就不需要继续向上。黑色结点的个数必须相同。进行检查,就可以直接推出循环。
2025-09-19 20:00:02
707
原创 AVLTree(C++ Version)
首先对右子树的根节点进行一次右旋转,使得右边高的左边高变为右边高的右边高。逻辑上是:右边高的左边高不会进行修正,但是右边高的右边高会啊使用左单旋。逻辑上是:左边高的右边高不会旋转,但是左边高的左边高会啊不就是右单旋。然后再对根结点进行左旋转。
2025-09-11 23:23:00
656
原创 c++ map and set使用
1.序列式容器: 之前接触的string,vector,list,stack,queue等,这些都是序列式容器 因为这些逻辑结构上是线性序列的容器,相邻数据之间的存储没有什么关联 将相邻数据交换一下还是序列式容器 简单理解为:序列式容器只是存储数据,数据之间没有什么关联 2.关联式容器: map和set就是关联式容器,关联式容器不仅仅只是存储数据,和序列式容器
2025-09-05 17:52:54
928
原创 c++二叉搜索树
1.二叉搜索树,是一个空树或者具有以下性质的二叉树: 若左子树不为空,那么左子树上所有结点的值都小于等于<=根结点的值 若右子树不为空,那么右子树上所有结点的值都大于等于>=根结点的值 左右子树也分别为二叉搜索树 2.二叉搜索树又称作二叉排序树,原因: 当二叉搜索树进行中序遍历时,左根右,所遍历出来的结果是升序的 3.二叉搜索树既可以支持插入相等的值,也可以不支持插
2025-08-29 11:51:19
872
原创 c++多态
1.多态概念:函数调用时展现的多种形态(本质上是调用了不同的函数) 同一函数,不同实现,统一调用 2.多态的分类:编译时多态(静态多态)、运行时多态(动态多态) (1)编译时多态(静态多态):实现方式函数重载、函数模板(函数同名) 调用函数时,在编译时根据参数的类型/个数不同调用不同的函数 从调用角度看调用的是同一函数,因为函数名相同
2025-08-18 15:00:07
715
原创 c++继承
1.继承的概念(1)继承是类设计层次的复用(2)派生类可以复用基类的代码,避免了重复编写相同的代码(3)派生类可以在基类的基础上添加新的成员变量和成员函数(4)继承允许一个类基于另一个类来构建继承的主要目的是实现代码重用和建立类之间的层次关系2.继承的定义(1)继承方式分为:public/protected/private(2)定义格式3基类成员在派生类当中的访问权限(1)基类成员在派生类当中的访问权限是根据:基类成员在基类中的访问限定符和派生类的继承方式决定的。
2025-08-15 16:58:11
733
原创 c++模板进阶
1.非类型模板参数定义常量 2.例子: (1)假设此时需要定义一个模板类型的静态数组 此时静态数组的大小是由宏定义的常量决定的 如果此时需要一份大小为10的静态数组,那么还可以完成 但是如果需要一份大小为100的静态数组,就无法完成任务 因为宏是写死的 为了解决此类问题
2025-08-09 18:10:12
730
原创 c++类常用默认成员函数细节分析
1.当我们不写,编译器会自动生成这些默认成员函数 2.编译器自动生成的默认成员函数的行为是什么,是否满足我们的需求 3.如果不满足我们的需求我们该如何编写 1.编译器默认生成的构造函数,自带初始化列表,所有的工作均在初始化列表中完成 (1)对于内置类型成员变量: a.拥有缺省值:在初始化列表中使用缺省值进行初始化 b.未拥有缺省值:初始化列表对其的行为是
2025-08-06 19:52:35
875
原创 Piriority_queue
1.在类中运算符重载了(),也就是函数调用时后面的() 则该类称作仿函数类,该类实例化出的对象称作仿函数 2.该类实例化出的对象称作仿函数是因为该对象可以像函数一样被调用 ( 对象(参数列表) ) == 对象.operator()(参数列表) 3.仿函数类也是类,所以仿函数类也可以拥有普通类的成员变量和成员函数 4.仿函数使用 (1)通过模板和类型转变函数体内
2025-08-02 23:12:18
717
原创 Stack、Queue and Deque
1.适配器的概念: 封装一个已有对象,转换其接口 2.容器适配器: 封装一个已有容器对象,转换其容器对象的接口 3.容器适配器中没有迭代器 (1)行为约束,保证栈后进先出和队列先进先出行为 (2)安全保证,避免破坏内部结构,如:priority_queue的堆序性 4.适配器模式: 封装旧对象 + 接口转换层
2025-08-01 17:00:23
786
原创 c++list模拟实现
1.list是一个双向循环链表,list创建出来的对象表示着整个链表,管理操作着整个链表 2.list是由一个个结点组成,结点也是自定义类型 3.根据1,2list的底层直接使用结点的底层可不可以呢? 不可以,如果list的底层是结点的底层,那么该list类管理的就是结点的内部,而不是整个 链表,所以结点必须为单独的一个类,list也为单独的一个类 链表的底层如果是结点的底层,那么这个类管理
2025-07-27 10:57:12
1027
原创 c++vector模拟实现
1.模板可以声明和定义分离到同一个文件当中,但是不可以声明和定义分离到两个不同的 文件 2.vector的成员变量不再是T* _arr;size_t _size;size_t _capacity; 3.vector的迭代器可以通过原生指针去实现 vector的成员变量通过迭代器去实现 (1)迭代器类型在外部需要被访问使用所以迭代器类型typedef在public下
2025-07-22 15:56:21
934
原创 c++vector使用
一、vector是什么? 1.vecto是一个顺序表,底层由一个指向动态开辟的数组的指针,_size和_capacity组成 2.vector在STL中是一个类模板 类模板的参数 (1)class T,表示该vector是哪种类型的顺序表,也就是vector底层数组存储的是哪一 种数据类型 (2)class AIIoc,表示该vector底层数组申
2025-07-20 21:02:19
864
原创 c++string模拟实现
本文系统介绍了C++中string类的模拟实现,主要包含以下内容:1.构造与析构函数的设计,包括无参构造、带参构造和深拷贝构造的实现细节;2.字符串遍历方法,包括[]运算符重载、迭代器实现原理及范围for的底层机制;3.空间管理接口如size()、capacity()、reserve()等;4.插入删除操作接口如push_back、append、insert、erase等;5.其他重要接口包括查找、子串、流操作符重载等;6.现代写法实现拷贝构造和赋值运算符重载;7.完整的string类模拟实现方案。
2025-07-18 22:17:06
1275
原创 c++string使用
本文系统介绍了C++中的string类及其相关操作。string是basic_string<char>类的typedef重命名,可视为字符顺序表,其底层包含字符数组和'\0'结束符。文章详细阐述了string的构造/析构函数、多种访问方式(包括[]运算符、迭代器和范围for)、空间管理接口(如size/capacity/resize/reserve等)、元素访问方法(at/back/front等)以及插入删除操作(push_back/append/insert/erase等)。此外还介绍了字符串
2025-07-12 23:53:56
1889
原创 算法复杂度
本文主要介绍了数据结构和算法的基本概念及其复杂度分析。数据结构是数据存储和组织的形式,其底层通过数组和链表实现,不同数据结构在不同场景下的效率各异。算法是解决问题的方法,其效率通过时间复杂度和空间复杂度来评估。时间复杂度反映算法运行速度,空间复杂度则指算法所需的额外空间。文章还详细解释了如何推导时间复杂度和空间复杂度,并介绍了大O渐近表示法,用于简化复杂度的表达。最后,文章对比了常见的复杂度类型,帮助读者理解不同算法的效率差异。
2025-05-17 13:08:38
930
原创 c++模板初阶
本文介绍了C++中的泛型编程及其核心概念——模板。泛型编程通过模板实现,允许编写不依赖于特定类型的函数和类,从而提高代码的复用性和灵活性。函数模板和类模板是两种主要形式,它们通过编译器实例化来生成具体类型的函数或类。函数模板可以隐式或显式实例化,而类模板只能显式实例化。文章还讨论了模板的语法、实例化规则以及模板与普通函数的匹配优先级,强调了模板在减少代码重复和提升开发效率方面的重要作用。
2025-05-11 17:18:05
814
1
原创 c++内存管理
文章主要探讨了C和C++中的内存管理机制,包括内存分布、内存管理函数和操作符的使用及其异同。首先,文章详细介绍了内存的分布,包括栈区、堆区、静态区和常量区,并分析了不同类型变量在内存中的存储位置。接着,文章复习了C语言中的内存管理函数,如malloc、calloc、realloc和free,并对比了C++中的new和delete操作符,强调了它们在处理内置类型和自定义类型时的不同行为。此外,文章还介绍了operator new和operator delete的内部机制,以及定位new表达式的使用场景。
2025-05-10 18:05:21
1741
原创 c++类与对象(终)
c++自定义类型类型转换、static定义、static成员变量与static成员函数、<< && >> 运算符重载与友元函数、内部类、匿名对象、对象拷贝时的编译器优化。
2025-05-07 15:44:53
1946
2
原创 c++类的默认成员函数
(1). 当运算符重载函数作为成员函数时,运算符第一个运算对象会传给成员函数中的 this 指针,因此当运算符重载函数作为成员函数时,运算符重载函数的定义看似会 少一个。指针,因此当运算符重载函数作为成员函数时,运算符重载函数的定义看似会少一个 (6). 运算符重载函数可以构成函数重载。的对象拷贝初始化形参,自定义类型对象的拷贝初始化一块空间,必须调用该自定。
2025-04-25 17:52:59
885
3
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅