- 博客(78)
- 收藏
- 关注
原创 C++之多态
多态是一个继承关系的下的类对象去调用同一函数,产生了不同的行为。比如Student继承了Person。Person对象买票全价,Student对象优惠买票。一般出现重定义,前面都会说继承体系中的编译报错的重定义是指在同一作用域多次定义一个变量或函数。
2025-05-10 20:21:27
994
原创 C++之继承
继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许我们在保持原有类特性的基础上进行扩展,增加方法(成员函数)和属性(成员变量),这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触函数层次的复用,继承是类设计层次的复用。
2025-05-07 18:52:25
866
原创 只出现一次的数字 III(力扣 260)
给你一个整数数组nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。找出只出现一次的那两个元素。你可以按返回答案。你必须设计并实现线性时间复杂度的算法且仅使用常量额外空间来解决此问题。[3,5][5, 3] 也是有效的答案。
2025-04-14 19:20:26
257
原创 只出现一次的数字 II(力扣 137)
具体地,考虑答案的第 i 个二进制位(i 从 0 开始编号),它可能为 0 或 1。对于数组中非答案的元素,每一个元素都出现了 3 次,对应着第 i 个二进制位的 3 个 0 或 3 个 1,无论是哪一种情况,它们的和都是 3 的倍数(即和为 0 或 3)。由于数组中的元素都在 int(即 32 位整数)范围内,因此我们可以依次计算答案的每一个二进制位是 0 还是 1。,并将它们相加再对 3 取余,得到的结果一定为 0 或 1,即为答案的第 i 个二进制位。这样一来,对于数组中的每一个元素 x,
2025-04-14 15:49:40
326
原创 浅拷贝与深拷贝
最终导致的问题是,s1、s2共用同一块内 存空间,在释放时同一块空间被释放多次而引起程序崩溃,这种拷贝方式,称为浅拷贝。浅拷贝:也称位拷贝,编译器只是将对象中的值拷贝过来。如果对象中管理资源,最后就会导致 多个对象共享同一份资源,当一个对象销毁时就会将该资源释放掉,而此时另一些对象不知道该 资源已经被释放,以为还有效,所以当继续对资源进项操作时,就会发生发生了访问违规。就像一个家庭中有两个孩子,但父母只买了一份玩具,两个孩子愿意一块玩,则万事大吉,万一 不想分享就你争我夺,玩具损坏。
2025-03-29 15:37:33
371
原创 auto和范围for
在早期C/C++中auto的含义是:使用auto修饰的变量,是具有自动存储器的局部变量,后来这个 不重要了。C++11中,标准委员会变废为宝赋予了auto全新的含义即:auto不再是一个存储类型 指示符,而是作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期 推导而得。因此 C++11中引入了基于范围的for循环。for循环后的括号由冒号“ :”分为两部分:第一部分是范围 内用于迭代的变量,第二部分则表示被迭代的范围,自动迭代,自动取数据,自动判断结束。
2025-03-29 15:27:26
225
原创 STL简介
STL(standard template libaray-标准模板库):是C++标准库的重要组成部分,不仅是一个可复用的 组件库,而且是一个包罗的软件框架。
2025-03-29 15:14:56
272
原创 leetcode:字符串相乘
不能使用任何内置的 BigInteger 库或直接将输入转换为整数。的乘积,它们的乘积也表示为字符串形式。给定两个以字符串形式表示的非负整数。对每次得到的结果进行累加,可以使用「
2025-03-22 18:40:56
302
原创 C++之模板
class 类模板名// 类内成员定义// 类模版public:_size = 0;// 模版不建议声明和定义分离到两个文件.h 和.cpp会出现链接错误// 扩容++_size;
2025-03-16 15:37:43
957
原创 new、delete
int main()// new/delete 和 malloc/free最大区别是 new/delete对于【自定义类型】除了开空间还会调用构造函数和析构函数free(p1);delete p2;// 内置类型是几乎是一样的// Cfree(p3);delete p4;free(p5);return 0;
2025-03-12 21:11:14
214
原创 C++之类型转换
• C++⽀持内置类型隐式类型转换为类类型对象,需要有相关内置类型为参数的构造函数。• 构造函数前⾯加explicit就不再⽀持隐式类型转换。 • 类类型的对象之间也可以隐式转换,需要相应的构造函数⽀持。
2025-03-10 20:38:08
154
原创 类的默认成员函数之拷⻉构造函数
传值引⽤返回,返回的是返回对象的别名(引⽤),没 有产⽣拷⻉。但是如果返回对象是⼀个当前函数局部域的局部对象,函数结束就销毁了,那么使⽤ 引⽤返回是有问题的,这时的引⽤相当于⼀个野引⽤,类似⼀个野指针⼀样。如果⼀个构造函数的第⼀个参数是⾃⾝类类型的引⽤,且任何额外的参数都有默认值,则此构造函数 也叫做拷⻉构造函数,也就是说拷⻉构造是⼀个特殊的构造函数。~Stack对同一地址析构了了两次,即对同一地址free了两次,因此编译器报错。st1和st2地址相同。
2025-03-06 19:22:25
698
原创 类的默认成员函数之析构函数
析构函数与构造函数功能相反,析构函数不是完成对对象本⾝的销毁,⽐如局部对象是存在栈帧的, 函数结束栈帧销毁,他就释放了,不需要我们管,C++规定对象在销毁时会⾃动调⽤析构函数,完成对 象中资源的清理释放⼯作。
2025-03-05 20:57:21
333
原创 类的默认成员函数之构造函数
默认成员函数就是⽤⼾没有显式实现,编译器会⾃动⽣成的成员函数称为默认成员函数。⼀个类,我 们不写的情况下编译器会默认⽣成以下6个默认成员函数,需要注意的是这6个中最重要的是前4个,最 后两个取地址重载不重要,我们稍微了解⼀下即可。默认成员函数很重要,也⽐较复杂,我们要从两个⽅⾯ 去学习:• 第⼀:我们不写时,编译器默认⽣成的函数⾏为是什么,是否满⾜我们的需求。• 第⼆:编译器默认⽣成的函数不满⾜我们的需求,我们需要⾃⼰实现,那么如何⾃⼰实现?构造函数是特殊的成员函数,需要注意的是,构造函数虽然名称叫构造,但
2025-03-05 20:08:32
854
原创 类和对象
• class为定义类的关键字,Stack为类的名字,{}中为类的主体,注意类定义结束时后⾯分号不能省 略。类体中内容称为类的成员:类中的变量称为类的属性或成员变量;类中的函数称为类的⽅法或 者成员函数。• 为了区分成员变量,⼀般习惯上成员变量会加⼀个特殊标识,如成员变量前⾯或者后⾯加_或者m 开头,注意C++中这个并不是强制的,只是⼀些惯例。
2025-03-03 15:11:16
889
原创 NULL与nullptr
• C++中NULL可能被定义为字⾯常量0,或者C中被定义为⽆类型指针(void*)的常量。不论采取何种 定义,在使⽤空值的指针时,都不可避免的会遇到⼀些⿇烦,本想通过f(NULL)调⽤指针版本的 f(int*)函数,但是由于NULL被定义成0,调⽤了f(intx),因此与程序的初衷相悖。• C++11中引⼊nullptr,nullptr是⼀个特殊的关键字,nullptr是⼀种特殊类型的字⾯量,它可以转换 成任意其他类型的指针类型。
2025-03-03 08:46:51
256
原创 C++之引用
目录1 引⽤的概念和定义2 引⽤的特性3 引⽤的使⽤4 const引⽤5 指针和引⽤的关系引⽤不是新定义⼀个变量,⽽是给已存在变量取了⼀个别名,编译器不会为引⽤变量开辟内存空间, 它和它引⽤的变量共⽤同⼀块内存空间。⽐如:⽔壶传中李逵,宋江叫"铁⽜",江湖上⼈称"⿊旋 ⻛";林冲,外号豹⼦头;类型& 引⽤别名=引⽤对象;• 引⽤在定义时必须初始化• ⼀个变量可以有多个引⽤• 引⽤⼀旦引⽤⼀个实体,再不能引⽤其他实体• 引⽤在实践中主要是于引⽤传参和引⽤做返回值中减少拷⻉提⾼效率和改变引⽤对象时同时改变被 引
2025-02-26 16:54:21
919
原创 函数重载
C++⽀持在同⼀作⽤域中出现同名函数,但是要求这些同名函数的形参不同,可以是参数个数不同或者 类型不同。这样C++函数调⽤就表现出了多态⾏为,使⽤更灵活。C语⾔是不⽀持同⼀作⽤域中出现同 名函数的。
2025-02-26 16:16:59
161
原创 命名空间namespace
• 定义命名空间,需要使⽤到namespace关键字,后⾯跟命名空间的名字,然后接⼀对{}即可,{}中 即为命名空间的成员。命名空间中可以定义变量/函数/类型等。• namespace本质是定义出⼀个域,这个域跟全局域各⾃独⽴,不同的域可以定义同名变量,所以下 ⾯的rand不在冲突了。• C++中域有函数局部域,全局域,命名空间域,类域;域影响的是编译时语法查找⼀个变量/函数/ 类型出处(声明或定义)的逻辑,所有有了域隔离,名字冲突就解决了。
2025-02-26 15:42:52
436
原创 计数排序( ⾮⽐较排序)
计数排序⼜称为鸽巢原理,是对哈希直接定址法的变形应⽤。,效率很⾼,但是适⽤范围及场景有限。时间复杂度: O(N+range)空间复杂度: O(range)
2025-02-18 11:17:22
165
原创 归并排序
归并排序(MERGE-SORT)是建⽴在归并操作上的⼀种有效的排序算法,该算法是采⽤分治法(Divide andConquer)的⼀个⾮常典型的应⽤。将已有序的⼦序列合并,得到完全有序的序列;创建临时数组tem,将每次递归中两个有序表合并的一个有序表放在tem中,直至所有元素排序完成后再将tem中的元素放在原数组arr中,排序完成。若将两个有序表合并成⼀个有序表(即两个有序数组的合并),称为⼆路归并。
2025-02-18 10:18:09
295
原创 快速排序
快速排序是Hoare于1962年提出的⼀种⼆叉树结构的交换排序⽅法,其基本思想为:任取待排序元素 序列中的某元素作为基准值,按照该排序码将待排序集合分割成两⼦序列,左⼦序列中所有元素均⼩ 于基准值,右⼦序列中所有元素均⼤于基准值,然后最左右⼦序列重复该过程,直到所有元素都排列 在相应位置上为⽌。
2025-02-08 15:44:49
364
原创 选择排序
例:标记好第一个元素和最后一个元素的位置begin,end,然后设置最大值位置maxi和最小值位置mini,令其初始化。从begin开始到end结束,依次遍历找到最大值位置和最小值位置最后交换begin与mini,end与maxi,begin++,end--重复上述步骤,直至begin>end,排序完成。
2025-02-04 15:49:00
350
原创 插入排序
直接插⼊排序是⼀种简单的插⼊排序法,其基本思想是:把待排序的记录按其关键码值的⼤⼩逐个插 ⼊到⼀个已经排好序的有序序列中,直到所有的记录插⼊完为⽌,得到⼀个新的有序序列。例如:我们玩扑克牌时,就⽤了插⼊排序的思想,此时 array[i] 的排序码与 即将 array[i-1],array[i-2],… 的排序码顺序进⾏⽐较,找到插⼊位置 array[i] 插⼊,原来位置上的元素顺序后移例:将下面数字升序排列。
2025-01-23 17:17:08
870
原创 文件操作详解
磁盘(硬盘)上的⽂件是⽂件。但是在程序设计中,我们⼀般谈的⽂件有两种:程序⽂件、数据⽂件(从⽂件功能的⻆度来分类 的)。上⾯说的适⽤于所有输⼊流⼀般指适⽤于标准输⼊流和其他输⼊流(如⽂件输⼊流);所有输出流⼀ 般指适⽤于标准输出流和其他输出流(如⽂件输出流)。
2024-10-26 15:56:11
905
1
原创 动态内存管理详解
C/C++程序内存分配的⼏个区域:1. 栈区(stack):在执⾏函数时,函数内局部变量的存储单元都可以在栈上创建,函数执⾏结束时 这些存储单元⾃动被释放。栈内存分配运算内置于处理器的指令集中,效率很⾼,但是分配的内 存容量有限。栈区主要存放运⾏函数⽽分配的局部变量、函数参数、返回数据、返回地址等。2. 堆区(heap):⼀般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收。分配⽅ 式类似于链表。3. 数据段(静态区):(static)存放全局变量、静态数据。程序结束后由系统释放。
2024-10-23 21:31:17
1232
原创 ⾃定义类型:联合和枚举
使⽤联合体是可以节省空间的,举例: ⽐如,我们要搞⼀个活动,要上线⼀个礼品兑换单,礼品兑换单中有三种商品:图书、杯⼦、衬衫。上述的结构其实设计的很简单,⽤起来也⽅便,但是结构的设计中包含了所有礼品的各种属性,这样 使得结构体的⼤⼩就会偏⼤,⽐较浪费内存。代码1输出的三个地址⼀模⼀样,代码2的输出,我们发现将i的第4个字节的内容修改为55了。联合的成员是共⽤同⼀块内存空间的,这样⼀个联合变量的⼤⼩,⾄少是最⼤成员的⼤⼩(因为联合 ⾄少得有能⼒保存最⼤的那个成员)。性别有:男、⼥、保密,也可以⼀⼀列举。
2024-10-23 19:12:01
958
原创 ⾃定义类型:结构体详解
1. 位段的成员必须是 int、unsigned int 或signed int ,在C99中位段成员的类型也可以 选择其他类型。2. 位段的成员名后边有⼀个冒号和⼀个数字。int _b:5;int _c:10;int _d:30;A就是⼀个位段类型。那位段A所占内存的⼤⼩是多少?
2024-10-22 21:39:12
1194
原创 数据在内存中的存储
⼤端(存储)模式: 是指数据的低位字节内容保存在内存的⾼地址处,⽽数据的⾼位字节内容,保存在内存的低地址处。⼩端(存储)模式: 是指数据的低位字节内容保存在内存的低地址处,⽽数据的⾼位字节内容,保存在内存的⾼地址处。上述概念需要记住,⽅便分辨⼤⼩端。
2024-10-22 19:40:03
1281
原创 sizeof和strlen的对⽐
在学习操作符的时候,我们学习了 sizeof , sizeof 计算变量所占内存内存空间⼤⼩的,单位是 字节,如果操作数是类型的话,计算的是使⽤类型创建的变量所占内存空间的⼤⼩。sizeof 只关注占⽤内存空间的⼤⼩,不在乎内存中存放什么数据。
2024-10-20 17:07:05
415
原创 深⼊理解指针(3)
⾸先我们再次理解⼀下⼆维数组,⼆维数组其实可以看做是每个元素是⼀维数组的数组,也就是⼆维 数组的每个元素是⼀个⼀维数组。那就意味着⼆维数组传参本质上也是传递了地址,传递的是第⼀ ⾏这个⼀维数组的地址,那么形参也是可以写成指针形式的。根据前⾯学习整型指针,数组指针的时候,我们的类⽐关系,我们不难得出结论: 函数指针变量应该是⽤来存放函数地址的,未来通过地址能够调⽤函数的。所以,根据数组名是数组⾸元素的地址这个规则,⼆维数组的数组名表⽰的就是第⼀⾏的地址,是⼀ 维数组的地址。思考⼀下:p1, p2分别是什么?
2024-10-20 16:29:29
769
原创 深⼊理解指针(2)
这个代码搞明⽩后,我们再试⼀下,如果我们再分析⼀下,数组名arr是数组⾸元素的地址,可以赋值 给p,其实数组名arr和p在这⾥是等价的。那么在数组传参 的时候,传递的是数组名,也就是说本质上数组传参传递的是数组⾸元素的地址。同理arr[i] 应该等价于 *(arr+i),数组元素的访问在编译器处理的时候,也是转换成⾸元素的地址+偏移 量求出元素的地址,然后解引⽤来访问的。这⾥我们使⽤ &arr[0] 的⽅式拿到了数组第⼀个元素的地址,但是其实数组名本来就是地址,⽽且 是数组⾸元素的地址,我们来做个测试。
2024-10-19 20:35:25
994
原创 深⼊理解指针(1)
前⾯的内容我们了解到,32位机器假设有32根地址总线,每根地址线出来的电信号转换成数字信号后 是1或者0,那我们把32根地址线产⽣的2进制序列当做⼀个地址,那么⼀个地址就是32个bit位,需要4 个字节才能存储。我们知道计算机上CPU(中央处理器)在处理数据的时候,需要的数据是在内存中读取的,处理后的 数据也会放回内存中,那我们买电脑的时候,电脑上内存是 8GB/16GB/32GB 等,那这些内存空间如 何⾼效的管理呢?在上⾯的代码中,将⼀个int类型的变量的地址赋值给⼀个char*类型的指针变量。
2024-10-19 20:01:55
949
原创 整型提升和算术转换
C语⾔中整型算术运算总是⾄少以缺省(默认)整型类型的精度来进⾏的。为了获得这个精度,表达式中的字符和短整型操作数在使⽤之前被转换为普通整型,这种转换称为整 型提升。b和c的值被提升为普通整型,然后再执⾏加法运算。加法运算完成之后,结果将被截断,然后再存储于a中。如何进⾏整体提升呢?
2024-10-19 16:56:18
255
原创 操作符详解(超全,超详细)
8进制的数字每⼀位是0~7的,0~7的数字,各⾃写成2进制,最多有3个2进制位就⾜够了,⽐如7的⼆ 进制是111,所以在2进制转8进制数的时候,从2进制序列中右边低位开始向左每3个2进制位会换算⼀ 个8进制位,剩余不够3个2进制位的直接换算。其实10进制的每⼀位是有权重的,10 进制的数字从右向左是个位、⼗位、百位....,分别每⼀位的权重是 10^0,10^1,10^2……各种运算符的优先级是 不⼀样的。2进制和10进制是类似的,只不过2进制的每⼀位的权重,从右向左是: 2^0,2^1,2^2……
2024-10-19 16:38:57
1221
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅