- 博客(46)
- 问答 (1)
- 收藏
- 关注
原创 leetcode -- 逆波兰表达式 -- 利用C++11lambda表达式的解法
【代码】leetcode -- 逆波兰表达式 -- 利用C++11lambda表达式的解法。
2025-03-27 08:51:13
219
原创 C++11中引入的比较常用的新特性讲解(上)
在2003年C++标准委员会曾经提交了一份技术勘误表(简称TC1),使得C++03这个名字已经取代了C++98称为C++11之前的最新C++标准名称。不过由于C++03(TC1)主要是对C++98标准中的漏洞进行修复,语言的核心部分则没有改动,因此人们习惯性的把两个标准合并称为C++98 / 03标准。从C++0x到C++11,C++标准10年磨一剑,第二个真正意义上的标准珊珊来迟。
2025-03-26 22:49:48
720
原创 C++ AVL树详解(含模拟实现)
{}// 该节点的左孩子// 该节点的右孩子// 该节点的双亲T _data;int _bf;// 该节点的平衡因子。
2025-02-27 22:19:55
777
原创 C++ 中的多态详解
多态是在不同继承关系的类对象,去调用同一函数,产生了不同的行为。比如Student继承了Person。Person对象买票全价,Student对象买票半价。那么在继承中要构成多态还有两个条件:必须通过基类的指针或者引用调用虚函数。被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写。public:// 注:虚函数的 virtual 跟继承那一章节中的虚拟继承的 virtual 没有任何关系,只是刚好都用 virtual 这个单词表示罢了。
2025-02-21 17:55:40
949
原创 C++ 中的继承详解(下)
1. 很多人说C++语法复杂,其实多继承就是一个体现。有了多继承,就存在菱形继承,有了菱形继承就有菱形虚拟继承,底层实现就很复杂。所以一般设计多继承时,一定要注意不要设计出菱形继承。否则在复杂度及性能上都有问题。2. 多继承可以认为是C++的缺陷之一,很多后来的语言都没有多继承,如Java。3. 继承和组合(都是一种复用)public继承是一种is-a的关系。也就是说每个派生类对象都是一个基类对象。组合是一种has-a的关系。假设B组合了A,每个B对象中都有一个A对象。
2025-02-21 17:24:11
592
原创 C++ 中的继承详解(上)
补充:封装的层次(实际上有很多层的,这里只写两层)第一层:数据和方法放到一起,把想给你访问的定义成公有,不想给你访问的定义成私有和保护。第二层:把一个类型放到另一个类型里面,通过 typedef 或 成员函数 调整,封装出另一个全新的类型 (例如反向迭代器、栈、队列)。继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我
2025-02-21 17:02:32
721
原创 动态库加载(可执行程序和地址空间)
补充:我们用语言(C、C++...)编写的程序,它的源代码中的 变量名、函数名 ,在它被翻译成二进制的代码之后,这些 变量名、函数名 就都不在了,变成了“地址”。注:cpu 从 pc 指针中拿到虚拟地址之后,然后就去页表中查该虚拟地址对应的物理地址,然后再根据物理地址去内存中执行相应的代码。补充:我们一般在 Linux 当中形成的可执行程序,它的格式叫做:ELF格式的可执行程序。补充:虚拟地址空间这个概念,不是 OS 独有的,它还需要有 编译器支持、加载器支持。补充:动态库也叫做共享库。
2025-02-20 18:01:48
794
原创 动态库和静态库(Linux环境)
补充:80%以上的可执行程序采用的都是动态链接(因为静态链接形成的可执行程序内存大),所以动态库非常重要,一旦被误删了,很多程序就直接跑不了了(因为程序在运行时,需要加载动态库,而静态库则不需要加载(因为静态库的内容已经拷贝到了程序中了))。补充:gcc/g++ 默认是认识 C/C++ 的库的,但是别人写的(第三方提供)的库,gcc/g++ 默认是不认识的,要想使用这些第三方提供的库,就要在后面加个 -l 选项,然后在 -l 选项后面加上(有无空格都行)库的真正的名字。(只要知道起始地址和偏移量就够了)
2025-02-20 17:48:36
635
原创 C++ -- stack的模拟实现 && 介绍适配器模式
是满的就先将 i-=第一个buff的数据个数,再执行接下来的操作(如果第一个buff是满的,就直接走下面的操作),这个值就在 第 i/N 个 buff里的 第 i%N 位置,要尾插的时候,就先看一下最后一个buff满了没?然后,它的[]的效率不够极致,比vector[]的访问效率慢很多(可以写个 Test_OP 测试一下,就是同样的数据分别存在 vector 和 deque 两个容器中,然后排序),在大量使用 [] 的情况下,deque 的 [] 效率大概只有 vector 的 [] 的一半。
2025-02-15 13:59:29
505
原创 反向迭代器(reverse_iterator)的模拟实现
在C++中,每一种容器的反向迭代器(如果有迭代器的话)并不是都单独去写了一种放在了那个容器中,而是统一的做了一个反向迭代器的模板。ex:forward_list(单向链表的迭代器) // 只支持++ // 单向迭代器没有对应的反向迭代器(因为它不支持--)它会根据被传过来的容器的迭代器来相应的去生成对应的反向迭代器。ex:vector/deque // 支持++、--、+、-ex:list(双向链表的迭代器) // 支持++、--补充:迭代器从性质方面的分类。补充:迭代器从功能方面的分类。
2025-02-15 13:51:42
196
原创 进程替换详解(Linux)
补充:const char *file:用户可以不传要执行的文件的路径(但是文件名要传),就是直接告诉 exec* ,我要执行谁就行了。用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序。调用exec系列的函数并不创建新进程,所以调用exec前后该进程的id并未改变。后面的参数的传参方式:在命令行中,是怎么执行这些命令的,那就怎么传参。
2025-02-11 15:57:44
1009
5
原创 Linux调试器-gdb的使用简介
a.调试工具终究只是工具,它的核心作用就是方便我们找到问题。(解决问题还是要靠我们自己)先直接用眼睛看,有的问题很简单,眼睛扫一扫就能看出来问题在哪用打印,在某些你觉得会出问题的地方,用一下打印注释一部分,运行一部分调试。
2025-01-23 19:57:00
823
原创 类与对象(下)
有默认构造的话,你就可以不用在初始化列表的位置写(也就是不需要你传参)(注意:如果你要在初始化列表显示写,那么你必须要在其相应的类中显示写一个能传参的构造函数(因为编译器默认生成的构造函数无参))。3. 尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,一定会先使用初始化列表初始化。4. 成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关。
2025-01-23 14:07:06
890
原创 算法的时间复杂度和空间复杂度
就是保留影响最大的一项即可(系数也可以忽略掉,算的就是一个量级),去掉了那些对结果影响不大的项。使用大O的渐进表示法以后,Func1的时间复杂度为:O(N^2)。另外有些算法的时间复杂度存在最好、平均和最坏情况:最坏情况:任意输入规模的最大运行次数(上界)平均情况:任意输入规模的期望运行次数最好情况:任意输入规模的最小运行次数(下界)ex:在一个长度为N数组中搜索一个数据x最好情况:1次找到最坏情况:N次找到平均情况:N/2次找到。
2025-01-21 13:50:40
1070
原创 类与对象中的六大默认成员函数万字详解
在现实生活中,可能存在一个与你一样的自己,我们称其为双胞胎。那在创建对象时,可否创建一个与已存在对象一某一样的新对象呢?
2025-01-21 13:29:13
1332
1
原创 类与对象(上)
/类体:由成员函数和成员变量组成//一定要注意后面还有个分号class为定义类的关键字,ClassName为类的名字,{}中为类的主体,注意类定义结束时后面分号不能省略。类体中的内容称为类的成员:类中的变量称为类的属性或成员变量;类中的函数称为类的方法或者成员函数。声明和定义全部放在类体中,需注意:成员函数如果在类中定义,编译器可能会将其当成内联函数处理。
2025-01-20 15:11:08
900
原创 C++入门(下)
在早期C/C++中auto的含义是:使用auto修饰的变量,是具有自动存储器的局部变量,但遗憾的是一直没有人去使用它,大家可思考下为什么?C++11中,标准委员会赋予了auto全新的含义即:auto不再是一个存储类型指示符,而是作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得。return 10;int a = 10;auto b = a;// auto e;// 无法通过编译,使用auto定义变量时必须对其进行初始化注意:使用auto。
2025-01-15 22:37:31
1033
原创 C++入门(上)
定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}中即为命名空间的成员。注:命名空间域里的变量还是全局变量,但它们的名字就不会冲突了。注:命名空间域不影响变量的生命周期。注:1.命名空间中可以定义变量/函数/结构体。2.命名空间可以嵌套3.同一个工程中允许存在多个相同名称的命名空间,编译器最后会将同名的命名空间合并成一个命名空间!!!!!注意:一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中。
2025-01-15 21:12:07
685
原创 Linux中一些与时间相关的指令
date -s “01:01:01 2008-05-23” -- 这样可以设置全部时间。date -s “2008-05-23 01:01:01” -- 这样可以设置全部时间。date 指定格式显示时间: date +%Y:%m:%d -- 显示的是当前时间。date -s “01:01:01 20080523” -- 这样可以设置全部时间。date -s “20080523 01:01:01” -- 这样可以设置全部时间。date -s 01:01:01 -- 设置具体时间,不会对日期做更改。
2025-01-02 18:07:52
293
原创 Linux中常用的基本指令和一些配套的周边知识详解
如何看待这么多指令???记不住怎么办???首先,指令不用刻意去记!-- 见多了,写多了自然就记住了其次,周边知识才是重点!!!1.clear --2.adduser 用户名 ----3.passwd 用户名 ----5.userdel - r 用户名 --7.which 某个指令的名称 --8.alias 别名='某个指令' --9.stat 文件名 --补充:什么是一个文件的ACM时间?(通过stat指令显示出来该文件的三个时间)
2025-01-02 18:03:29
715
原创 常见的排序算法(2万字)详解+代码实现
ex:直接插入排序是一种简单的插入排序法,其基本思想是:把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列。ex:实际中我们玩扑克牌时,给牌排序就用到了插入排序的思想。
2024-12-21 16:09:38
1167
原创 二叉树 -- 堆(详解)
k(n-1) },把它的所有元素按完全二叉树的顺序存储方式存储在一个一维数组中,并满足:ki=k(2*i+2) ) (i = 0,1,2…,)则称为小堆(或大堆)。因为向下调整需要先保证该节点的左右子树已经是大/小堆了,才能向下调整,所以先从尾开始调整(思路就是从尾开始调整,从最后一个叶结点的父结点开始调整,叶结点无需调整,因为叶结点可以看作是一种特殊的子树,既可以当作大堆,也可以当作小堆)。
2024-12-21 15:28:08
760
原创 程序的编译(预处理操作)+链接 详解(C语言)
语法:#define name(名字) stuff(内容)#define reg register // 为 register这个关键字,创建一个简短的名字;) // 用更形象的符号来替换一种实现case // 在写case语句的时候自动把 break写上。// 一种奇葩的写法// 注:如果定义的 stuff过长,可以分成几行写,除了最后一行外,每行的后面都加一个反斜杠(续行符)。注:在预处理阶段,这些符号都会被直接替换。注:#define定义标识符的时候,最后面不要加上;
2024-11-30 17:02:21
897
原创 C语言 -- 文件操作详细介绍
1.磁盘上的文件就是文件。2.但是在程序设计中,我们一般谈的文件有两种:程序文件、数据文件--这是从文件功能的角度来分类的。
2024-11-28 21:34:00
825
1
原创 C++中list容器的特性及使用介绍(超详细!!)
1.1 list的介绍list文档链接:kw=list注:C++库里自带的list是带头双向循环链表1. list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。2.list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过两个指针分别指向其前一个元素和后一个元素。3. list与forward_list(单向链表)非常相似:最主要的不同在于forward_list是单链表,只能朝前迭代,已让其更简单高效。
2024-05-08 13:44:18
882
原创 二叉搜索树介绍(C++)
如果找的是 左子树的最大结点(也就是左子树的最右结点) 来替换的话,那么在交换完这两个结点的值,删除掉这个最右结点后,还要记得让这个最右结点的双亲结点指向这个最右结点的左子树(如果这个最右结点有左子树的话)。情况d:替换法,找一个结点的值替代这个要删除的值,这个用来替代的值就是 左子树的最大节点 或者 右子树的最小节点,这样才能保证删除之后,这还是一颗搜索树。情况c:删除该结点且使被删除节点的双亲结点指向被删除结点的右孩子结点--直接删除。若它的右子树不为空,则右子树上所有节点的值都大于根节点的值。
2024-05-04 16:58:17
556
原创 C++中map和set的介绍和应用总结
set文档介绍链接:kw=set大致内容:1. set是按照一定次序存储元素的容器2. 在set中,元素的value也标识它(value就是key,类型为T),并且每个value必须是唯一的。set中的元素不能在容器中修改(元素总是const),但是可以从容器中插入或删除它们。3. 在内部,set中的元素总是按照其内部比较对象(类型比较)所指示的特定严格弱排序准则进行排序。
2024-05-04 16:07:31
785
2
原创 C++中string类的模拟实现(超详细!!)
浅拷贝:也称位拷贝,编译器只是将对象中的值拷贝过来。如果对象中有管理资源,最后就会导致多个对象共享同一份资源,当一个对象销毁时就会将该资源释放掉,而此时另一些对象不知道该资源已经被释放,以为还有效,所以当继续对资源进项操作时,就会发生访问违规的问题。就像一个家庭中有两个孩子,但父母只买了一份玩具,两个孩子愿意一块玩,则万事大吉,万一不想分享就 你争我夺,玩具损坏。给每个对象都独立分配一份资源,不用和其他对象共享一份资源,解决了浅拷贝中因多个对象共享一块资源而导致的访问违规的问题。
2024-03-11 13:46:35
532
3
原创 C++中的内存管理
int _val;,_val(val);{}struct ListNode* CreateListNode(int val) //以前C语言创建一个结点的做法if(!newnode)//...ListNode* CreateList(int n) //假设要创建一个长度为n的链表,用C++的方式//哨兵位,不然下面还需要判空int val;//尾指针printf("请依次输入%d个结点的值:",n);//注:这里用C语言的printf方便点,用cout还有分几段进行打印。
2024-03-04 13:04:01
1588
4
原创 leetcode--设计循环队列详解
2.多开一个位置,不用来存放数据,只用来判断空还是满(满的时候就是(back+1)%(k+1)==front)在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。enQueue(value): 向循环队列插入一个元素。deQueue(): 从循环队列中删除一个元素。循环队列的一个好处是我们可以利用这个队列之前用过的空间。答:(两种方法,本文使用第2种方法,多开一个位置)isEmpty(): 检查循环队列是否为空。isFull(): 检查循环队列是否已满。
2023-12-08 22:37:37
107
原创 数据结构--线性表--顺序表和链表
不带头单向不循环链表只适合头插、头删,进行其他的操作效率都不高不带头单向不循环链表只有一个next,所以要注意不带头单向不循环链表的相交不可能是一个X型,两个不带头单向不循环链表相交一定是Y型。
2023-12-07 20:44:07
417
1
原创 C语言自定义类型详解(结构体+位段+枚举+联合)
int x;int y;}p1={1,2};int data;//结构体的嵌套初始化//结构体的嵌套初始化int main()int a=10;int b=20;//通过.结构体成员名的方式可以不按顺序初始化return 0;这些都是正确的结构体变量的定义和初始化。位段的声明和结构体是类似的,但有两个不同:1、位段的成员必须是int、unsigned int或signed int。
2023-10-22 19:43:43
151
7
原创 C语言部分内存操作函数详解+模拟实现
注:1、本文中所提到的4个内存操作函数的头文件均为<string.h>2、本文中所用例子均为本人在VS2022 Debug X86的环境下测试所得。
2023-09-25 19:37:49
222
6
空空如也
蓝桥杯题库里的问题(用C++写的代码)
2024-03-05
代码编译的没问题,为什么算出的都是无结果(这个是有解的)?不知道哪里有问题
2023-04-05
这位什么错啊?(刚开始学c)
2023-03-30
TA创建的收藏夹 TA关注的收藏夹
TA关注的人