• C++学习笔记之四(标准库、标准模板库、vector类)


    1、C++标准库

    C + + C++ C++标准库指的是标准程序库( S t a n d a r d Standard Standard L i b a r a y Libaray Libaray),它定义了十个大类,其中包括我们比较熟悉的 i o s t r e a m , s t r i n g iostream, string iostream,string都是这十个大类的其中一个类中的一个小类。而 c + + c++ c++的标准模板库也只是占了其中三个大类而已。
    在这里插入图片描述
    上面这十个类还只是一个些大类,这十个大类下面还有51个小类。例如容器类下有这些小类:
    在这里插入图片描述
    更多内容可以参考这篇文章,链接: C++标准库
    使用的时候,由于十个大类是一个抽象集合,本身是没办法调用的。我们只能调用这些大类下的小类,且必须通过添加头文件的形式。同时, C + + C++ C++标准强制头文件不要加 . h .h .h。下面是一些例子:

    #include				//调用输入输出类中的标准输入输出类
    #include				//调用字符串类
    #include				//调用容器类中的vector
    #include					//调用容器类中的queue
    #include				//调用算法类
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2、C++标准模板库

    标准模板库( S T L : STL: STL: S t a n d a r d Standard Standard T e m p l a t e Template Template L i b r a r y Library Library)区别于标准库,它是一组用于处理各种容器对象的模板,提供了表示容器、迭代器、函数对象、和算法的模板。也就是说,标准模板库是为服务容器而设计的。其中比较容易被忽略的是, a r r a y array array其实也是容器中的一种。
    在这里插入图片描述
    如上图所示,迭代器、函数对象、算法它们虽然同属于 S T L STL STL库的基本组件,但其实都是服务于容器的。

    2.1、vector

    V e c t o r Vector Vector中文名是矢量的意思,是容器类中最基础也是最重要的一个类。

    2.1.1、vector与array

    C + + C++ C++ v e c t o r vector vector a r r a y array array(数组)有很多相似之处,它们都可以被用于存放某一类型的变量。下面则来看一个入门级别的应用——用vector存放特定类型的数值。

    #include
    #include
    
    #define num 5
    using namespace std;
    
    int main()
    {
    	vector<int> mycontain(num);				//声明一个存放整形变量的vector
    	
    	for(int i=0; i<num; i++)
    	{
    		cout<<"please enter the "<<i+1<<" number : ";
    		cin>>mycontain[i];					//跟往数组里面放数据一样,往vector里面放数据
    	}
    	for(int i=0; i<num; i++)
    	{
    		cout<<mycontain[i]<<" ";
    	}
    	cout<<"\n";
    	
    	return 0;	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    2.1.2、vector与函数对象

    v e c t o r vector vector a r r a y array array高级的地方莫过于它能和函数对象、算法以及迭代器结合起来使用,下面直接通过一些例子了解 v e c t o r vector vector和一些常规函数对象的结合。
    有begin, end, push_back, insert, erase, size.

    #include
    #include
    
    using namespace std;
    
    void print_vector(void);		//define a function to print all of numbers in the vector
    
    vector<int> my_vector;
    
    int main()
    {
    	int i,temp;
    	
    	//push some number into the vector and print all of them
    	while(1)
    	{
    		cout<<"please enter the "<<++i<<" number : ";
    		cin>>temp;
    		my_vector.push_back(temp);					//push_back( ),一个往vector的末端添加数字的函数,有且仅有一个输入参数。
    		pd = my_vector.end();								//end(),返回值是vector末端的地址,无输入参数。
    		if(*(my_vector.end()-1) == 0) break;		//if the last number you enter is zero, the program will jump out the loop.
    	}
    	print_vector();
    	
    	//erase some numbers in the vector and print out the rest
    	my_vector.erase(my_vector.begin(), my_vector.begin()+2);		//.erase( , ),拆除vector中某一段数字,有两个输入参数,第一个是将要擦除的起始地址,另一个是停止地址。
    	
    	//my_vector.erase(my_vector.begin()+i);			用这句话也可以删除my_vector中的第i个元素。
    																										//.begin(),返回值是vector的首部地址,无输入参数。
    	print_vector();
    	
    	//insert a number into the vector and print all of them.
    	my_vector.insert(my_vector.end(), 9);											//.insert( , ),往vector某个地方插入一个数字,两个输入参数,第一个是要插入的地址,另一个是要插入的数字
    	print_vector();
    	
    	return 0;	
    }
    
    
    void print_vector(void)
    {
    	for(int i=0; i<my_vector.size(); i++)										//.size(),返回值vector的尺寸大小。
    	{
    		cout<<my_vector[i]<<" ";
    	}	
    	cout<<"\n";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    看完代码,再来根据解决代码中的几个疑惑点。其一,在这句代码:“if(*(my_vector.end() - 1) == 0)”,my_vector.end(),的返回值是一个迭代器,但我这里并没有定义一个迭代器去接收它的返回值,而是直接调用该代码然后解引用。其实这样是合规的。其二,同样是这句代码,我为了拿到vector中的最后一个值,我需要在尾部的地址基础上减去一。这是由vector的性质决定的,我们来看看这个图。
    在这里插入图片描述
    如上图所示,my_vector.end()拿到的并不是最后一个数据的地址,而是内存中其他数据的地址。又由于vector的地址从尾部到首部呈现从高到低分布,所以需要减一,而非加一。
    值得一提的是, v e c t o r vector vector的数据输入输出方式,是从尾部输入,从首部输出。并且当有新的数据输入进来的时候,my_vector.end()的迭代器会指向新输入进来的数据。而不是新输入的数据取代原来尾部的数据,这个理解尤为重要。

    2.1.3、vector与迭代器

    上文有提到过"my_vector.begin()"和"my_vector.end()"的返回值是一个迭代器,并且这个迭代器可以像指针那样操作。便可以大概看出,迭代器和指针颇为相似。但两者的区别是指针指向的必须是连续的内存空间,但迭代器指向的可以是间断的内存空间。这是由于一些容器的内存分配可能零散导致的,如图:
    在这里插入图片描述
    容器的内存空间可能间断分布,而为了准确寻找容器中的数据,迭代器就应运而生了。不过迭代器也分为五个种类,本人学识有限,就只介绍可用于 v e c t o r vector vector的那一种。直接上个例子:

    #include
    #include
    
    using namespace std;
    
    int main()
    {
    	vector<int> my_vector;
    	vector<int>::iterator iter;						//定义一个存放vector地址的迭代器
    	int temp,i=0;
    	
    	while(1)
    	{
    		cout<<"please enter the "<<++i<<" number : ";
    		cin>>temp;
    		my_vector.push_back(temp);			//由于内存分布不完整,当你没添加数据进去之前,它压根不知道下一个数据在那个位置,所以不能用my_vector[i]的方式赋值。
    		iter = my_vector.end();					//把尾部的地址传给迭代器iter
    		if(*(iter-1) == 0) break;						//解引用迭代器以获得对象的值
    	}
    	for(i=0; i < my_vector.size(); i++)
    	{
    		iter = my_vector.begin();
    		cout<<*(iter+i)<<" ";							//同上
    	}
    	cout<<"\n";
    	
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    2.1.4、vector与算法

    这里的算法特指对vector内部数据进行处理的算法,如排序、变换、打乱等。直接上代码看看一些常用的算法怎么用。由于算法部分内容太庞大了,所以这几句话带过会显得十分草率。

    #include
    #include
    #include
    #include
    
    using namespace std;
    
    void vector_print(void);
    vector<int>::iterator iter;
    int array[9] = {1,5,2,7,9,11,3,6,2};
    vector<int> my_vector(array,array+9);
    
    int main()
    {	
    	sort(my_vector.begin(), my_vector.end(), greater<int>());			//输入参数为两个或者三个,前两个参数为迭代器的始末值,最后一个参数是排序标准。
    	vector_print();
    	random_shuffle(my_vector.begin(), my_vector.end());			//输入参数为两个,前两个参数为迭代器的始末值。
    	vector_print();
    	vector<int>::iterator temp = find(my_vector.begin(), my_vector.end(), 9);		//前两个参数为迭代器的始末值,最后一个参数是要查找的值,返回值也是一个迭代器。
    	cout<<*temp<<endl;
    	
    	return 0;
    }
    
    void vector_print()
    {
    	iter = my_vector.begin();
    	for(int i = 0;i<my_vector.size();i++){
    		cout<<*(iter+i)<<" ";
    	}
    	cout<<"\n";	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
  • 相关阅读:
    尚硅谷Java数据结构--希尔排序
    JVM-垃圾回收
    项目管理工具dhtmlxGantt甘特图入门教程(四):可见性和布局视图大小设置
    接口测试经典面试题:Session、cookie、token有什么区别?
    从零搭建开发脚手架 自定义HandlerMethodArgumentResolver-注解@JsonArg和实体CurrentUser
    5G端到端网络切片进展与挑战分析
    Django定时任务之django_apscheduler使用
    PM说 | 一文全方位解析C端用户的评论功能!
    分布式锁选型+缓存db一致性
    手把手教你在项目中引入Excel报表组件
  • 原文地址:https://blog.csdn.net/weixin_45885074/article/details/134034065