C++
文章平均质量分 77
羽晨同学
自己的人生由自己做主,加油
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
蓝桥杯好题推荐-----高精度减法
这个题目的解题思路,其实是和高精度加法是非常像的。怎么说呢,其实开始的时候,由于范围受限的原因,所以我们必须把数字存到字符串中,然后用倒序,存到数组中,然后进行高精度减法,进行高精度减法的时候,我们可以逐个相减,然后如果减下的数字小于0,那么+10,前一位减一,最终从非0的第一位开始输出。记录详情 - 洛谷 | 计算机科学教育新生态。好了,今天的内容就到这里,我们明天再见。原创 2025-02-28 16:41:25 · 568 阅读 · 0 评论 -
蓝桥杯好题推荐--高精度加法
高精度加法,其实这种题目,因为数据范围的原因,所以我们不管用什么类型,都达不到这个的范围,所以,我们一般采用的就是数组+字符串,我们把要加的数字存放到字符串中,然后字符串中的数字倒序存入数组中,然后我们会定义三个数组,然后利用数组完成加法操作。好了,今天的内容就到这里,我们明天再见。原创 2025-02-28 11:12:58 · 500 阅读 · 0 评论 -
蓝桥杯lesson3---string的使用
string字符串是一种更加高级的封装,string字符串中包含了大量的方法,这些方法使得字符串的操作变得更加简单,string的使用,往往贯穿于整个蓝桥杯生涯中。迭代器是一种对象,它可以用来遍历容器,迭代器的作用类似于指针,或者数组下标,这就意味着,如果我们想要访问迭代器所指向的值,我们需要解引用。当然C++中的string创建的字符串和char类型的数组所表示的字符串还有一个区别,string类型的字符串对象可以直接赋值。这个其实适用于不带空格的字符串,但如果输入的是带空格的字符串呢,我们来看看。原创 2025-01-23 21:45:34 · 1357 阅读 · 0 评论 -
C++系列-多态
多态是在不同继承关系的类对象,去调用同一函数,产生了不同的行为。必须通过基类的指针或者引用调用虚函数。被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写。public:cout << "买票-全价" << endl;//重写/覆盖cout << "买票-半价" << endl;public://重写/覆盖cout << "买票-优先" << endl;//多态条件//1.虚函数重写//2.父类指针或者引用调用虚函数int main()Person p;原创 2024-10-02 15:17:31 · 1291 阅读 · 0 评论 -
C++系列-继承补充
怎么说呢,其实看上面的图,我们可以看到,Person的信息其实被Student和Teacher继承了一次,说明在Student和Teacher中都有Person的信息,当Assistant继承Student和Teacher的时候,继承了两次Person的信息,这就造成了数据的冗余和二义性。有了多继承,就存在菱形继承,有了菱形继承就有菱形虚拟继承,底层实现就很复杂,所以一般不建议设计出多继承,一定不要涉及出菱形继承,否则在复杂度及性能上都有问题。在实践中,尽可能的使用多继承,而不是菱形继承。原创 2024-10-02 10:59:56 · 1009 阅读 · 0 评论 -
C++系列-继承
继承是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行拓展,增加功能,这样可以产生新的类,叫做派生类,继承呈现了面向对象的程序设计的层次结构,继承是类设计层次的复用。public:Person(){}//姓名protected://父类定义本质,不想被子类继承private://继承的父类的成员public://子类用不了(不可见)protected:int _stuid;原创 2024-09-29 19:12:39 · 941 阅读 · 0 评论 -
C++系列-模版
通常情况下,我们使用模版可以实现一些与类型无关的代码,但对于一些特殊类型的可能会得到一些错误的结果,需要特殊化处理。我们所能打印的只是int类型的变量,但是我们想要打印其他的类型,我们应该怎么做呢,最简单的,引入模版的概念。我们再来看一下vector的越界部分,在vector当中,同样也会进行严格的越界检查,溢出也会进行报错。上面的这个其实给出了全特化和半特化的例子,半特化中我们引出了参数,一个固定,一个随机参数。首先,我们想在定义的类中实现这样的功能,很明显,这是不可能的,但是有了。原创 2024-09-25 22:03:43 · 883 阅读 · 0 评论 -
C++系列-Stackqueue
适配器是一种设计模式,这种模式将一个类的接口转换成另外一个类的接口。而在STL库中,不管是stack,还是queue,其中都用到了适配器的概念。在STL库中,stack和queue默认使用的是deque在了解deque之前,我们先实现一下用vector来充当容器,先体会一下适配器对于代码的作用。原创 2024-09-25 20:08:07 · 771 阅读 · 0 评论 -
C++系列-list的模拟实现
在链表中实现迭代器和vector,string中实现迭代器的代码实现不同,这是由于二者之间的底层逻辑不同,无论是string还是vector,因为是先使用后++,所以我们先将节点放在一个变量当中。其实这些主要都是我们运用迭代器的时候所需要实现的代码。它的底层都是连续的,而list不是这样的。我们先对它进行修改,然后返回修改后的值。,所以我们之前使用的那样子就不可以了。在这个构造函数当中,原创 2024-07-21 08:47:44 · 383 阅读 · 0 评论 -
C++系列-List的使用
其实我们在这里可以明确的是,list的时间是远远大于vector的,因为毕竟list的底层是归并排序,而且需要对指针进行操作。如果什么都不加的时候,那么会将链表按照升序排序,如果想要按照降序排序,那么则需要在括号里面加入greater<int>();我们将mylist2中的元素粘贴到了mylist1中,并且删除了mylist2中的这些元素。通过这段代码,我们可以看到list的基本功能使用。在这里,我们其实可以看到关于链表的sort的使用,所以,我们打印出来的结果是这样子的。原创 2024-07-20 19:30:22 · 418 阅读 · 0 评论 -
C++系列-Vector模拟实现(补充)
其实我们可以分析出来迭代器失效的原因,其原因在于当删除it指示的元素的时候,it未能被重新赋值,it位置后面的数值赋值到了it位置,内存空间位置被改变,从而造成迭代器失效。initializer_list是一个代理对象,它就是auto的类型,它的大小就是两个指针的大小(一个指向数量的指针,一个指向存储元素的数组)这篇文章是基于上一篇的Vector的模拟实现的补充知识点,首先我们需要重点关注的便是迭代器失效的问题。所以说,其实Vector的兼容性蛮强大的,任何类型的数据都能放在vector中。原创 2024-07-18 12:10:10 · 402 阅读 · 0 评论 -
C++系列-Vector的模拟实现
在这个insert功能实现当中,我们先对空间进行判断,若是没有多余空间进行插入,则我们需要重新拓展空间,然后重新定位Pos位置,然后将插入位置之后的数据往后移动一位,插入数值。在实现Vector(顺序表)的过程中,我们为了保证顺序表对于所有类型数据的普遍使用性,所以,我们将定义一个类模板和类,以保证Vector可以用于各种类型的数据。,对于下面的标识符更新而言,如果没有oldsize,那么删除原先空间的时候,便会把size()删除,那么_finish便会无法得到更新,所以我们。这里其实有一个需要注意的点,原创 2024-07-18 09:56:04 · 469 阅读 · 0 评论 -
C++系列-Vector(一)
当vector构建的参数类型为char类型时,它是和string是极其类似的,但是二者之间也有不同,比如,对于vector而言,它可以兼顾其他不同的类型,而string只能是针对字符串的,而当我们详细学习了string之后,我们学习其他的STL的东西会变得更加简单。Vector是表示可变大小数组的序列容器。原创 2024-07-11 22:21:14 · 660 阅读 · 0 评论 -
C++系列-String(五)String初步的模拟实现
首先在String.cpp文件中,我们用到了类域的概念我们将功能的具体实现的代码放到了与功能声明相同的类域当中,这样可以防止将具体的库展开从而造成混乱。首先,我们对npos进行了定义,将它定义为-1,除了在cpp文件中定义之外(我们一般都选择在类外进行定义),我们也可以在头文件当中对int类型的变量进行定义(只有Int类型)。这样是可以的,但是这样是特例,我们一般来说不会这样做。这样会进行报错。接下来,我们对迭代器的开始和末尾进行的定义//迭代器的定义。原创 2024-07-10 10:41:28 · 640 阅读 · 0 评论 -
C++系列-String(四)String初步的模拟实现
在.cpp文件的开头我们引入头文件,有同学可能会好奇会不会和C++库当中的String.h文件发生冲突,但结果是不会的,因为编译器会现在当前目录进行查找,而当前目录就已经存在了这个文件。其实对于范围for而言,它的底层是迭代器,而迭代器,主要就是一个封装,底层的不同的类型都用iterator进行了重命名,搭建起来统一的上层建筑。这样子写的目的主要是兼顾空的字符串,加入了缺省值,若是传入的字符串为空时候,会自动复制为“\0”所以,只要搭建了基本的迭代器,范围for就可以使用了。原创 2024-07-08 09:02:36 · 216 阅读 · 0 评论 -
C++系列-String(三)
在这段代码当中,会出现报错情况,原因是由于虽然开辟了空间但并未进行空间的初始化。replace括号当中,第一个是从i位置,删除一个字符,然后用%20替代。这个接口的目的在于减少这个的长度,删除string中的一些字符。这个接口的目的是用一个新的值代替之前的那个值。这个接口的目的在于插入。原创 2024-06-26 19:46:25 · 429 阅读 · 0 评论 -
C++系列-String(二)
对于范围for而言,相同的是我们不仅可以对其进行遍历,也可以对其进行修改,并且对于范围for而言,他的底层就是迭代器。其实通过这个代码,我们可以回顾到之前讲过的auto的作用,可以自动辨别类型,是不是相当方便。当我们用const修饰s1的时候,s1的内容使用迭代器仍然无法修改。我们不仅可以对string进行遍历,而且可以对其中的值进行修改。我们接下来讲string中的下一个接口,对其按照字典序进行排序。而若是我们使得【】中的数字大于s1的范围,会出现越界警告。接下来,我们讲解三种对string的遍历方式。原创 2024-06-23 21:13:21 · 490 阅读 · 0 评论 -
C++系列-String(一)
在这段代码中,涉及到的知识点为隐式类型转换,我们都知道,临时变量具有常性,所以这段代码会出现报错,报错原因是由于权限的放大。在这段代码中我们可以看到,当传参的时候,我们既可以传临时变量,也可以传字符串。接口6是下标为3开始到30,由于30大于最大长度,所以到字符串的结尾。在接下来的接口6,7,8,这三个接口当中,想要实现的功能分别为。我们可以看到,这个接口的目的是从下标为3开始,一直拷贝到结尾。我们可以看到的是,string起到了拷贝字符串的作用。这样子,我们就避免了权限放大的这个问题。原创 2024-06-22 23:24:37 · 394 阅读 · 0 评论 -
C++系列-STL简介
STL是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架。原创 2024-05-31 16:26:42 · 491 阅读 · 0 评论 -
C++系列-类模板
在这个当中,我们需要注意的是,声明和定义不能分开放在.h和.cpp中,这样的话会出现链接错误。但是我们可以都放在.h中。原创 2024-05-31 16:03:25 · 422 阅读 · 0 评论 -
C++系列-模板初阶
在编译器的编译阶段,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应类型的函数以供调用,比如:当用double类型使用函数模板时,编译器通过对实参类型的推演,将T确定为double类型,然后产生一份专门处理double类型的代码,对于字符类型也是如此。函数模版是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具,所以其实模板就是将本来应该我们做的重复的事情交给了编译器。用不同类型的参数使用函数模板时,成为函数模板的实例化,模板参数实例化分为:隐式实例化和显式实例化。原创 2024-05-30 21:52:56 · 973 阅读 · 0 评论 -
C++系列-定位new表达式(placement-new)
用new[]创建多个变量的时候,编译器会在前面自动加上四个字节,用来告诉编译器,一共有多少个变量,但是删除的时候并不会从头进行删除,也就是说并不会删除完全,所以会出现报错情况。或者也可以显示调用operator new和operator new[]这两个全局函数。我们先来强调一个很关键的问题,那就是在new和delete中的一一对应的问题,我们可以通过上面这样的方式对已有的空间,显示调用构造。在这段代码当中,会发生报错情况,你知道是为什么吗?所以,我们最好的选择就是要进行一一对应。这个原因是为什么呢?原创 2024-05-27 18:52:31 · 440 阅读 · 0 评论 -
C++系列-operator new和operator delete函数
new的原理调用operator new的函数申请空间在申请的空间上执行构造函数,完成对象的构造delete的原理在空间上执行析构函数,完成对象中资源的清理工作调用operator delete函数释放对象的空间new T[N]的原理调用 operator new[] 函数,在operator new[]中实际调用operator new函数完成N个对象空间的申请在申请的空间上执行N次构造函数delete[]的原理在释放的对象空间上执行N次析构函数,完成N个对象中资源的清理。原创 2024-05-27 17:22:46 · 1276 阅读 · 0 评论 -
C++系列-C/C++内存管理方式
int main()//自定义类型,new才能调用构造初始化,malloc不能free(p1);delete p2;delete p3;return 0;我们可以从这段代码当中得出一个很重要的点,那就是malloc不能调用构造初始化,但是new可以//A aa1(1);//A aa2(2);原创 2024-05-26 20:40:10 · 893 阅读 · 0 评论 -
C++系列-友元
在上面的这个代码当中,所呈现出来的,就是我们所要讲到的内部类,内部类是一个独立的类,它不属于外部类,更不能通过外部类的对象去访问内部类的成员,外部类对于内部类没有任何优越的访问权限,Date是Time的友元,但是在这个其中涉及到了一个问题,那就是Time可以访问Date,但是Date却不可以访问Time,在这段代码当中,我们可以看到一个典型的运用了友元函数的代码,在这段代码当中,你看,当Date访问Time的私有时,编译器就会进行报错。原创 2024-05-24 20:49:27 · 508 阅读 · 0 评论 -
C++系列-static成员
声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量,用static修饰的成员函数,称之为静态成员函数,静态成员变量一定要在类外进行初始化。我们来看下面的这一段代码,思考一下,程序中创建出了多少个类对象。在上面的这段代码当中,我们可以获取到下面的几个知识点。我们可以看到,类的大小是4个字节,这个说明了什么呢?原创 2024-05-22 11:23:50 · 570 阅读 · 0 评论 -
C++系列-explicit关键字
原因就是这个的raa是3类型转换之后产生的临时变量的别名,但是临时变量具有常性,不能进行修改。所以,在这个过程中涉及到了两步,第一步是默认构造,第二步是拷贝构造,但是这种连续构造编译器会进行优化,所以显示出来的结果为直接构造。就是3构造了一个A类型的临时变量,然后a类型的临时变量进行拷贝构造,给了aa1。上面的这个就是多参数构造部分的代码,我们可以看到的是,和单参数构造是差别不大的。这段代码,将3直接给了aa1,但是代码并不会进行报错,这是为什么呢?上面我们讲的是单参数构造的情况,那么多参数构造的情况呢?原创 2024-05-22 10:52:54 · 501 阅读 · 0 评论 -
C++系列-构造函数和初始化列表
这个其实就和上面的情况类似,当类中没有默认构造函数时,我们用初始化列表将其定义。原创 2024-05-21 22:34:07 · 859 阅读 · 0 评论 -
C++系列-cout,cin的底层逻辑初讨论
那就涉及到了我们前面讲过的编译器默认的*this指针,这是是占第一个的,所以,我们上传的只能占第二个,而形参必须要和实参的顺序对应,所以,我们只能写成这样。这个当中,会有一个*this指针,我们将&d1也就是const Date*传入,由Date*接收,很明显,出现了权限的放大。但是这样有一个很严重的问题,那就是_year等变量是私有空间当中,不能进行访问,那我们这个时候应该怎么办呢?所以,我们需要堆Date*进行范围的限制,那我们应该怎么做呢,这是出现了权限的放大,我们知道,在。原创 2024-05-18 09:09:04 · 516 阅读 · 1 评论 -
C++系列-日期类的实现
大家可以看到,在实现日期类的判断功能的时候,我们切切实实手敲的只有等于和大于这两个部分,其余的功能都是这两个功能的组合,并结合其他的功能诞生出了更多的功能。下面的这个部分是前置++和后置++,前置--和后置--,这几个操作,我们在上一篇文章中有详细讲解,大家可以看看。在这几个功能当中,其实实现逻辑十分相似,我们可以总共分为两类,一个是-和-=,一个是+和+=,这两个部分。在这其中更为重要的是-=和+=的实现逻辑,因为要涉及到是否需要进位的操作,然后后面的+和-,就运用了+=和-=的操作逻辑。原创 2024-05-17 21:59:20 · 431 阅读 · 0 评论 -
C++入门系列-前置++和后置++重载
由于系统默认生成的*this指针不会进行销毁,所以,我们直接选择传*this指针,设为引用类型,这样子可以提高效率,而对于后置++而言,我们需要先使用,再+1,所以,好了,这个就是运算符重载当中的前置++和后置++的重载过程,下一节,我们将会带大家走进日期类的实现。在C++11当中,为了进一步的进行区分,这个代码的实现逻辑是什么呢?让我们一个个来进行分析,原创 2024-05-17 20:18:14 · 403 阅读 · 0 评论 -
C++入门系列-赋值运算符重载
其实重载成类的成员函数和重载成全局函数有一个很大的不同点,就是成员函数还有一个潜在的this指针,而全局函数是没有这个东西,所以,如果要重载为全局函数的话,我们就需要给两个参数。这段代码是operator的全局调用,我们会看到如果全局调用的话会存在一个问题,那就是成员变量是私有的。接下来,我们就回到了operator关键字的作用,这个关键字可以极大的提高代码的可读性,我们来看下面的代码。其实.*的作用是什么呢,我们可以通过这段代码看到,.*的作用就是帮助我们调用成员函数的指针。我们一般使用的就是第三种。原创 2024-05-15 18:23:44 · 907 阅读 · 0 评论 -
C++入门系列-拷贝构造函数
但是,在编译器生成的默认拷贝构造函数当中,内置类型是按照字节方式直接拷贝的,而自定义类型是调用其拷贝构造函数完成拷贝的。这个应该是最经典的拷贝构造的代码,通过上面的代码,我们可以知道我们创建了一个d2,并将d1的值对d2进行了初始化。当然像日期这样的类是没必要的,那么下面的类呢?你看,这个是有显示调用的,当没有显示调用时,编译器会调用默认的拷贝构造函数。在创建对象的时候,能不能创建一个和已知已存在的对象一模一样的对象呢?当没有显示调用的时候,我们就会调用编译器默认的拷贝构造函数。我们这个怎么理解呢?原创 2024-05-12 19:34:38 · 705 阅读 · 0 评论 -
C++入门系列-析构函数
有资源需要显示清理,就需要写析构,如:stack,list有两种场景不需要显示写析构,默认生成就可以。1.没有资源需要清理,如Date2. 内置类型成员没有资源需要清理,剩下的都是自定义类型成员,如MyQueue。原创 2024-05-11 22:02:32 · 564 阅读 · 0 评论 -
C++入门系列-构造函数
而在C++11当中针对内置类型成员不初始化的缺陷,又打了补丁,即:内置类型成员变量在类中声明时可以给默认值。原创 2024-05-11 21:44:40 · 893 阅读 · 0 评论 -
C++入门系列-类对象模型&this指针
C++引入了this指针类解决这个问题,即:C++编译器给每个非静态成员函数增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该参数的对象),在函数体所有的成员函数的操作,都是通过该指针去访问,只不过所有的操作对用户是透明的,即用户不需要去传递,编译器自动完成。要是这样的话,我们会发现好多对象又保存了同一份代码,这样做的结果就是浪费了非常多的时间,那么我们应该如何解决呢?说明一个类的大小取决于成员变量,但是空类比较特殊,编译器给了空类一个字节来唯一标识这个类的对象。算算看,这个类的大小是多少。原创 2024-05-04 22:52:36 · 463 阅读 · 0 评论 -
C++入门系列-类和对象(上)
/类的定义//类体:由成员函数和成员变量组成//一定要注意后面的分号class为定义类的关键字,className为类的名字,{}中为类的主体,注意类定义结束之后后面的分号不能省略。类体中内容称为类的成员,类中的变量称为类的属性或成员变量,类中的函数称为类的方法或成员函数类的两种定义方式1.声明和定义全部放在类体中,需注意,成员函数如果在类中定义,编译器可能会将其当做内联函数来处理。int _age;int main()原创 2024-05-04 22:18:56 · 1194 阅读 · 0 评论 -
C++入门系列-基于范围的for循环(C++11)和指针空值nullptr(C++11)
对于一个有范围的集合而言,有程序员来说明循环的范围是多余的,有时候还容易犯错误,因此C++11中引入了基于范围的for循环,for循环后的括号由冒号‘:’分为两部分,第一部分是范围内用于迭代的变量,第二部分则表示被迭代的范围。在良好的 C/C++编程习惯中,声明一个变量时最好给该变量的初始值,否则可能会出现不可预料的错误,比如未初始化的指针,如果一个指针没有合法的指向,我们基本都是按照如下方式对其进行初始化。这个是代码的运行结果,我们可以通过这段代码看到,形参那里接收的NULL是一个值。原创 2024-05-03 18:40:03 · 656 阅读 · 0 评论 -
C++入门系列-auto关键字(C++11)
使用auto定义变量时必须对其进行初始化,在编译阶段编译器需要根据初始化表达式来推导auto的实际类型,因此auto并非是一种“类型”的声明,而是一个类型声明时的“占位符”,编译器在编译器会将auto替换为变量实际的类型。C++11中,标准委员会赋予了auto全新的含义即:auto不再是一个存储类型指示符,而是作为一个新的类型指示符来指示编译器,auto声明必须由编译器在编译时推导而得。用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&原创 2024-05-03 17:49:29 · 288 阅读 · 0 评论 -
C++入门系列-内联函数
以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内敛函数的地方展开,这就意味着使用内联函数可以提升程序的运行的效率,减小了调用所需要的时间。这个是未使用inline的汇编代码的情况,我们可以看到,它这里ADD是不会进行替换的。下面显示的代码是inline修饰后的代码,大家可以观察一下,有什么问题我们可以看到在使用了inline之后,ADD函数就进行了替换。原创 2024-05-02 23:02:27 · 96 阅读 · 0 评论
分享