自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 C++继承

Person是父类,也称作基类。Student是子类,也称作派生类。很多人说C++语法复杂,其实多继承就是一个体现。有了多继承,就存在菱形继承,有了菱形继承就有菱形虚拟继承,底层实现就很复杂。所以一般不建议设计出多继承,一定不要设计出菱形继承。否则在复杂度及性能上都有问题。多继承可以认为是C++的缺陷之一,很多后来的OO语言都没有多继承,如Java。继承和组合public继承是一种is-a的关系。也就是说每个派生类对象都是一个基类对象。组合是一种has-a的关系。

2024-09-24 15:39:14 1198

原创 C++模板进阶

因为编译的时候进行的语法检查,Add函数在头文件有声明,语法就没有错误,只要链接的时候才会去符号表中寻找函数。但是在。

2024-09-24 15:38:52 799

原创 C++模拟实现priority_queue(仿函数)

优先队列是一种容器适配器,根据严格的弱排序标准,它的第一个元素总是它所包含的元素中最大的。类似于堆,在堆中可以随时插入元素,并且只能检索最大堆元素(优先队列中位于顶部的元素)关于仿函数的使用,不仅仅局限于上面代码的比较,还可以进行类的比较,不如日期类或者日期类的指针。看手册的描述可以发现,我们需要传我们需要的比较逻辑,sort会根据bool类型的返回确定仿函数的两个参数哪一个排在前面。通过上述代码,即使优先级队列插入的是日期类的指针,同样可以按照我们需要的大小输出。,我们可以根据我们的需要改变比较逻辑。

2024-09-11 17:24:37 432

原创 C++模拟实现stack和queue(容器适配器)

适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结),该种模式是将一个类的接口转换成客户希望的另外一个接口。简单理解,将模板参数给成容器,就是容器适配器,写成参数的容器的各种接口,均满足需要。

2024-09-11 12:35:20 277

原创 C++模拟实现list

可以发现上述代码中为了解决const修饰的链表仍然可以通过迭代器修改结点的值的问题,重新写了一个类,但是这个类中只要解引用和->访问被const修饰了。其他成员函数都是一样的。于是可以通过模板解决这个冗余的问题。讲解引用和->的重载返回值改用模板参数。然后通过list中的两个宏去定义二者。这样就有了两个类,且功能和上面的代码一样。list的实现最主要的点就是迭代器的实现,不能在使用原生指针,因为链表的结点并不是连续的。

2024-09-06 13:52:27 465

原创 C++模拟实现vector

模拟实现vector只是实现了一些基础功能,复杂一些操作可能会存在bug。一些相关知识点在注释标注。

2024-08-28 10:05:22 198

原创 模拟实现string

模拟实现string只是仿造库里的功能模拟实现,并不和库中代码一样。需要知道的是,string在不同的编译器下,string的实现也是有差异的。

2024-08-28 10:04:54 373

原创 C++string

在cplusplus这个网站上的介绍可以知道,string是C++标准库中的一个类,*而且可以发现string其实是一个宏,是其中是类名,宏替换为string。可以发现也是一个类模板实例化为char类型的一个 类 类型。所以可以理解为string就是一个存储字符串的一个类。之所以定义为宏和编码方式有关。在 C语言 中,字符串是以\0结尾的一些字符的集合,C++面向对象编程,于是 C++ 中就引入了string类,它可以看做是一个管理字符串的数据结构。

2024-08-22 12:43:10 841

原创 C++模板

所以也不是调用的最开始的模板代码,他们调用的是编译时编译器通过模板生成的代码。对于模板来说,他所在的位置,如果是全局的,那么实例化出来的模板函数就是全局的,如果是成员函数,那么实例化出来的函数就是成员函数。对比typedef可以发现,如果要想实现上述的定义两个不同类型的栈,宏的方式就必须定义两个宏,且必须定义两个结构体。函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本。用不同类型的参数使用函数模板时,称为函数模板的实例化。函数模板的参数可以不止一个,

2024-08-21 13:22:49 1187

原创 C++内存管理

除了开空间还会调用构造函数和析构函数。在申请自定义类型的空间时,

2024-08-21 13:22:22 1002

原创 友元 / 内部类 / 匿名对象

的普通函数,但有权访问类的所有私有(private)成员和保护(protected)成员。尽管友元函数的原型有在类的定义中出现过,但是。

2024-08-20 13:15:21 940

原创 Linux进程状态

在操作系统中,会有大量的进程被创建,但是并不是所有的进程都在运行,于是便有了进程的状态的区分。在操作系统教材里面所描述的状态是所有操作系统都有的状态,但是名字可能不同,具体的实现还要看操作系统具体的实现方案。上图就是操作系统教材介绍的进程的几种状态。但是Linux的进程的状态分类就要比上图多。

2024-08-20 13:14:47 774

原创 初始化列表 / 隐式转换 / 静态

初始化列表给了初始值,如果没有初始值,在C++11中的打了补丁,给了缺省值,即在类声明的时候给的值,其实就是初始化时候要给的值,如果没有缺省值,那初始化就给默认值。

2024-08-19 09:16:28 925

原创 this指针 \ 默认成员函数 \ 重载 \ const

分析一个类型成员和初始化需求,需要我们写构造函数我们就自己写,不需要 ,就用编译器生成的。绝大多数场景下我们要自己写构造函数。并不是编译器生成的构造函数才叫默认构造函数,

2024-08-19 09:15:56 758

原创 C++类和对象认识

定义一个类需要使用关键字class,然后指定类的名称,并类的主体是包含在一对花括号中,主体包含类的成员变量和成员函数。定义一个类,本质上是定义一个数据类型的蓝图,它定义了类的对象包括了什么,以及可以在这个对象上执行哪些操作。// 类体:由成员函数和成员变量组成 };// 一定要注意后面的分号像上面写的栈的代码,成员函数的参数名和成员变量的名称可能相同,所以,对类中的成员变量进行一定规则的命名,便可以很好的区分class Dateint _year;// 或者class Date。

2024-08-18 13:49:57 721

原创 内联函数与auto关键字与nullptr

如果两个C文件都包含了此头文件,就会报链接错误。我们包含头文件,然后预编译的时候展开,展开后就相当于在此C文件定义了一个函数,两个C定义同一个函数,就会报错。因为在彼此。

2024-08-18 13:49:26 540

原创 排序(直接插入,希尔,选择,快排)

因为我们规定的右边先走,总是找到小的数才去找大的数,在没有找到小的数之前会一直走。找到以后交换,假设已经没有比keyi位置小的数,那么就会一直走到上次交换的那个数的位置,然后与keyi进行交换。假设找到小没有找到大,那么左边一直和右边相遇,那么直接进行交换,假设整体都比keyi大,那么右边一直走到begin,然后自己与自己交换。

2024-08-17 13:03:35 1568

原创 预处理详解

C语言设置了一些预定义符号,可以直接使用,预定义符号也是在预处理期间处理的。//1.预定义符号__FILE__ //进⾏编译的源⽂件地址__LINE__ //语句当前的行号__DATE__ //⽂件被编译的日期__TIME__ //⽂件被编译的时间__STDC__ //如果编译器遵循ANSI C,其值为1,否则未定义//但是__STDC__ 在VS中未定义的,VS不支持ANSI C,在Linux中才可以使用int main()//VS中STDC语法错误,但是这个却可以。

2024-08-17 13:02:22 649

原创 C语言文件操作

磁盘上的文件就是文件。例如电脑当中的C盘内放入的文件夹内的内容就是文件。但是在程序设计中,我们一般谈的文件有两种:程序文件、数据文件(从文件功能的角度来分类的)。

2024-08-16 13:29:05 968

原创 动态内存管理与柔性数组

C99中,结构体中的最后一个元素允许是未知大小的数组,这就叫作柔性数组int i;int a[0];//柔性数组成员,也可以写int a[];结构体成员a数组,它的数组大小是没有确定的,将来如果需要可以大也可以小。有些编译器支持a[0]这种写法,有些编译器支持a[ ]这种写法,具体取决编译器。

2024-08-16 13:28:38 1131

原创 (自定义类型)枚举

枚举顾名思义就是一一列举。把可能的取值一一列举。比如我们现实生活中:一周的星期一到星期日是有限的7天,可以一一列举性性别有:男、女、保密,也可以一一列举月份有12个月,也可以一一列举三原色,也是可以意义列举enum Day//星期Mon,Tues,Wed,Thur,Fri,Sat,Sunenum Sex//性别MALE,FEMALE,SECRETenum Color//颜⾊RED,GREEN,BLUE以上定义的enum Dayenum Sex。

2024-08-15 19:17:40 341 1

原创 (自定义类型)联合体union(共用体)

实设计的很简单,用起来也方便,但是结构的设计中包含了所有礼品的各种属性,这样使得结构体的大小就会偏大,比较浪费内存。以同样的方法分析第二个联合体Un2的大小就是,最大对齐数是4,最大成员大小是14,所以最终的空间大小是16。的,这样一个联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)。上述代码Un1中 c 的最大对齐数应该是他的成员类型的对齐数,就是1,默认是8,那么取1。当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。说明我们赋值的44被修改了。

2024-08-15 19:16:34 785

原创 (自定义类型)结构体以及结构体的存储

可以在声明的同时直接创建变量,也可以声明以后再创建变量。

2024-05-23 13:18:11 903

原创 STM32入门周边知识(为什么要装MDK,启动文件是什么,为什么要配置时钟,pack包是什么,51内核与32内核的区别等等)

之前学习微机原理的时候知道CPU内部有通用寄存器和段寄存器等等一些寄存器,但是学习32的寄存器配置的时候发现有好多寄存器,因为之前学习说过寄存器存在的很少,速度很快,但是现在却出现了很多寄存器。搜索后发现,其实是内存中有一些存外设地址的内存块,说是寄存器配置,其实配置的还是在内存里面,并不是真正的寄存器。

2024-05-10 17:52:34 1388

原创 数据在内存中的存储,大小端,浮点数

超过一个字节的数据在内存中存储的时候,就有存储顺序的问题,我们要怎样在内存中存放数据呢。按照乱序正序还是倒序呢?计算机只采取了两种方式,按照不同的存储顺序,我们分为大端字节序存储和小端字节序存储。数据的低位存在高地址称为大端字节序存储。数据的低位存在低地址称为小端字节序存储。如图正在写博客的这台电脑就是小端存储。因为位于低位的01存放在了低地址0x003EFD34。为什么会有大小端模式之分呢?

2024-04-28 18:12:04 871

原创 C语言内存函数及模拟实现

函数memcpy从source的位置开始向后复制num个字节的数据到destination指向的内存位置。这个函数在遇到’\0’ 的时候并不会停下来。如果source和destination有任何的重叠,复制的结果都是未定义的。for (i = 0;i < 10;从 str2 复制 n 个字符到 str1,但是在重叠内存块这方面,memmove() 是比 memcpy() 更安全的方法。

2024-04-28 16:32:33 537 1

原创 字符串函数及其模拟实现

函数介绍:字符串以’\0’作为结束标志,strlen函数返回的是在字符串中’\0’前面出现的字符个数(不包含’\0’)。参数指向的字符串必须要以’\0’ 结束。注意函数的返回值为size_t,是无符号的实现字符串拷贝,左参数是目标字符串的首地址,右参数是源字符串的首地址。源字符串必须以‘ \0 ’ 结束。strcpy会将源字符串的‘ \0 ’拷贝到目标空间中。目标空间足够大,以确保能存放源字符串。目标空间必须可变。如果目标空间不够大,那么就会造成非法写入,然后报错。

2024-04-27 18:51:12 930 1

原创 字符分类函数与字符转换函数

C语言中有一系列的函数是专门做字符分类的,也就是一个字符是属于什么类型的字符的。这些函数的使用都需要包含一个头文件是。上面的代码,我们将小写转大写,是-32完成的效果,有了转换函数,就可以直接使用tolower函数。通过返回值来说明是否是小写字母,如果是小写字母就返回非0的整数,如果不是小写字母,则返回0。代码演示:字符串中的小写字母转大写,其他字符不变。是能够判断参数部分的c是否是小写字母的。具体用法在Cplusplus中有介绍。使用库函数转换就是这样的。

2024-04-25 16:52:09 313

原创 C语言生成随机数

如果再深入了解⼀下,我们就不难发现,其实rand函数⽣成的随机数是伪随机的,伪随机数不是真正的随机数,是通过某种算法生成的随机数。真正的随机数的是无法预测下一个值是多少的。程序中在调用rand函数之前先调用srand函数,通过srand函数的参数seed来设置rand函数生成随机数的时候的种子,只要种子在变化,每次生成的随机数序列也就变化起来了。rand函数会返回⼀个伪随机数,这个随机数的范围是在0~RAND_MAX之间,这个RAND_MAX的大小是依赖编译器上实现的,但是大部分编译器上是32767。

2024-04-20 19:07:16 481

原创 C语言整型提升

C语言中整型算数运算总是以整型类型的精度来进行的。表达式中的字符和短整型操作数在使用之前被 转化为普通整型,这种转换称为整型提升。

2024-04-20 11:25:28 1073

原创 二叉树的遍历方式

下面是三种遍历的代码和计算树的大小,计算叶子的个数,树的高度和计算k层结点的个数,都是递归思想。前序遍历:根结点 —> 左子树 —> 右子树。后序遍历:左子树 —> 右子树 —> 根结点。中序遍历:左子树—> 根结点 —> 右子树。

2024-03-27 18:02:44 207

原创 堆排序(附降序代码)

这样就是一个升序的数组了。之前想过可以建立小堆进行排序,也是首尾交换,但是放在数组里面就算是降序了,所以这种方式适合降序排列数组的时候使用。

2024-03-24 15:48:58 634

原创 堆TOP K问题

建立一个k个数的小根堆,因为是找最大的k个数,所以要建立小根堆,这样每次都是当前最大的k个数里面最小的在堆顶,当前的数和堆顶比较,如果比堆顶大,就和堆顶交换,然后向上调整,如此循环最后得到最大的k个数。如果想要找出一组数据中的最大的k个值,如果直接建堆时间复杂度时O(n*logn),当数据量大的时候,不仅时间复杂度高,而且空间复杂度也很高为O(n),加入数据是1亿个,就会占用大量的空间。不是建立大根堆,如果建立大根堆,那么堆顶如果是最大的,那么就会一直卡着,后面的数据无法进入到堆里面。

2024-03-24 14:50:13 360

原创 树,二叉树与堆

树结构相对线性表就比较复杂了,要存储表示起来就比较麻烦了,既然保存值域,也要保存结点和结点之间的关系,实际中树有很多种表示方式如:双亲表示法,孩子表示法、孩子双亲表示法以及孩子兄弟表示法等。(一种二叉树)使用顺序结构的数组来存储,需要注意的是这里的堆和操作系统虚拟进程地址空间中的堆是两回事,一个是数据结构,一个是操作系统中管理内存的一块区域分段。需要注意的是二叉树和堆都是对数据的描述和存储的方式,不同的情况选择不同的存储方式,堆就是其中一种。:一个节点含有的子树的根节点称为该节点的子节点。

2024-03-23 20:45:05 974 1

原创 队列的实现(C语言链表实现队列)

队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。因为数组头出了以后要把所有数据都往前挪动一位。只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out)出队列:进行删除操作的一端称为队头。入队列:进行插入操作的一端称为队尾。

2024-03-23 17:47:25 166

原创 栈的实现(C语言数组栈)

栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端。称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出的原则。栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。栈的删除操作叫做出栈。

2024-03-23 17:33:22 349

原创 C++引用

引用被称为变量的别名,它不能脱离被引用对象独立存在,这是在高级语言层面的概念和理解,并未揭示引用的实现方式。常见错误说法是“引用“自身不是一个变量,甚至编译器可以不为引用分配空间。引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。实际上,引用本身是一个变量,只不过这个变量的定义和使用与普通变量有显著的不同。但是引用自身占用内存,引用也是一种变量。在C语言中我们要交换两个数是这样的。如果用引用作为参数的话就是这样的。

2024-03-21 17:16:21 242

原创 C++基本认识

实际项目通常是由多个头文件和多个源文件构成,而通过C语言阶段学习的编译链接,我们可以知道,【当前a.cpp中调用了b.cpp中定义的Add函数时】,编译后链接前,a.o的目标文件中没有Add的函数地址,因为Add是在b.cpp中定义的,所以Add的地址在b.o中。所以链接阶段就是专门处理这种问题,链接器看到a.o调用Add,但是没有Add的地址,就会到b.o的符号表中找Add的地址,然后链接到一起。而C++是通过函数修饰规则来区分,只要参数不同,修饰出来的名字就不一样,就支持了重载。这样写是不对的,必须。

2024-03-20 18:51:38 434

原创 C++认识及域的概念

命名空间域不仅可以定义变量,还可以定义结构体,定义函数等对于结构体的定义就是命名空间的名字要写在中间int x = 10;int val;int main()错误的。

2024-03-20 14:04:55 478

原创 Linux进程初步理解

进程信息被放在一个叫做进程控制块的一个数据结构(struct PCB)中,可以理解为进程属性的集合,其中包括了内存指针,指向程序所在的内存地址。无参数,返回值为pid_t,子进程的返回值是0,父进程的返回值为其子进程的pid,返回值为负数则创建失败。,该文件夹包含了所有的进程信息,每形成一个进程该目录下就会形成以该进程pid命名的文件夹。每个进程都有唯一的进程标识符,叫做PID,PID是结构体中的一个无符号整型。课本上讲的是,进程是程序的一个执行实例,正在执行的程序。:获得当前进程的父进程pid。

2024-03-11 18:06:08 310

空空如也

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

TA关注的人

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