C/C++学习记录
文章平均质量分 86
包括C语言进阶内容,C++入门到C++进阶,数据结构等内容
与你日常
擅长C/C++和数据结构,Linux系统编程,Linux网络编程,MySQL数据库,Git企业级开发
展开
-
STL标准模板库——string模拟实现
string的迭代器其实就是一个指针,但不是每个容器的迭代器都是指针,以后的list,map和set等等链式数据结构的迭代器会被专门当作一个类来实现,以此使他们的迭代器适应更复杂的功能,这个等以后实现的时候再说。C语言中,字符串以‘\0’作为结尾,为了方便操作,C标准库也提供了一些字符串系列的库函数,但是因为这些库函数是和字符串分开的,底层空间需要用户自己管理,而且容易越界访问。,如果要拷贝大的字符串刚好有个\0就会导致数据丢失,memcpy是根据size大小来拷贝,所以用memcpy拷贝。原创 2023-10-02 15:38:26 · 112 阅读 · 1 评论 -
C++入门,C++基础
定义命名空间需要用到关键字namespace,后面跟命名空间的名字,然后接一对{}即可,{}内是命名空间的成员namespace My_Namespace//前面是关键字,后面是名字一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限与该命名空间中。原创 2023-09-17 15:00:30 · 64 阅读 · 3 评论 -
C++标准模板库——Stack和queue
1,队列我们在学习数据结构的时候已经了解过了,它是一种“先进后出,后进先出”的一种数据结构2,但与C语言不同,STL将栈当作一种适配器来使用,专门用在具有后进先出操作的上下文环境中,只能从容器的一端进行元素的插入和删除,关于适配器下面会有详细讲解3,stack是作为容器适配器被实现的,所以stack的底层容器可以是任何标准的容器类模板或者一些其他特定的容器类,这些容器支持以下操作:①empty:判空操作②back:获取尾部元素操作③push_back:尾部插入元素操作。原创 2023-10-25 19:56:18 · 355 阅读 · 2 评论 -
c++面向对象三大特性——多态
在类中,被virtual关键字修饰的成员函数称为虚函数public://虚函数cout原创 2023-09-11 19:36:35 · 129 阅读 · 1 评论 -
C语言进阶——数据的存储
大端存储模式数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中小端存储模式数据的低位保存在内存的低地址中,而数据的高位,保存在内存的高地址中为什么会有大小端模式之分呢?这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一 个字节,一个字节为8bit。但是在C语言中除了8bit的char之外,还有16bit的short型,32bit的long型(要看具 体的编译器),另外,对于位数大于8位的处理器,例如16位或者32。原创 2023-11-02 20:39:35 · 129 阅读 · 1 评论 -
C++面向对象三大特性 —— 继承
继承(inheritance)是面向对象程序设计的重要手段,它可以让程序员复用曾经写过的代码,在原有类保持其自身特性的基础上进行扩展,增加新的功能。继承呈现了面向对象程序设计的层次结构,为代码实现由简单到复杂提供了认知过程和途径。与曾经的函数复用不同,继承是类层次设计的复用。在一个类名后面加上“ : ”,后面再加上继承关系和另一个类名,组成继承class Aprotected://此处构成继承class B: public A //这里的B类称为派生类或子类,public称为继承关系,A称为基类。原创 2023-09-08 21:08:37 · 169 阅读 · 2 评论 -
C语言进阶——指针进阶(下)
关于指针进阶的基本知识已经在“C语言进阶——指针进阶(上)”中讲解完成,本篇文章主要是通过大量的sizeof和strlen练习来更加熟悉指针。原创 2023-11-06 14:13:46 · 91 阅读 · 1 评论 -
C++经典题目:栈的压入 弹出序列
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。2:如果相同:则pop栈顶元素并把i++,注意,在这之后需要继续比较因为有可能会连着好几个数字都相同。输入:[1,2,3,4,5],[4,3,5,1,2] 返回false。输入:[1,2,3,4,5],[4,5,3,2,1] 返回true。原创 2023-06-04 20:47:02 · 164 阅读 · 2 评论 -
C++——模板详解
函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型的不同产生对应的特定的类型版本。格式为template<typename T1,typename T2 ......,typename Tn>T Sum(T a,T b)//完成不同类型的相加int main()return 0;class Stack//注意此处Stack不是具体的类,时编译器根据实例化类型生成具体类的摸具,原因是T还没有被实例化public:_top = 0;~Stack()原创 2023-09-21 22:16:41 · 125 阅读 · 0 评论 -
c++面向对象三大特性——封装
将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。封装本质上是一种管理,让用户更方便使用类。比如,身为计算机使用者,我们不需要关系内部核心部件,主板上的线路如何布局,CPU如何设计,如何关联各种硬件等,我们只需要知道怎么通过鼠标和键盘和计算机交互即可。计算机在设计制造的时候,在外面套上外壳,隐藏内部的各种细节,仅仅对外提供开机,鼠标以及各种插孔等,对计算机进行封装,保护内部元件,方便用户使用。原创 2023-09-12 13:56:32 · 297 阅读 · 4 评论 -
STL标准模板库——vector模拟实现
vector的数据安排以及操作方式与array数组非常相似,两者的唯一差别在于对空间运用的灵活性。array是静态空间,一旦配置了就不能改变,这也是为什么定义数组时[]里只能给常量不能给变量;vector是动态空间,随着元素的假如,它的内部机制会自行扩充空间以容纳新元素,对于内存的合理利用与运用的灵活性会有很大的帮助。vector的实现技术,关键在于其对大小的控制以及重新配置时的数据移动效率,而且所谓扩充空间,是“配置新空间/数据移动/释放旧空间”的大工程,时间成本很高。原创 2023-10-03 16:09:28 · 101 阅读 · 3 评论 -
C++——深入理解类与对象
C++编译器给每个“非静态成员函数”怎加了一个隐藏的指针参数,让该指针指向当前对象,并且在函数运行时调用该对象,在函数体中,所有的“成员变量”都是通过指针去访问。浅拷贝,也叫值拷贝,位拷贝,编译器只是将对象中的值拷贝过来。int _month;int _day;假如一个家庭有两个孩子,两个孩子一起玩一个玩具,就叫做浅拷贝,两个对象共用同一资源。深拷贝就是两个孩子各自有自己的玩具,每个对象有自己独有的资源,互不干扰。原创 2023-09-14 20:04:45 · 63 阅读 · 3 评论 -
C语言进阶——指针进阶(上)
数组指针是指针 ,我们已经熟悉整形指针(int * pint)是能够指向整形数据的指针,字符指针(char* charp)是能够指向字符或字符串数据的指针,所以数组指针就是能够指向数组的指针----[]的优先级高于*,所以这个式子可以理解为p1是个10个元素的数组,数组中每个元素类型为int*,所以这是一个指针数组----()将*和p2结合,所以p2是个指针,这个指针指向一个数组,这个数组里有十个元素,所以我们称p2为数组指针,它指向一个数组使用指针模拟实现二维数组//指针数组。原创 2023-11-05 23:02:29 · 79 阅读 · 1 评论 -
STL标准模板库——list模拟实现
相较于vector线性空间,list就显得复杂许多,它的好处是每次插入或删除一个元素,就配置或释放一个空间,list对于空间的运用有绝对的精准,一点也不浪费。而且,对于任何位置的元素插入或删除,list的时间复杂度永远都是常数list和vector是两个最常被使用的容器,什么十几下最适合使用哪一种容器,必须视元素的多寡,元素的构造复杂度,元素存取行为的特性而定。原创 2023-10-14 19:27:21 · 103 阅读 · 1 评论 -
C语言进阶——动态内存管理
我们已经熟悉的内存开辟的方式有但是上面两种方式有两个缺点:1,空间开辟大小是固定的 2,数组在声明的时候必须指明数组长度,在编译时分配但是对于空间的需求,不仅仅时上面的情况,有时候我们对内存的需求是会随着程序的依次执行而改变的,于是上面两种方式就不适合了,于是C语言推出了动态开辟的内存管理方式。原创 2023-11-13 08:18:39 · 57 阅读 · 0 评论 -
C++&数据结构——部分OJ题详解
这是一种思路,但是这种思路有很大缺点,因为必须要求是满二叉树或者完全二叉树的时候时间复杂度才是O(logN),其他的都是O(N^2),所以我们采用方法二会更好。②通过一个levelSize变量控制队列出的数据数量,当变量出完后用队列的size更新levelSize。从题目我么可以看出,前序的整数数组preorder和inorder可以确定根,中序可以分割处左右子树。①用两个队列,一个队列控制层序遍历的节点,一个控制节点的层数。只需要将上面的层序遍历逆置一下即可。原创 2023-12-20 15:32:59 · 632 阅读 · 0 评论 -
C++&&数据结构——AVL树
/祖先,三叉链,可以倒着遍历int _bf;原创 2024-01-15 16:47:08 · 794 阅读 · 0 评论 -
C++——位图与布隆过滤器
先看一个面试题:给40亿个不重复的未排序的无符号整数,然后如何快速判断一个数是否在这40亿个数中以我们前面的知识,最先想到的有两种方法:1,排序+二分查找 2,存到哈希表和红黑树中再查但是题目中给的是40亿个整数,我们先算下需要的内存:1G就是1024MB,是1024*1024KB,是1024*1024*1024Byte,相当于10亿Byte,所以,40亿个数需要4*40Byte大概就是16G的空间,所以由于空间的限制,上面两种方法就都可以去掉了。原创 2024-02-05 17:14:12 · 1025 阅读 · 0 评论 -
C语言实现通讯录
/名称int age;//年龄//性别//电话//地址}PeoInfo;原创 2023-11-28 10:38:21 · 387 阅读 · 1 评论 -
C语言进阶——自定义类型
这个我觉得还是直接上代码比文字解释要清楚得多,啊哈哈struct SNchar c;int i;//可以自己改变初始化顺序//全局变量struct S1double d;//局部变量//结构体里有结构体int i = 0;for (i = 0;i < 10;i++)顾名思义,就是把可能的值一一列举,下面就是枚举的定义enum Dat //星期Mon,Tues,Wed,Thur,Fri,Sat,Suenum Sex //性别MALE,FEMALE,原创 2023-11-10 13:34:42 · 109 阅读 · 1 评论 -
C++——关于继承的一些补充
使用父类对象拷贝子类时,会将子类中父类继承下来的那部分内容切出来拷贝一份给父类,中间新对象产生,用父类引用或指针时没有新对象产生,父类指针或引用只代表了子类对象中从父类继承下来的那一部分,所以用父类指针或引用去改变值的时候,会改变子类的值。原创 2023-12-12 16:29:34 · 417 阅读 · 0 评论 -
关于C语言代码是如何变成可执行程序的
从所周知,计算机是能够执行二进制指令的,但是我们写出的C语言代码是文本信息,计算机不能直接理解所以我们地代码是如何变成二进制代码从而能够让计算机执行的呢?在ANSI C的任何一种实现中,存在两个不同的环境第一种是翻译环境,在这个环境中源代码被转换为可执行的机器指令第二种是执行环境,用于实际执行代码。原创 2023-11-16 13:16:51 · 612 阅读 · 1 评论 -
C++——类与对象补充
下面的两条语句可以证明该对象存在。原创 2023-12-06 10:27:07 · 841 阅读 · 0 评论 -
C++&&数据结构——二叉搜索树详解
插入的目标是插入合适的值,并且和父亲链接起来,比如要在某个节点右边插入一个值,递归时就是 _Insert(root->right,key),我们用Node* &root之后,这个root就间接代表了上一个节点的right指针,然后我们再root = new Node(key),相当于生成一个新节点并直接赋值给父节点的右,间接完成链接,如下代码。二叉搜索树的插入不难,如果数为空直接新增根节点,如果不为空,比我小走左边,比我大走右边,走到空的时候新增节点并完成链接,如下代码和注释。原创 2023-12-19 20:08:04 · 988 阅读 · 0 评论 -
C++——关于多态的一些补充
先看下面代码的执行结果可以发现在析构子类对象的时候只调用了父类的析构函数,没有调用子类的,为了能正确调用子类的析构函数,需要对析构函数也实现成虚函数。原创 2023-12-13 20:52:26 · 880 阅读 · 0 评论 -
C语言进阶——常用字符串函数和内存函数
字符串以'\0作为结束标志,strlen函数返回的是在字符串中'\0'前出现的字符个数,不包含'/0',并且参数指向的字符串必须要以'\0'结束,strlen的返回值为size_t,是无符号整数,这个要注意。这是因为我们的memcpy是从前面往后面拷贝的,1会覆盖3的位置,2会覆盖4的位置,所以我们再去访问3的位置时最后访问到的还是1,于是造成了上面的情况。所以memcpy函数是用来处理不重叠的内存拷贝的,如果有重叠的会有专门的函数来解决,就是下面的memmove函数。原创 2023-11-07 10:34:03 · 65 阅读 · 1 评论 -
C++——使用红黑树封装mat和set
第二个模板参数_Val决定了节点里面存什么,而第一个模板参数是为了单独拿到Key的类型,因为像Find,Erase这些接口函数的参数就是Key,我们也不可能拿pair去find对不对。在STL库中,set和map使用的是同一颗红黑树,所以为了使map和set都有各自的特性,这里采用了泛型的方法,想办法让红黑树支持传两个值,就。上面就是红黑树的部分源码,有两个模板参数_Key和_Val,可以看到节点中用的是_Val这样,查找和插入的改造大体相同,加入仿函数拿到T中的Key,即可,其他的基本不动。原创 2024-02-20 16:37:12 · 343 阅读 · 0 评论 -
C语言进阶——预处理详解
在预处理阶段,编译器提前提供了一些指令以供我们使用,下面就是几个常用的预定义符号//进行编译的源文件地址//文件当前的行号//文件被编译的日期(年月日)//文件被编译的时间(时分秒)//当前VS是不支持ANSI C;FOR//死循环预处理后结果为可以看到#define对应的符号被替换了,所以有人写代码的时候就用偷懒了caseint d = 0;原创 2023-11-16 16:15:12 · 221 阅读 · 1 评论 -
C++&&数据结构——红黑树
/用枚举来标识颜色RED,BLACK, _kv(kv){}原创 2024-01-25 15:04:45 · 1837 阅读 · 2 评论 -
C语言进阶——文件操作
存储在磁盘上的是文件,我们执行一个程序,查看某个文档,或者最常用的删除复制,都是在对文件进行操作。文件分为程序文件和数据文件。原创 2023-11-16 10:54:24 · 121 阅读 · 1 评论 -
C++——map和set的基本使用
①set是按照一定次序存储元素的容器②在set中,元素的value也标识它(value就是key,类型为T),并且每个value必须是唯一的③在内部,set中的元素总是按照其内部比较对象所指示的特点排序准则进行排序④set在底层是用红黑树实现的①map是关联容器,它按照特点的次序(按照key来比较)存储由简直key和value组合而成的元素②在map中,键值key通常用于排序和唯一的标识元素,而值value中存储与此键值key关联的内容。原创 2024-01-10 16:44:49 · 1003 阅读 · 0 评论 -
C++&&数据结构——哈希表
在C++98中,STL提供了以红黑树为底层的一系列关联式容器,查询时效率可达到logN,但是当树中节点非常多时,查询效率也不理想,所以在C++11中,STL提供了unordered系列的几个容器,使用哈希表作为底层,大大增加了查询效率。对于删除,采用闭散列处理哈希冲突时,不能直接删除表中的数据否则会影响其他数据的搜索,所以采用标记的伪删除法来删除,给要删除的位置打上delete的标记,具体实现请看后面的模拟实现部分。最好的情况是,每个桶中刚好有一个节点,再插入数据时,都会发生哈希冲突,原创 2024-01-23 19:11:49 · 1629 阅读 · 2 评论 -
C++&&数据结构——二叉树的非递归遍历
有了C++的STL和前面大量学习的支持,我们可以来实现二叉树的非递归遍历了!二叉树的非递归遍历思路大体如下:①将一棵树分成左路节点和左路节点的右子树两部分②用一个栈存储左路节点,目的是访问每个节点的右子树③然后以子问题访问右子树,将访问的右子树转化为一个个小的左路节点和左路节点的右子树两部分,然后循环。原创 2023-12-20 16:00:34 · 466 阅读 · 0 评论 -
C++——内存管理
new:①调用operator new函数申请空间②在申请的空间上执行对象的构造函数完成初始化delete①在空间上先执行析构函数,完成清理工作②调用operator delete函数释放空间new T[N]①调用operator new[]函数,完成对数个对象的空间申请②在申请的数个空间上执行相同数量的构造函数delete[]①先进行N次析构②调用operator delete[]释放多个空间。原创 2023-12-12 11:31:40 · 931 阅读 · 0 评论 -
C++——C++11线程库
在Linux中我们可以使用用户层的线程接口来实现线程操作,但是Linux下的接口无法在Windows下使用,因为Linux支持了POSIX线程标准,但是Windows没有支持,它搞了一套属于它自己的线程标准。所以在C++11之前,涉及到多线程问题的代码可移植性比较差所以C++11中最重要的特性就是对线程进行支持了,使得C++在并行编程时不需要依赖第三方库,而且在原子操作中还引入了原子类得概念。C++,Linux和Windows下都可以支持多线程程序 -- 条件编译#else#endif。原创 2024-03-28 15:41:51 · 1142 阅读 · 0 评论 -
C++——IO流
int _month;int _day;return in;//不仅仅针对ostream,ofstream和stringstream也可以用,因为用的是继承体系return out;//自动识别类型的本质--函数重载//内置类型可以直接使用--因为库里面ostream类型已经实现了int i = 1;// 自定义类型则需要我们自己重载<< 和 >>cout << d;原创 2024-04-10 18:37:11 · 875 阅读 · 1 评论 -
C++——类型转换
static_cast用于相近类型之间的转换,编译器隐式执行的任何类型都可以用static_cast来转换,但是不能用于两个不相关的类型进行转换。①static_cast用于相关类型之间的转换,译器隐式执行的任何类型都可以用static_cast来转换,比如int和double的转换,相当于C的隐式类型转换。所以C++看中了C的转换缺陷,推出了属于自己的转换标准,但是要注意,C++是兼容C的,所以C++仍然可以使用C的转换方法。对象本身是无论如何都不允许转换的,所以转换的只是指向对象的指针或引用。原创 2024-04-07 16:40:45 · 923 阅读 · 1 评论 -
C++——C++11智能指针
这是我们双链表的基本结构,两个节点,里面都有两个指针,类型为shared_ptr,当函数结束后要释放资源,首先释放n1,_val被释放,然后shared_ptr调用自己的析构函数,本来没啥问题,但是释放_next时,除了释放_next自己的资源时,还会去释放它指向的资源,它指向的是n2,所以再释放n2,然后释放n2时,_prev和_next都调用自己的析构,然后再去释放它们指向的资源,然后它们指向n1。因为迭代器不管资源释放,它只管访问资源,修改资源,因为释放资源的事情是交给析构函数的。原创 2024-04-03 11:06:46 · 881 阅读 · 0 评论 -
C++——特殊类设计
C++的类是C++这门面向对象语言的精华所在,C++的类设计在众多OO语言中也是非常具有代表性的存在。所以,原本的类功能已经可以满足我们大部分的需求,但是随着编程语言的不断发展和实际应用的持续复杂,类原本的功能可能会有一部分失效或缺陷。所以就有了特殊类设计,通过设计特殊的类来应对特殊的各种情况。正所谓对症下药。下面给出了部分特殊类设计。原创 2024-04-05 11:23:43 · 933 阅读 · 0 评论 -
C++——异常机制
C++库给我们提供了一系列标准的异常,定义在std::exception中。在实际中我们可以去继承exception类实现自己的异常类。但是实际上很多公司有一套属于自己的异常继承体系,因为C++标准库给的并不好用。很多公司都会自定义自己的异常体系进行规范的异常管理,因为一个项目中如果大家都随意抛异常,那么外层的调用者基本没法玩了。class SqlException : public Exception //数据库的错误。原创 2024-04-02 11:21:09 · 1078 阅读 · 1 评论