vector与迭代器部分内容学习

vector因为“容纳着”其他对象,所以也常常被称之为“容器”

一、vector基本内容

vector<int>ivec;   //ivec保存int类型的对象
vector<Students>Student; //Student保存Students类型的对象

一方面,vector的优势在于,程序在运行的时候可以很高效地往vector对象中添加元素。
另一方面,vector还可以保存“类”的对象,这就很不错了

个人认为,vector的一大好处可以节约内存。就像我们在刚开始学C和C++的时候,若是要开一个数组,都是开类似于

int a[100000]={0};//开一个很大的值
//没错,但是很浪费内存,并且会让别人一看就发现是个新手小白

二、vector的初始化

vector<int>v1(10)//v1有10个元素,每个值都是0
vector<int>v2{10}//v2有1个元素,该元素的值是0

vector<int>v3(10,1);//v3有10个元素,每个值都是1
vector<int>v4{10,1}//v4有2个元素,分别为10和1

可知,()是用来初始化元素个数,{ }是用来初始化vector对象的

三、vector操作


```cpp
v.empty();//如果v不含任何元素,返回真;否则返回假
v.size();//返回v中元素的个数
v.push_back(t);//向v的尾端添加一个值为t的元素
v[n];//返回v中第n个位置上元素的引用
v1 = v2;//用v2中元素的拷贝替换v1中的元素
v1 = {a,b,c...};//用列表中元素的拷贝替换v1中的元素

注意:不能用下标形式添加元素
但可以队确知存在的元素执行下标操作,如:

vector<int> ivec;
cout << ivec[0];//错误:ivec不包含任何元素

vector<int>ivec2(10);
cout << ivec2[10];//错误:ivec2元素的合法检索是0-9

vector<int>c(10);

c[5] = 6;
cout << c[5] << endl;//输出结果是6,此可以说明课以在确定存在的元素执行下表操作

迭代器:
我们可以使用下标运算符来访问string对象的字符或vector对象的元素,其实还有另一种更通用的机制也可以实现同样的目的——迭代器。

迭代器有有效和无效之分,这一点和指针差不多

类似于指针类型,迭代器也提供了对对象的间接访问。但和指针不一样的是,获取迭代器不是选取地址符,有迭代器的类型同时拥有返回迭代器的成员。例如这些类型都有名为begin和end的成员,其中begin成员负责返回指向第一个元素的迭代器。

标准容器迭代器的运算符

	*itera//返回迭代器iter所指元素的引用
	iter->mem//解引用iter并获取该元素的名为mem的成员,等价于(*iter).mem
	++iter//令iter指示容器的下一个元素
	--iter//令iter指示容器的下一个元素

!!因为end返回的迭代器并不实际指示某个元素,所以不能对其进行递增或解引用操作!

迭代器类型:

实际上那些拥有迭代器的标准库类型使用iterator和const_iterator来表示迭代器的类型:

vector::iterator it; //it能读写vector的元素
string::iterator it2; //it2能读写string对象中的字符

vector::const_iterator it3; //it3只能读vector的元素,不能写元素
string::const_iterator it4; //it4只能读string对象中的字符,不能写字符

	vector<int>c;
	for (int i = 0;i < 10;i++)
	{
		c.push_back(i);
	}

	vector<int>::iterator it;

	for (it = c.begin();it != c.end();++it)
	{
		cout << *it << endl;
	}

输出结果是
0
1
2
3
……
9
这就是迭代器的用法了

结合解引用和成员访问操作

检查vector对象是否为空,可以用下面的代码

(it).empty();
其中圆括号必不可少,该表达式的含义是先对it解引用,然后解引用的结果再执行点运算符。
但为了简化上述表达式,c++语言定义了箭头运算符(->)箭头运算符把解引用和成员访问结合在一起,也就是说:
it->mem和(it).mem表达的意思相同。故也可以用it->empty();

例如

typedef struct node
{
    int data;
    struct node* next;
}stu;

stu* list1;
stu* list2;



void creat()
{
    list1 = (stu*)malloc(sizeof(struct node));
    list2 = (stu*)malloc(sizeof(struct node));
    list1->next = NULL;//等价于(*list1).next = nullptr;
    list2->next = NULL;//等价于(*list2).next = nullptr;
}

默写对vector对象的操作会使迭代器失效
vector可以动态的增长,但会有一些副作用。已知的一个限定是不能在范围内for循环想vector对象添加元素,还有一些限制后面会讲。

但凡是使用了迭代器的循环体,都不要向迭代器所属的容器中加元素
(例如push_back())操作。

关于c++primer练习3.26的一些见解
练习3.26:
在 100 页的二分搜索程序中,为什么用的是 mid = beg + ( end - beg ) / 2,而非 mid = ( beg + end ) / 2;?

答案很简单,因为在vector迭代器支持的运算中,不支持两个迭代器相加,但支持一个迭代器+(or)- 一个数值。
而两个迭代器相减就是它们之间的距离,是个数值!

学习资料:《C++Primer》,经典不愧是经典

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值