【C++】vector的底层原理及实现 我们的目的不是去模拟实现vector,而是更深入地理解vector的底层原理,更好地提升自己。本篇将简单地模拟实现vector,更好地理解它的构造和原理。在C++的STL中,vector是最常用的容器之一,底层是一段连续的线性内存空间(泛型的动态类型顺序表),可以支持随机访问。vector可以存储各种类型,int、char、string等,所以它是一种类模板,可以套用各种类型。
【C++】string的底层原理及实现 string与C语言中的char类型字符串的一个较大的区别就是:char类型的字符串是以\0为结束符,遇到\0就停止;而string是以_size来判断是否结束,遇到\0并不会停止。 这点很重要,一定要弄清楚!
【C++】string基本用法(常用接口介绍) string是表示字符串的字符串类。它提供了一系列成员函数和操作符,使得字符串的操作更加方便和灵活。它位于标准命名空间std下,因此通常需要使用语句或者前缀来引用。string是C++的STL(standard template libaray-标准模板库)的容器之一。本篇,我们主要介绍string的基本用法。所有接口用法都可以在cplusplus参考手册中查阅。下面我们主要介绍string的一些常用接口。string底层实际是basic_string类模板的实例化,是表示字符串类型的模板类。
【C++】模板初阶 模板是一种C++特性,允许创建可重复利用的代码,无需编写多个版本。通过模板可以用来处理数据类型不同而实现代码和功能基本相同的程序。泛型编程:编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础。之前我们学习过函数重载,函数重载常用来处理功能类似而数据类型不同的问题。针对不同类型的对象,我们可以写多个函数重载来满足需求,但是这样不仅麻烦而且效率低。
【C++】动态内存管理new和delete 对于内置类型,malloc/free与new/delete区别不大,真正的区别在于自定义类型。malloc/free与new/delete最大的区别申请自定义类型对象时,malloc是纯粹的开辟空间,不会初始化;而new在申请空间后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理。对于需要资源申请的自定义类型更能体现其优势,以链表为例new会先开辟空间再调用构造函数初始化,delete会先调用析构函数清理资源再释放空间,
【C++】运算符重载 但是我们如果重载成全局函数,就需要类成员变量是公有属性,因为类外无法访问类的私有成员。但是这样就会破坏封装性。 因此,为了保证封装性,我们一般将运算符重载为类的友元函数或类的成员函数。
【C++】初始化列表、匿名对象、static成员、友元、内部类 实际上,构造函数的函数体内,并不是对 对象 初始化的地方,而是对成员变量进行赋值。因为初始化只能初始化一次,而构造函数体内可以多次赋值。真正进行初始化的地方是初始化列表(在创建类变量时,初始化列表将成员变量直接初始化为括号内的表达式值)
【C++】类和对象的引入 C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。比如洗衣机洗衣服的过程:总共四个对象:人、衣服、洗衣液、洗衣机。面向过程:主要是人将衣服放进洗衣机,再倒入洗衣液,启动洗衣机,然后洗衣机完成洗衣功能这些过程。面向对象:整个过程是人、衣服、洗衣液、洗衣机这四个对象之间交互完成的。主要关注对象和对象之间的关系和交互。class为定义类的关键字。
【C++】入门基础 C++是在C的基础之上,容纳进去了面向对象编程思想,并增加了许多有用的库,以及编程范式等。本篇大致介绍C++如何填补C语言留下的坑,以及C++是如何对C语言设计不合理的地方进行优化的,为后续类和对象学习打下基础。C++是向下兼容C语言的,所以C++文件也可以使用C语言代码。
【八大排序算法】插入排序、希尔排序、选择排序、堆排序、冒泡排序、快速排序、归并排序、计数排序 对这八种算法进行性能测试,随机生成10万个数据,统计排序所消耗时间如下:可以看出,三种基本排序:插入排序、选择排序、冒泡排序所花费的时间明显更多。它们的时间效率都是O(N2),但是它们的效率却有明显差别。插入排序最快;选择排序扫描一遍数组,只需要换两次位置;而冒泡排序需要不断交换相邻的元素。因此,选择排序在大型数据集中的性能比冒泡排序更好。剩下五种排序算法跟它们不是一个量级,数据量太小看不出明显差别,我们单独用100万个数据来测试这五种排序算法的性能。计数排序最快,但是计数排序的使用场景也有限。
【数据结构】堆(Heap) 堆(Heap)是一种特殊的非线性结构。堆中的元素是按完全二叉树的顺序存储方式存储在数组中。满足任意结点的值都大于等于左右子结点的值,叫做大堆,或者大根堆;反之,则是小堆,或者小根堆。
【数据结构】二叉树(Binary Tree) 二叉树是一种特殊的树,每个结点最多只能有两个子结点,即二叉树不存在度大于2的结点。二叉树可以分为三个部分:根、左子树、右子树,每颗子树又可以划分为这三个部分,一直递归到叶子结点,叶子结点是其本身的根结点。二叉树的子树有左右之分,次序不能颠倒,因此二叉树是有序树。
【数据结构】栈(Stack)和队列(Queue) 栈和队列都是一种特殊的线性表。栈的特点:后进先出,只能在表尾进行插入和删除。队列的特点:先进先出,只能在表头删除,在表尾插入。它们都可以用顺序存储和链式存储的方式。栈常用顺序存储结构即数组的方式,因为数组的尾插尾删效率高,但可能会存在频繁开辟内存空间和内存空间浪费的问题。而栈的链式存储结构,解决了空间浪费的问题,但每个节点都存放一个指针域,也会存在一定的内存开销,并且在每次申请和释放节点的过程中也存在一定的时间开销。队列常用链式存储结构即链表的方式,
【数据结构】单链表和双链表 1.通过本篇,掌握不带头单向非循环链表和带头双向循环链表之后,大概也能类推写出其他六种链表结构。2.不带头的链表传参数需要二级指针来接收,因为函数中可能会改变头结点(第一个结点)的值,例如链表为空时的操作。带头的链表传参时只需一级指针接收即可,因为并不会改变头结点(哨兵位头结点)的值。3.双向链表插入删除操作时,如果不事先保存结点的前后结点,则需要注意链接顺序,否则会找不到原来的结点。4.在pos位置进行删除操作时,要么传入二级指针置空,要么在外部调用函数完自行置空,否则会形成野指针。
【C语言】通讯录小程序的实现(动态内存版) 在学完结构体、动态内存管理、文件操作之后,我们可以用C语言来实现一个通讯录,通讯录的功能有:1.可以存储足够数量的联系人,每个联系人的信息包括:姓名、年龄、性别、住址、电话;2.功能有:增加、删除、查找、修改、查看、保存、排序联系人。3.联系人信息保存在电脑文件中,下次程序运行联系人信息仍存在。//存放联系人信息int age;}Pepe;//通讯录 结构体嵌套Pepe* data;//指向存放人的信息的空间int sz;//当前已经存放联系人的个数//当前通讯录的最大容量。
【C语言】文件操作(详解) 之前我们输入的数据在程序关闭后就销毁不存在了,比如我们实现一个通讯录,每次关闭这个系统时里面的数据都被清空,这样就不能完整实现通讯录的功能。学完本章文件操作之后,我们可以将我们想要保存的数据内容永久保存到电脑文件中,下次重新运行程序,可以读取之前保存的数据,做到数据的持久化。什么是文件?电脑文件,也称为计算机文件,是存储在计算机的长期或临时存储设备上的数据单元。电脑文件通常具有标识其内容的名称和扩展名,如文本文档、图片、程序等。
【C语言】动态内存管理和柔性数组 我们知道数据的存储有静态存储和动态存储两种方式,各有各的优点,前面我们所学的都是静态存储,今天我们来学习一下如何进行动态的存储。柔性数组是C99 引入的一个新特性,即结构体中的最后一个元素可以是未知大小的数组,并且要求这样的结构体至少包含一个其他类型的成员。char str[];//或者char str[0](部分编译器会报错) 都表示数组大小是未知的//输出4柔性数组的特点1.结构中的柔性数组成员前面必须至少一个其他成员。
【C语言】字符串函数和内存函数及其模拟实现 本篇整理了C语言中针对字符串或者字符数组的各种操作的库函数以及内存操作函数,包括其用法和模拟实现的过程。包括strcpy、strcar、strcmp、strstr、strtok、strerror、memcpy、memmove、memcmp;isalpha、isdigit、tolower、toupper等函数。