C++个人学习记录01
-
容器用于装数据,容器可以嵌套容器
-
容器种类
- 序列式容器:容器元素在容器的位置,是由进入容器的时间和地点决定
- 关联容器:以容器的规则决定元素在容器的位置
-
算法:解决某一个问题
- STL算法:例如遍历,查找,删除,统计…
-
注意容器和算法的设计是分离的,中间需要建立某种关联,这就是迭代器的作用。容器提供迭代器,算法拿迭代器。
-
注意:
v.begin()
是一个迭代器,它指向容器v
的第一个元素。 -
案例1:统计容器中值为 4 的元素出现的次数
-
包含
<vector>
头文件以使用vector
容器。 -
包含
<algorithm>
头文件以使用其中的算法。 -
创建了一个
vector<int>
类型的容器v
,并向其中添加了一些整数元素。 -
使用迭代器
pStart
遍历容器中的元素,并将每个元素打印出来。 -
使用
std::count
算法统计容器中值为 4 的元素出现的次数,并将结果打印出来。#include<vector> // vector 是一种序列式容器,它提供了动态数组的功能,允许在容器的尾部快速添加和删除元素,并支持随机访问。 // 通过包含 <vector> 头文件,你可以在你的 C++ 程序中使用 vector 容器,从而能够利用其提供的功能 // 动态数组容器 #include<algorithm> // 这个头文件包含了许多常用的算法,如排序、查找、计数、替换等 #include<iostream> using namespace std; void test01(){ // 创建容器,指定vector是int类型,创建一个名为 v 的空的整数类型 vector 容器 vector<int> v;//泛性编程,创建一个容器 动态数组 指定这个容器中放的数据类型 v.push_back(10);//通过vector提供的成员方法,向容器的尾部添加元素 v.push_back(4); v.push_back(5); v.push_back(4); // 创建了一个名为 pStart 的迭代器,它指向 vector<int> 类型的容器 v 的第一个元素。 // vector<int>::iterator:这部分声明了一个迭代器类型,表示这个迭代器可以用来遍历 vector<int> 类型的容器。 // pStart:这是迭代器的名称 // v.begin():这是获取容器 v 中第一个元素的迭代器的方法。begin() 函数返回一个指向容器第一个元素的迭代器。 vector<int>::iterator pStart = v.begin(); //拿到了指向第一个元素的迭代器 vector<int>::iterator pEnd = v.end();//指向最后一个元素的下一个位置 // 如果两个重合则遍历完了 // 这段代码使用迭代器 pStart 来遍历容器中的元素, // 并将每个元素打印出来,直到达到容器末尾。 while (pStart!=pEnd){//判断迭代器 pStart 是否等于迭代器 pEnd cout <<*pStart << " ";//打印迭代器 pStart 指向的元素的值,*pStart 表示获取迭代器 // pStart 指向的元素的值,并将其打印出来。 pStart++; } cout <<endl;//在控制台输出一个换行符 // 使用了 <algorithm> 头文件中的 std::count 算法, // 统计容器中某个元素的个数,算法需要迭代器来用,为什么不用pStart因为已经被++l int n = count(v.begin(),v.end(),4); //v.begin()统计范围的起始位置,这里是容器 v 的第一个元素的迭代器 // v.end():表示统计范围的结束位置,这里是容器 v 的末尾元素的下一个位置的迭代器。 // 注意,std::count 会遍历从起始位置到结束位置之前的所有元素,但不包括结束位置本身。 // 4:表示要统计的值,即要在容器中统计出现的次数的值 cout <<"n:"<< n <<endl; } int main(){ test01(); }
// 输出:10 4 5 4 // n:2
-
-
容器可以放类或对象
-
注意:
Teacher
是一个类,它描述了教师的属性。当你使用该类来创建一个具体的教师对象时,才会产生对象 -
案例2:定义一个类,容器里放对象
// 定义了一个名为 Teacher 的类,其中包含一个构造函数, // 用于初始化 Teacher 对象的属性 ID 和 age。。 class Teacher{ public: Teacher(int id, int age):ID(id),age(age){} // 这句话构造函数,它带有两个参数 id 和 age,用于初始化 Teacher 对象的属性 ID 和 age。 // 在构造函数的初始化列表中,通过 ID(id) 和 age(age) 分别将参数的值赋给了 ID 和 age 成员变量。 // 例如:Teacher teacher1(12345, 35); // 创建一个教师对象,并设置 ID 为 12345,age 为 35 int ID; int age; };
void test02(){ vector<Teacher> v; Teacher t1(1,2),t2(3,4),t3(5,6); v.push_back(t1); v.push_back(t2); v.push_back(t3); vector<Teacher>::iterator pStart = v.begin(); vector<Teacher>::iterator pEnd = v.end(); while(pStart!=pEnd){ // 这里的*pStart就是一个个Teacher对象 Teacher t = *pStart; cout<<"ID:"<<t.ID<<"AGE:"<<t.age<<endl; pStart++; } }
//main函数 test02(); // 输出:ID:1AGE:2 // ID:3AGE:4 // ID:5AGE:6
-
-
容器可以放指针
void test03(){ vector<Teacher*> v;//容器中放Teacher类型指针 // 创建了一个 vector 容器 v,它可以存储 Teacher* 类型的指针。 // 这意味着容器中的每个元素都是指向 Teacher 对象的指针。 // 创建了三个 Teacher 对象 t1、t2 和 t3, // 分别用给定的参数初始化它们的属性 ID 和 age。 Teacher t1(1,2),t2(3,4),t3(5,6); // 创建了三个 Teacher* 类型的指针 p1、p2 和 p3, // 并将它们指向对应的 Teacher 对象。 Teacher* p1 = &t1; Teacher* p2 = &t2; Teacher* p3 = &t3; // 指向 Teacher 对象的指针 p1、p2 和 p3 分别添加到容器 v 中 v.push_back(p1); v.push_back(p2); v.push_back(p3); // 要遍历就要迭代器 vector<Teacher*>::iterator pStart = v.begin(); //指向第一个元素的迭代器 vector<Teacher*>::iterator pEnd = v.end(); //遍历 while(pStart!=pEnd){ // 这里的*pStart就是一个个Teacher类型的指针 Teacher* ttemp = *pStart; cout<<"ID:"<<ttemp->ID<<" AGE:"<<ttemp->age<<endl; pStart++; } }
test03(); // 输出:ID:1 AGE:2 // ID:3 AGE:4 // ID:5 AGE:6
-
案例四
#define CRT_SECURE_NO_WARNINGS #include<iostream> using namespace std; // pStart:指向要统计范围的起始位置的指针。 // pEnd:指向要统计范围的结束位置的下一个位置的指针。 // value:要统计出现次数的值。 int mycount(int* pStart, int*pEnd, int value){ int n = 0; while(pStart != pEnd){ if(*pStart == value){ n++; } pStart++; } return n;//注意这里要返回n } int main(){ int arr[] = {3,2,7,5,2};//数组初始化,容器 // 创建了两个指针 pStart 和 pEnd,分别指向数组 arr 的起始位置和结束位置的下一个元素。 int* pStart = arr; int* pEnd = &arr[sizeof(arr)/sizeof(int)]; // &arr[sizeof(arr)/sizeof(int)]:意思是取数组 arr 中从起始位置开始偏移 sizeof(arr)/sizeof(int) 个 int 元素的地址 // sizeof(arr):返回数组 arr 占用的总字节数。 // sizeof(int):返回 int 类型的变量所占用的字节数。 // sizeof(arr) / sizeof(int):计算出数组 arr 中能容纳的 int 类型元素的个数。这个表达式的结果就是数组 arr 的长度。 // & 操作符用于取地址。因为数组名 arr 表示数组的首地址,所以 &arr[sizeof(arr)/sizeof(int)] 表示数组的起始地址加上偏移量所指向的地址。 int n = mycount(pStart,pEnd,2);//统计2的个数 cout << "n: "<<n<<endl; // system("pause"); // 系统调用,它会执行一个命令来暂停程序的执行。 // pause 命令会等待用户按下任意键后继续执行,因此这条语句会使程序暂停执行,直到用户按下任意键为止 // return EXIT_SUCCESS; // EXIT_SUCCESS 是一个宏定义,表示程序成功执行并正常退出。在标准库 <cstdlib> 中定义了这个宏,它的值通常是 0。 return 0; //输出:2 }