【C++】C++11之vector容器详解

目录

一.vector介绍

二.vector初始化

1.初始化vector的方法

2.vector拷贝vector对象

3.列表初始化(花括号)

4.值初始化(圆括号)

5. 列表初始化和值初始化注意点

三.向vector对象中添加元素

1.什么时候使用值初始化?

2.push_back()方法

3.不能使用下标添加元素

四.其他vector操作

五. vector与vector::iterator

1.二者关系

2.begin和end操作

六.遍历vector的方法

1.用迭代器遍历输出容器中的元素

2.使用STL算法for_each()

七.vector存放自定义数据类型

1.vector存放class类型

2.vector存放指针类型

八.vector嵌套vector容器

九.vector的数据结构 


一.vector介绍

vector是STL(标准模板库)中的一个序列式容器,本质是一个类模板

每一个STL库都需要包含对应的头文件,所以使用vector第一步是:

#include <vector>

vector和数组的区别是:vector是动态空间,随着元素的加入,它的内部机制会自行扩充空间容纳新元素。

vector也可以解释为单端数组


二.vector初始化

1.初始化vector的方法

初始化vector对象的方法
vector<T> v1v1是一个空vector,元素类型为T,执行默认初始化
vector<T> v2(v1)把v1的元素拷贝给v2
vector<T> v2=v1把v1的元素拷贝给v2
vector<T> v3(n,val)v3包含了n个重复的元素,每个元素的值都是val
vector<T> v4(n)v4包含了n个重复的元素,每个元素的值都是0
vector<T> v5{a,b,c,...}v5包含了列表中个数的元素,每个元素对应相应的值
vector<T> v6={a,b,c,...}和上面v5等价

2.vector拷贝vector对象

允许把一个vector对象元素拷贝给另一个vector对象,注意两个vector对象的类型必须相同。

vector<T> v2(v1) //把v1的元素拷贝给v2
vector<T> v2(v1.begin(),v1.end()) //把v1的[brgin,end)前闭后开数据拷贝给v2
vector<T> v2=v1	//把v1的元素拷贝给v2,重载运算符=

3.列表初始化(花括号)

vector<T> v5{a,b,c,...}	//v5包含了列表中个数的元素,每个元素对应相应的值
vector<T> v6={a,b,c,...} //和上面v5等价

4.值初始化(圆括号)

vector<T> v3(n,val)	//v3包含了n个重复的元素,每个元素的值都是val
vector<T> v4(n)	//v4包含了n个重复的元素,每个元素的值都是0

5. 列表初始化和值初始化注意点

(1) 如果提供的书初始值列表,则只能把初始值放在花括号中进行列表初始化,不能放进圆括号中

vector<string> v7("a","b","c") //错误!不能用圆括号初始化值列表

(2) 花括号中的值与元素类型不同,会尝试用值初始化列表

vector<string> v8{10,"hi"} //转换使用值初始化

 三.向vector对象中添加元素

1.什么时候使用值初始化?

(1)初始值已知且数量较少

(2)初始值是另外一个vector对象的副本

(3)所有元素初始值都一样

但是当元素各不相同且数量很多时,值初始化就不方便了。

2.push_back()方法

vector<int> v1; //创建一个空vector
for(i=0;i!=100;i++)
{
  v1.push_back(i); //依次添加到v1的尾端
  //循环后v1有100个元素,0-99
}

3.不能使用下标添加元素

vector<int> v2; //创建一个空vector
v2[0] = 1; //错误!

只能用下标读取元素


四.vector其他操作

        引用黑马程序员C++教程中的图:

         为什么capacity()>=size() 参考九.vector的数据结构 

vector支持的操作
v.empty();v中不含任何元素,返回真;否则返回假
v.size();返回v中元素个数
v1.assign(v2.begin(), v2.begin()+3);赋值:将v2的0~2个元素构成的向量赋给v1
v.assign(4,2)赋值:v只含4个元素,且每个元素为2
v.back();返回v的最后一个元素
v.front();返回v的第一个元素

v[i];

返回v的第i个元素,当且仅当v[i]存在

v.clear();

清空v中的元素

v.pop_back(); 

删除v向量的最后一个元素

v.erase(v.begin()+1,v.begin()+3);

删除v中第1个(从第0个算起)到第2个元素

v.insert(v.begin()+1,5);

在v的第1个元素(从第0个算起)的位置插入数值5,如v为1,2,3,4,插入元素后为1,5,2,3,4

v.insert(v.begin()+1,3,5);

在v的第1个元素(从第0个算起)的位置插入3个数,其值都为5

v.insert(v.begin()+1,b+3,b+6);

//b为数组,在v的第1个元素(从第0个算起)的位置插入b的第3个元素到第5个元素

v.capacity();

返回v在内存中总共可以容纳的元素个数
v.resize(10);将v的现有元素个数调至10个,多则删,少则补,其值随机

v.resize(10,2);

将v的现有元素个数调至10个,多则删,少则补,其值为2

v.reserve(100);

将v的容量(capacity)扩充至100
v1.swap(v2);v2为向量,将v1中的元素和v2中的元素进行整体性交换

v1==v2;

v2为向量,向量的比较操作还有!=,>=,<=,>,<

 五. vector与vector::iterator

1.二者关系

每种容器类型都定义了自己的迭代器类型,如vector:

vector<int>::iterator iter;

vector<int>是声明向量容器;
例如 verctor<int> v,就是创建了一个名字叫v的向量容器。

vector<int>::iterator是定义向量迭代器
例如,vector<int>::iterator iter  就是定义了一个名字叫iter 的向量迭代器

iter 实质上是一个迭代器指针,访问时需要解引用*iter,解引用后的数据类型和<int>相同。

2.begin和end操作

每种容器都定义了一对命名为begin和end的函数,用于返回迭代器。如果容器中有元素的话,由begin返回指向第一个元素的迭代器

vector<int>::iterator iter = v.begin();
//这条语句把迭代器iter初始化为由名为begin的vector操作的返回值。如果vector非空,初始化后,iter即指该元素为v[0]

由end操作返回的一个指向vector的末端元素的下一个迭代器。称为“超出末端迭代器”,表明它指向了一个不存在的元素。如果噢vector为空,begin返回的迭代器与end返回的迭代器相同。 

//用迭代器遍历输出容器中的元素
容器名::iterator iter;
for(iter = 容器.begin();iter != 容器.end();iter++)
{
	cout << *iter << ' ';
}

 六.遍历vector的方法

1.用迭代器遍历输出容器中的元素
 

std::vector<int>::iterator iter;
for(iter = v.begin();iter != v.end();iter++)
{
    cout << *iter << ' ';
}

2.使用STL算法for_each()

引入头文件

#include <algorithm>
void myPrint(int val)
{
    cout<<val<<endl;
}

for_each(v.begin,v.end,myPrint) //myPrint回调函数

 七.vector存放自定义数据类型

it实质上是一个迭代器指针,访问时需要解引用*it,解引用后的数据类型和<Person>相同。

1.vector存放class类型

#include <iostream>
#include <vector>
#include <string>

using namespace std;

class Person
{
public:

	Person(string name, int age)
	{
		this->m_name = name;
		this->m_age = age;
	}

	string m_name;
	int m_age;
};

int main()
{
	vector<Person> v;
	Person p1("Mike", 20);
	Person p2("Simth", 21);
	Person p3("Lily", 22);

	v.push_back(p1);
	v.push_back(p2);
	v.push_back(p3);

	for (vector<Person>::iterator it = v.begin(); it != v.end(); it++)
	{
        //cout << "姓名:" << (*it).m_name<< endl;
		cout << "姓名:" << it->m_name<< endl;
		cout << "年龄:" << it->m_age<< endl;
	}

	system("pause");
	return 0;
}

2.vector存放指针类型

#include <iostream>
#include <vector>
#include <string>

using namespace std;

class Person
{
public:

	Person(string name, int age)
	{
		this->m_name = name;
		this->m_age = age;
	}

	string m_name;
	int m_age;
};

int main()
{   //存放指针类型
	vector<Person*> v;
	Person p1("Mike", 20);
	Person p2("Simth", 21);
	Person p3("Lily", 22);
    //&取地址符
	v.push_back(&p1);
	v.push_back(&p2);
	v.push_back(&p3);

	for (vector<Person*>::iterator it = v.begin(); it != v.end(); it++)
	{
        //cout << "姓名:" << *(*it).m_name<< endl;
		cout << "姓名:" << (*it)->m_name<< endl;
		cout << "年龄:" << (*it)->m_age<< endl;
	}

	system("pause");
	return 0;
}

 八.vector嵌套vector容器

这种嵌套关系有点类似于二维数组。主要还是要注意(*it)<==>vector<int>,(*vit)<==>int

#include <iostream>
#include <vector>

using namespace std;

int main()
{
	vector<vector<int>> v;
	//创建小容器
	vector<int> v1;
	vector<int> v2;
	vector<int> v3;

	//向小容器中添加数据
	for (int i = 0; i < 5; i++)
	{
		v1.push_back(i + 1);
		v2.push_back(i + 2);
		v3.push_back(i + 3);
	}

	//将小容器插入到大容器中
	v.push_back(v1);
	v.push_back(v2);
	v.push_back(v3);

	//通过大容器把所有数据遍历一遍
	for (vector<vector<int>>::iterator it = v.begin(); it != v.end(); it++)
	{
		//(*it)的类型是vector<int>
		for (vector<int>::iterator vit = (*it).begin(); vit != (*it).end(); vit++)
		{
            //(*vit)的类型是int
			cout << (*vit) << " ";
		}
		cout << endl;
	}

	system("pause");
	return 0;
}

 九.vector的数据结构 

16a1aa0292594f3b8984d99848f265a5.jpg

参考《C++ primer》、《STL源码剖析》等。

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员赵大宝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值