C++初学(3)
基础概念以及和C有区别的部分在(1)、(2)都进行了学习,下面花一些篇幅梳理细碎的知识点。
C++数字
数字定义很简单,使用原始的数据类型定义即可。
C++数字运算
C++中的数学运算,都写在标准C和C++库中,叫做内置函数,若是需要使用这些内置函数,需要引用对应的头文件
C++随机数
在许多情况下需要生成随机数,主要函数是rand(),生成一个伪随机数,生成随机数之前需要先调用一下srand()函数。
C++数组
数组其实在C中用的很多,并不陌生,可以存储一个固定大小的顺序集合,数组一般是由连续的内存位置组成,最低的地址对应第一个元素,最高的地址对应最后一个元素。
数组的声明和C一致,类型 数组名[number]。
数组的初始化:可以使用一个初始化语句,或者省略掉数组的大小,若是选择省略,数组的大小就是初始化时数组的大小。
访问数组
数组元素可以通过数组名称加索引进行访问,索引一般放在方括号内,跟在数组的后边。
C++中的数组是非常重要的,下面是一些数组的重要概念:
多维数组:最简单的形式是二维数组。
指向数组的指针:通过指定不带索引的数组名称来生成指向数组第一个元素的指针。
传递数组给函数:通过指定不带索引的数组名称来给函数传递一个指向数组的指针。
从函数返回数组:C++允许从函数返回数组。
C++字符串
表示形式:同C或者C++中引入了string类类型。
C风格的字符串无需叙述,字符数组,以null字符’\0’终止,编译器会在初始化数组时,自动把 \0 放在字符串的末尾。
与数值计算类似,C++中也有大量的函数用来操作以null结尾的字符串。
C++中的string类
在C++的标准库中提供了string类类型,除了以上的功能之外,还额外增加了许多功能。
其实就是将原来的一些函数给进行了封装变成了一个class,这样调用的时候就会变得易用且移植性更好。
1 |
|
C++指针
指针的大体概念和C其实没多少的差异,所有的数据类型的指针都是一样的,不同的只是指向的数据类型不同而已。
每一个变量都有内存位置,每个位置都有自己的地址,可以使用&进行访问。
C++使用指针
同C
C++指针详解
Null指针:空指针,是一个定义在标准库中的值为零的常量。
指针运算:++、–、+、-。
指针和数组:指针和数组有着密切的关系。
指针数组:定义用来存储指针的数组,int* p[5],p中存储着5个指向整形数据的指针。
指向指针的指针:在C++中是允许的。
传递指针给函数。
函数返回指针。
C++引用
相较于指针,C++中区别于C的一个概念就是引用,引用变量是一个别名,是已存在变量的另一个名字,可以指向变量,说到这就很容易和指针混淆在一起。
指针 vs 引用
1.不存在空引用,引用必须连接到一块合法的内存。
2.一旦引用初始化为一个对象,就不能指向另外一个对象,而指针在任何时候都可以指向另一个对象。
3.引用必须在被创建时初始化,指针可以在任何时候被初始化。
C++创建引用
1 | int i = 17; |
引用和指针一样,也常被使用于函数的参数列表和函数返回值。
C++日期&时间
C++主要是继承了C用于日期和时间操作的结构和函数,常规所用的都在标准库当中,不过多赘述。
C++基本输入输出
标准库提供了一组丰富的输入/输出功能,C++的io发生在流中,流是字节序列,流向内存则称为输入操作,若是从内存流向设备,叫做输出。
标准输出流cout
预定义的对象cout是iostream类的一个实例,cout对象连接到标准输出设备,一般是显示屏,和<<结合使用。<<叫做流插入运算符,流插入运算符可以在一个语句多次使用。
标准输入流cin
预定义的对象cin是iostream类的一个实例,cin对象附属到标准输入设备,通常是键盘,一般和流提取运算符>>结合使用。
1 | cin >> name >> age; |
标准错误流cerr
cerr也是iostream类的一个实例,附属于输出设备,但其是非缓冲的,会立即输出,搭配 << 使用。
标准日志流clog
与cerr不同的是,clog对象是缓冲的,每个流插入到clog都会先存储在缓冲区,等到填满或者刷新才输出。
这样分类的好处就是当出现错误的时候,可以立即就知道,而常规运行的输出可以记录在日志当中。
C++结构体
数组是可以存储相同类型数据项的变量,那么结构体就是可以用户自定义的数据类型,允许存储不同类型的数据项,表面来看,结构体和类比较类似,允许定义成员变量和成员函数,定义需要使用struct语句:
1 | struct type_name { |
结构体的优点:
1.适合封装多种简单数据,用于数据的存储。
2.相比于class,语法更为简单,适合小型数据对象。
3.支持构造函数,成员函数和访问权限控制,可以实现面向对象。
访问结构体成员
我们一般使用成员访问运算符(.),该符号是结构体变量名称和我们要访问成员之间的一个符号。
1 |
|
结构体作为函数参数
结构体作为函数参数和其他类型变量或指针类似,和正常访问无异。
结构体虽然在功能上类似于类,但是在细节部分还是有一些不同的,如在访问权限,结构体也是可以使用public、private和protected来定义成员的访问权限,在结构体中,默认权限为public,但是在class中,默认是private。
指向结构体的指针
1 | struct Books *strcut_pointer; |
与其他类型的指针类似,查找结构体的地址使用&运算符放在结构体的前面:
1 | strcut_pointer = &Book1; |
若是需要使用指针来访问结构体的成员,则需要使用->运算符:
1 | struct_pointer->title; |
1 |
|
typedef关键字
利用typedef关键字可以为创建的类型取一个别名:
1 | typedef struct Books{ |
这样就可以使用Books来定义Books类型的变量,而不需要struct关键字。
C++vector容器
C++中的vetcor是一种序列容器,允许在运行的时候动态的插入和删除元素,vector是基于数组的数据结构,但vector可以自动管理内存,不用手动分配和释放,相较数组来说,vector具有更多的灵活性和功能。
vector还是C++标准模板库的一部分,具有灵活的接口和操作,使用vector需要我们包含
创建vector
1 | std::vector<int> myvector; //创建一个存储整数的空vector |
创建时也可以指定初始大小和初始值。
1 | std::vector<int> vec2 = {1, 2, 3, 4}; |
添加元素:使用push_back()方法,可以将元素添加到vector末尾。
访问元素:使用下标操作符[]和at()方法访问vector中的元素。
获取大小:使用size()方法获取vector中元素的数量。
迭代访问:使用迭代器遍历vector中的元素。
1 | for (auto it = myvector.begin(); it != myvector.end(); ++it){ |
删除元素:使用erase()方法可以进行删除。
清空vector:使用clear()方法可以对vector进行清空。
1 |
|
C++的数据结构
C++中有许多数据结构,基础的如数组、结构体、类等,高级的如STL容器如vector、map和unordered_map。
1.数组:
存储相同类型的一组数据。
2.结构体:
允许将不同类型数据组合在一起,形成自定义的数据类型。
3.类(class):
面向对象编程的核心,允许定义成员变量和成员函数,和struct类似,但是功能更加强大,支持继承、封装、多态,同时包含构造函数和析构函数。
1 | class Person { |
4.链表:
一种动态数据结构,由一系列节点组成,每个节点包含数据和指向下一个节点的指针。可以调整大小,不需要提前定义容量,操作效率高。
1 | struct Node{ |
5.栈:
栈是先进后出的数据结构,常用于递归和深度优先搜索等场景,只允许在栈顶进行对应的操作。
1 | stack<int> s; |
6.队列:
队列是先进先出的数据结构,用于广度优先搜索,任务调度场景,插入在队尾进行,删除在队头进行。
1 | queue<int> q; |
7.双端队列:
允许在两端进行插入和删除操作数据结构,是栈和队列的结合体。
1 | deque<int> dq; |
适合需要在两端频繁操作的场景。
8.哈希表:
一种通过无序键值对存储数据的结构,支持快速查找、插入和删除操作,unordered_map是哈希表的实现。
1 | unordered_map<string, int> hashtable; |
除了unordered_map之外,unordered_set也是哈希表的实现之一,使用哈希函数快速定位元素,但是不保证元素的顺序。
9.映射:
一种有序的键值对容器,底层实现是红黑树,和哈希表不同,映射保证键的顺序,使用二叉搜索树实现。
1 | map<string, int> mymap; |
适合需要按照顺序处理数据的场景。
10.集合:
一种用于存储唯一元素的有序集合,保证元素不重复且有序。
1 | set<int> s; |
11.动态数组:
一种标准库的实现,可以动态扩展容量,支持随机访问。
1 | vector<int> v; |
下面就要学习类和对象的知识。