- 博客(48)
- 收藏
- 关注
原创 【C++进阶五】list深度剖析
STL标准库中的list是一个带头双向循环链表和vector不同,list没有支持[ ]访问以及resize和reserve容量相关的函数,这是因为list不能随机访问数据,并且list的迭代器的底层不是指针和vector一样,list也有两个模板参数,但是第二个模板参数是和内存效率相关的,所以现在的学习暂时不用管它(它有缺省值)
2025-04-05 17:54:32
611
原创 【C++进阶九】继承和虚继承
继承是代码复用的一种手段,子类继承父类就能使用父类中的变量比如我们同时定义student类和teacher类二者有大量的相同信息,因此可以把共同信息提取出来单独形成一个类string sex;int age;int height;只用在实现student类和teacher类时继承person类即可class Student : public Person//继承protected:int _stuid;//学号class Teacher : public Person//继承。
2025-04-03 22:03:49
1006
原创 【C++进阶四】vector模拟实现
但是又因为我们实现的size()是_finish - _start,所以_finish=_start+ _finishi - _start = _finish。我们写的push_back拷贝用的是memcpy,对于内置类型,tmp出了作用域也不用处理,但对于自定义类型,tmp除了作用域还要被析构一次,一个空间总共。erase(it)后,it指向位置的意义就改变了,如果是连续的偶数,会导致后一个偶数没有被判断,也没有被删掉。因为begin()是传值返回,返回的是临时变量,具有常性,不能直接传给引用。
2025-04-02 21:11:59
981
原创 【C++进阶三】vector深度剖析(迭代器失效和深浅拷贝)
迭代器失效的本质原因是:扩容后start和finish的地址发生变化,指向原先位置的迭代器失效。
2025-04-02 18:26:11
837
原创 【C++进阶二】string的模拟实现
string底层是一个字符数组,为了跟库里的string区别,我们定义了一个命名空间将string类包含咋内。
2025-03-26 18:46:49
944
原创 【Linux进程七】程序地址空间
我们用下面的代码可以查看到一个事实int main()if(id == 0)//子进程执行的代码tmp = 200;while(1)printf("子进程tmp: %d,&tmp: %p\n",tmp,&tmp);sleep(1);if(id > 1)//父进程执行的代码while(1)printf("父进程tmp: %d,&tmp: %p\n",tmp,&tmp);sleep(1);return 0;子进程和父进程的地址一样,但却有两个值。
2025-03-20 23:13:28
1273
原创 【LInux进程六】命令行参数和环境变量
因为我们修改的环境变量表是bash内部的,每一次重新登陆账号都会依照家目录下的.bash_profile文件中的内容重新生成命令行解释器bash。后面继续输入任意字符串时,它会以空格为分割,分别打印出数组中下标为0,1,2的字符串,这些输出的字符串正是我们所输入的。获取不到本地变量的信息(命令行启动的进程都是shell和bash的子进程,而内置命令是由bash自己执行的)命令行启动的进程都是shell和bash的子进程,子进程的命令行参数和环境变量都是父进程传递的。代表这个数组的元素个数(指针的数量)
2025-03-18 23:31:35
970
原创 【C++进阶一】STL和string
string是表示字符串的字符串类,该类的接口与常规容器的接口基本相同,在此之上添加了一些专门用来操作string的常规操作。若len长度大于字符pos位置后的长度或者不给len值自动使用了npos, 则pos位置开始全的部删除。s.begin()代表开头的位置,s.begin()+5代表w的位置,在w之前插入字符!查找字符,找到了返回当前pos位置的下标,没有找到就返回npos(整形最大值)顾名思义是倒着走的迭代器,和反向迭代器相对应的是rbegin和rend函数。(像指针一样的类型,用法和指针相似)
2025-03-18 11:56:50
770
原创 【C++基础十】泛型编程(模板初阶)
tmp = a;a = b;b = tmp;tmp = a;a = b;b = tmp;a = b;b = temp;正常来说,对于不同类型的变量进行交换,需要实现不同的swap函数,这样实现有些太繁琐了为了解决相似函数的不同调用问题,C++提出泛型编程,编写与类型无关的通用代码,实现代码复用,即模板模板主要分为函数模板和类模板template <typename T1, typename T2,…,typename Tn>//一次性可以定义多个类型。
2025-03-17 12:29:56
800
原创 【C++基础九】内存管理(new和delete)
new自定义类型用法与内置类型相同在申请自定义类型的空间时,new会调用构造函数,malloc不会new可以初始化变量的内容class Apublic:: _a(a)~A()private:int _a;delete[]p1;return 0;delete会调用自定义类型的析构函数,而free不会delete面对不同的情况需要加上[ ],然而free不用考虑public:stack()//构造_top = 0;
2025-03-14 18:38:51
704
原创 【C++基础八】类和对象—末(初始化列表、友元和匿名对象)
内部类是一个定义在另一个类内部的类,内部类是一个独立的类,不属于外部类,不能通过外部类的对象访问内部类的成员(外部类对内部类,没有任何优越的访问权限)友元函数可以直接访问类的私有成员,它是定义在类外部的函数,不属于任何类,但需要在类的内部声明,声明时需要加friend关键字。构造函数中,为一个成员赋值,只能说对此成员赋初始值,不能称之为初始化,初始化列表才是真正初始化成员变量的地方。一个函数定义在类外,但又想访问类中的私有成员,只能将这个私有成员改成公有后再访问,但这种操作就破坏了类的封装。
2025-03-14 12:02:16
641
原创 【初阶三】认识C语言—下
define定义宏和我们之前的定义常量有一点相似//define定义宏//define定义宏 # define ADD(x , y)((x) +(y)) //Add后面括号里的x和y为参数,后面的((x)+(y))叫做宏的实现体 # include <stdio.h> int main() {//遇见Add()时就会自动把Add和里面的变量替换为后面的宏的实现体 printf("sum = %d\n" , sum);
2025-03-13 18:16:11
633
原创 【C++基础七】类和对象—下(拷贝构造和运算符重载)
类的对象d2实例化需要先调用构造函数,所以需要先传参数,把d1传给拷贝构造中d的这个过程属于传值调用,若两者为内置类型(int ,char ,double)会直接进行拷贝,但d1和d都是自定义类型date,所以会发生拷贝构造,默认构造函数是按照字节方式直接拷贝的,array指向的空间是动态开辟在堆区存储的,使用值拷贝的方式,s1和s2中的array指向的空间相同。由于拷贝中的d变成了d1的别名,d相当于d1本身,所以参数d1传给d的过程中, 不会发生拷贝构造。
2025-03-13 13:45:00
909
原创 【C++基础六】类和对象—中(构造和析构函数)
构造函数,,是用于初始化的函数函数名与类名相同无返回值对象实例化时自动调用对应的构造函数构造函数可以重载构造函数是特殊的成员函数,不能将它与普通函数对比构造函数的任务是初始化对象,而不是开辟空间创造对象class Datepublic:Date(int year, int month, int day)//含参的构造函数_day = day;Date()//无参的构造函数_month = 3;_day = 12;
2025-03-12 21:49:19
650
原创 【C++基础五】类和对象—上 (成员函数和this指针)
class className//类的定义与结构体类似,只不过将struct换成了class// 类体:由成员函数和成员变量组成//一定要注意后面的分号声明和定义都放在类里char* name;char* sex;int height;int age;void Print_Info()//打印学生的消息这个类的成员函数的声明和定义都在类中,编译器就可能把此函数当作内联处理只要是在类中定义的函数都会被看作内联(这只是给编译器一建议,具体会不会内当作内联要看代码长度)声明和定义分离。
2025-03-12 11:36:44
1061
原创 【C++基础四】内联函数和auto关键字
被inline修饰的函数被称为内联函数编译器会在编译时将内联函数展开展开后,没有函数调用建立栈帧的开销内联函数可以提升程序运行效率int main()return 0;从函数的反汇编代码可得知,调用一个函数,开辟栈帧时需要call指令内联函数:可以看到编译器直接将add函数内容放在了主函数里注意:debug模式下需要设置才能看到内联函数的反汇编。
2025-03-11 17:41:40
677
原创 【C++基础三】引用
引用不是定义新的变量,而是给已存在的变量取别名编译器不会为别名开辟内存空间,变量和别名共用同一块内存空间类型& 别名 = 已存在的变量;别名的值改变,也会影响本体变量的值。
2025-03-11 13:02:30
1038
原创 【C++基础二】缺省参数和函数重载
函数重载是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 / 类型 / 类型顺序)不同,常用来处理实现功能类似但数据类型不同的情况void Func(int i,char c) //函数1//...void Func(char c,int i) //函数2//...两个Func函数虽然重名,但可以同时存在,并且两个Func函数是不同的函数。
2025-03-10 20:43:42
642
原创 【C++基础一】C++介绍和命名空间
在C语言中,可能会遇见:自定义变量名与库函数命名冲突因为在库中有了rand这个函数,再定义另一个名为rand的变量或函数时,编译器分不清你想使用的是哪个randC++为了解决上述问题,更新出了命名空间的解决方式((C++兼容C语言的所有语法))定义命名空间,需要使用到namespace关键字,后面是命名空间的名字,再用{}划定范围//命名空间中可以定义变量/函数/结构体//函数//结构体int a[10];int num;
2025-03-10 15:27:26
1175
原创 【Linux进程五】进程优先级和进程间切换
CPU资源分配的先后顺序就是进程的优先级 (priority)优先级高的进程有优先执行的权利,配置优先级对多任务环境的Linux很有用,可以改善系统性能还可以把进程运行到指定的CPU上,这样就可以把不重要的进程安排到某个CPU上优先级:一定能获得申请的资源,只是要考虑得到资源的时间权限:要考虑是否有资格获得申请的资源ps - lps - alPRI:进程优先级,值越小优先级越高NI:优先级的修正值。
2025-03-09 16:04:29
1029
原创 【Linux进程四】僵尸进程和孤儿进程
我们之前提到过多种进程状态,僵尸进程本质就是死亡状态就和现实中的意外身亡相同,警察不会立刻将死者火化,而是要查明死亡原因给家属和社会一个交代,最后也会有家属处理后事Linux中的进程在死亡后也不会立刻销毁,会有其父进程处理后事当一个子进程还没有退出,但父进程先退出了,这时子进程被称为孤儿进程当一个孤儿进程出现,意味着没有父进程处理孤儿进程的PCB了,不处理就会占用操作系统的资源导致内存泄漏,所以操作系统会作为“干爹”给给孤儿进程“收尸”
2025-03-08 15:27:25
271
原创 【Linux进程三】进程的状态
当我们在互联网上下载资源时(将数据拷贝到磁盘),会遇到文件很大下载时间很长的情况,如果在下载时内存不足,操作系统就会杀掉一些进程保证自身存活,若恰巧将正在拷贝下载数据的进程杀掉,拷贝就会失效,因此才需要D状态。:当代码运行到scanf和cin时,系统等待用户输入,只要用户不输入,那么要访问的资源就没有就绪,代码无法继续与运行,这就是阻塞状态吗?操作系统管理的是进程的PCB块,那么很显然,进程状态就是PCB中的一个变量,可以使用宏定义来实现。将内存中的数据移动到外设上的操作是针对所有阻塞进程的。
2025-02-25 21:53:37
803
原创 【Linux进程二】子进程和fork函数
让数据在各个进程中私有一份,数据会在需要使用时被写时拷贝到PCB,在fork的返回值赋值给变量时,本质也是写入,所以会发生写时拷贝,因此不同进程执行的代码中的变量的id不同。很明显reutrn也是代码,在出现两个进程后才会执行,而父子局进程的代码是共享的,二者都会执行一次return,因此fork有两个返回值。一个父进程可以创建很多子进程,但每个子进程都有唯一一个父进程,确保了父进程pid的唯一性,便于父进程管理它的子进程。fork函数创建子进程时,操作系统会以父进程为模板创建子进程的PCB。
2025-02-24 22:31:39
708
原创 【Linux进程一】进程的概念
当进程在链表中时,会等待CPU寻找PCB处理,而CPU不能同时处理多个进程,因此需要进程排队,这就是进程队列。当使用ps指令查看进程的pid时,我们还可以在首列看到一个ppid,这就是父进程。来终止进程,这只能在运行程序的地方使用,并且只能在前台结束进程,对后台进程无效。便可观察到进程的pid了(左边窗口会执行死循环一直打印,右窗口观察)写代码时,想要运行的程序自动获取自己的pid,就不能用ps指令了。比如PCB既在管理PCB的链表上,又在进程队列中。在程序中想查看本身的父进程ppid,可使用函数。
2025-02-23 12:50:35
520
原创 【Linux基础八】计算机体系结构(冯诺依曼和操作系统)
因此冯诺依曼体系拥有高价值设备用于处理复杂数据,又有低价值设备存储数据和接收数据,二者使该体系下的计算机在价格适中的情况下拥有较高的效率,综合性价比高。是利用磁效应来存储数据的设备,比内存的存储容量更大,价格更便宜,但是读写速度较慢,即使在断电的情况下,数据依然可以被保存。是利用电流来实现存储的半导体存储器,能够快速读写,但是价格相对较高,一旦断电,存储在内存中的数据就会丢失。内存的速度非常快,可以与CPU的速度匹配,CPU为了总体效率不被拉低,就不会。在硬件层面上,CPU只和内存交互,
2025-02-20 18:27:30
814
原创 【Linux基础七】Linux开发工具—下(make和makefile)
当我们编译代码时,会输入当我们删除可执行程序时,会输入2.make和makefile的使用创建makefile文件,vim开始编辑,如下是比较标准且基础的格式(test.c编译为mybin 和 清理mybin两个过程)底行模式下wq退出后,makefile已经创建结束,准备一个任意代码的test.c文件放在同一目录下使用指令:成功得到mybin程序后,清理掉mybin,使用指令:将编译指令和清理指令交换位置执行make,再执行make mybin,可以看到结果是否是伪目标有什么区
2024-12-14 12:19:36
778
原创 【Linux基础六】Linux开发工具—中(gcc和g++)
Linux系统不看分文件后缀,不代表linux下的各种程序不看而gcc和g++就是看后缀的gcc:C语言编译器,只能编译C语言g++:C++编译器,C/C++都能编译gcc test . c - o 程序名gcc test。c -std=99。
2024-12-12 12:06:31
937
原创 【Linux基础五】Linux开发工具—上(apt和vim)
不同的 Linux 发行版使用不同的包管理工具,apt 是 Debian 和 Ubuntu 系列发行版的包管理工具,使用 apt 可以轻松地安装、更新和删除软件包。界面下方出现insert即成功进入插入模式,我们尝试输入简单的代码,但保存代码需要底行模式。当我们只想在原先的代码上做修改,不想增加或删除时使用以下指令,从命令模式进入替换模式。现在出现的界面就是命令模式,这种模式无法输入内容,只能输入命令进入其他模式。当我们要写注释时需要视图模式的帮助,从命令模式输入指令进入视图模式。
2024-12-09 14:48:39
1278
原创 【初阶二】认识C语言—上
认识C语言讲的是C语言的基础知识,目的是让大家认识这些知识,后续文章会把这些知识深入讲解,知识点很多,篇幅原因分为上下两篇。
2024-11-14 00:56:13
739
原创 【初阶一】初识c语言
C语言是一门经久不衰的计算机编程语言,有句话叫:万物起源于C,学好C语言能为以后的编程学习打下坚实的基础我推荐使用Visual Studio 2022作为编译器具体安装教程可以跳转后方链接去B站观看教学VS2022安装教程,当我们安装好编译器后第一步:创建一个项目第二步:创建源文件到这里就创建结束了什么是GitHub和Gitee?GitHub和Gitee都是可以存放个人代码的网站,类似于一个代码库,但是GitHub是国际版的,使用起来有诸多不便,在国内直接使用Gitee就好,网站可以看到所
2024-11-12 20:52:48
1157
原创 C++ 仿函数和模板(非类型模板参数和模板特化)
模板通常可以实现多种类型的相同代码,但部分特殊类型代码所得结果与我们预想中不符合。当传递指针时,会调用第二个特化后的模板,从而比较指针内容的大小。特殊情况我传指针,想比较的是指针内容,但比较的是指针地址。可见仿函数的使用可以很方便地更改库中某些函数升降序。:当第二个参数是int时就会调用此偏特化。仿函数的本质是一个重载了()的。优先级队列的类模板中 这个。就是一个仿函数,控制优先级队列。将所有模板参数全部确定。
2024-10-11 16:58:51
566
原创 C++static总结
1.静态局部变量在局部变量前面加上static,使其成为静态局部变量特点:(1)在程序第一次执行到该对象声明的时候初始化(仅此一次)(2)一般在声明的时候初始化,若没有显式初始化,默认初始化为0(3)调用范围是声明该函数的作用域(局部作用域)(4)延长局部变量的生命周期,直到程序运行结束。
2024-01-23 21:15:40
525
1
原创 六大排序——冒泡、插入、希尔、选择、快排、堆排
默认首元素已经有序,取下有序序列的下一位元素作为tmp,向前扫描有序序列,若tmp小于前一位的元素,则该元素后移一位,然后tmp继续与前面的元素比较,直到tmp大于前一位的元素,则插入该元素后面的下标位置,若tmp比全部有序序列的元素都要小,则直接插入到下标为零的位置,重复前面的步骤直到全部元素排列为升序。的元素就停下,将end上的值放到坑hole的位置上,然后将end作为新的坑hole,随后begin向右走,遇到比key。的两个元素进行比较,每次比较之后,保证较大元素在较小元素的下一位,
2023-10-15 16:11:52
179
1
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人