栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++新经典课程学习笔记之第二章-2.8小节

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++新经典课程学习笔记之第二章-2.8小节

本博客将记录:vector类型这个知识点的笔记!    

这方面知识分为3个点:

   一、vector类型简介
   二、定义和初始化vector对象(只介绍日常coding中最常用的几种)
   三、vector对象上的操作(只介绍最常用的几种,其他的用到再翻书orBaidu即可)
   补充:对范围for这个知识点的进一步讲解

   一、vector类型简介:

        vector是标准库提供的一种动态数组容器可以把若干的同类型的对象or变量放在里面。

有2个要注意的点:

        1)使用时要包含头文件

#include

        2)定义vector容器对象的格式:

vector< Original or Self-define dataTypeName> vectorObjectName;
比如:

vector vec;//定义了一个存放int内置数据类型的动态数组(vector容器的对象)
vector vec;//定义了一个存放Person自定义数据类型的动态数组(vector容器的对象)
vector< vector > vec;//容器套容器,这其实就相当于定义了一个二维数组的意思
(但一般来说不推荐这样容器套容器的用法)

vector vec;//vec中每一个元素都是TreeNode*类型的数据

<里面存放的是啥类型的对象or数据> 就认为是vector中存放的数据
因为标准库中vector的源码是函数模板
其实就是类模板的实例化的过程
也即:
template T就是vector中存放的数据的类型
vector vec;
......

注意:不能往vector中放引用类型,因为引用类型就是给别的数据or对象起一个别名而已,本质上并不是对象!

vector vec;//×!!!引用类型不能放入容器中

   二、定义和初始化vector对象(只介绍日常coding中最常用的几种):

1)空vector对象:

vector myStr;//创建了一个空的vector容器的对象

2)元素拷贝的初始化vector:

vector myStr2(myStr);
//这个拷贝过程其实先创建一个存储myStr数据的临时匿名对象,再将这个你们对象拷给myStr2
vector myStr3 = myStr;
//直接进行拷贝赋值

3)C++11标准引入的初始化vector的方式:列表初始化,即:用{ }括号括起来

vector vec {1,3,5,7,9,};
//这和 C++11引入的 int a[] {1,3,5,7,9,}的初始化方式是同理的
vector vec2 {vec} ;
//直接将vec拷贝复制给vec2

4)创建指定容器对象的元素数量的初始化vector方式:

(但凡碰到设置元素数量时候,一般都会用到圆括号)

vector vv(5, 1001);
//给vector容器对象vv创建5个int型的元素,且每一个元素的值都是1001

//打印输出vv
//包含头文件并写一个仿函数print打印int型数据
for_each(vv.begin(), vv.end(), print());
cout << endl;

//当然,你也可以不给初始值,而只是指定容器的size
vector vv(5);
//给vector容器对象vv创建5个int型数据,其中每个数据默认初始值为0
vector vStr(3);
//给vector容器对象vStr创建3个string型数据,其中每个字符串默认初始值为空串""

5)多种初始化vector的方式:

vector v1(10);//创建了一个v1对象,存储了10个int型元素,每个元素的默认初始值为0
vector v2{10};//创建了一个v2对象,存储了一个data为10的int型元素

vector v3(10,1);//10个元素,每个元素的值为1
vector v4{10,1};//2个元素,分别是v4[0] == 10,v4[1] == 1

vector vStr1{ "hello" };//创建要给vStr1对象,其存储了一个"hello"元素
//不提倡这么写,这样写很诡异了!
vector vStr2{10};
//10不为string类型,因此无法通过初始化列表的方式来初始化vStr2
//因此有:
// {}-->退化为(),10不可以作为string类型对象的内容
//这就相当于创建了一个vStr2对象,其size为10的,每个string元素的默认初始值都是空串""

vector vStr3{10,"hello,world!"};//诡异写法
<===>
vector vStr4(10,"hello,world!");//这才是正规的写法
//含义:都是创建了一个vStr3对象,包含10个string类型的元素,每个元素的值都为"hello,world!"

总结:要想正常通过{}大括号给vector对象初始化,那么{}内的值类型必须与vector后的这个<>里边的类型一致。   

三、vector对象上的操作(只介绍最常用的几种):
        对于vector容器,我们最常用的是:事先未知vector里有多少个元素,so我们需要有对vector容器对象动态增加or减少的成员函数(方法),so我们先创建空的vector再对其do一些操作。


1)判断是否为空.empty(),返回的是布尔值(bool,true就是真,false就是假)

vector vecc;
if(vecc.empty()) cout<<"vecc为空!"< 

 

 2).push_back():常用方法,用于向vector中的末尾增加(push)一个元素

vector vecc;
vecc.push_back(1);
vecc.push_back(2);
vecc.push_back(3); 

 

  3).size():常用方法,用于求vector中的元素个数

//输出上述vecc容器对象的size
cout << vecc.size() << endl;//vecc.size() == 3

   4).clear():常用方法,用于清空vector中的all的元素

vecc.clear();//清空
//再输出上述vecc容器对象的size
cout << vecc.size() << endl;//vecc.size() == 0,因为clear清空了

   5)vector[n]:常用方法,用于返回vector容器对象中的index == n 的这个元素,注意,位置是从0开始的,这和数组的用法一模一样

(当然,如果index <0 || index >= vector.size()的话,返回的值就是一个不可预测的结果)

vector vec{1,3,5,7};
for(int i=0;i 

    6) vec1 = vec2; 等号赋值(vector容器中是重载了operator=号的)

vector vec1{1,3,5,7};
vector vec2;//vec2为空
vec2.push_back(111);//vec2--> {111}
vec2 = vec1;//vec2--> {1,3,5,7}
vec2 = {8,8,9,9,10};//vec2--> {8,8,9,9,10}
cout< 

  7) ==  等于号,!= 不等于号 。(vector容器中是重载了operator==号和operator!=号)

所谓的vector相等:容器对象中的元素的个数相同 且 对应位置的元素也相同

同时满足这2条件才叫相等,否则就是不相等。

//仍然拿上述的vec2和vec容器对象作判断
bool ret1 = (vec2 == vec) ? true : false;//ret == false
bool ret2 = (vec2 != vec) ? true : false;//ret == true

  8)vector的范围for的应用(和string对象类似)

  当你做范围for遍历容器vec中的每一个元素时,不想对其元素进行修改,那么就正常用auto即可

(此时是把vec中的元素都赋值一份给到x)

vector vec{1,3,5,7};
for(auto x:vec){cout< 

 

 当你做范围for遍历容器vec中的每一个元素时,想对其元素进行修改,那么就要用到auto&这种引用的方式了,当然对于这里的vectorvec 你可以用 int&,一般我们用auto&让系统进行自动类型推断即可了。(此时是把x指向vec中的元素的地址了,因为取了别名,占据相同的内存空间,因此可以do修改)

vector vec{1,3,5,7};
for(auto& x:vec){
    cout<<"Before revising:"< 

    补充:对范围for这个知识点的进一步讲解:

其实,本质上范围for语句是拿来对于某个序列do遍历(把序列中all的元素都搜素一遍,就叫做遍历)的,使用时对于序列本身而言是固定了的,如果说你此时再添加or减少序列的元素的话,就会导致输出彻底乱套!

就像下面注释了的这行坑爹代码千万不要写!

for (auto x : vec) {
	//vec.push_back(788);//这行会导致输出彻底乱套!
	cout << x << endl;
}
或者
for (int i = 0;i < vec.size();i++) {
	//vec.push_back(788);
    //这行会导致输出死循环因为每一次都push一个元素,导致拥有无法遍历输出完vec中的元素
	cout << vec[i] << endl;
}

 这里直接给结论:在for语句中(遍历一个容器等类似操作时),千万不要改动vector容器的容量size,也即你在这个过程对vector进行增加or删除的操作,千万不要这么干!否则你会很容易因为找不出错误而烦恼!!!

 好,那么以上就是这一2.8小节我所回顾的内容的学习笔记,希望你能读懂并且消化完,也希望自己能牢记这些小小的细节知识点,加油吧,我们都在coding的路上~

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/396044.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号