在我们编写每一个程序时,都会或多或少的需要存储一些数据,而c++在这方面只提供了几种最基本的方法,我们可以创建局部变量或者全局变量在存放某个值,也可以用数组来存放多个值。
对于容器(container):能够容纳两个或更多个值的数据结构
数组是c++唯一支持的容器,但数组并不适合用来解决所有的问题
假如我们编写一个程序:输入一串字母,判断与给定单词是否一样。
这时候我们会想到用数组来存放,我们将不得不遍历每一个数组元素并把它与给定的单词进行比较, 这样如此下去效率实在太低。
计算机领域的科学家们在过去的几十年里投入了大量的精力来为不同类别的问题寻找最合适的数据结构
于是现在在c++标准库里有许多现成的容器,他们都是经过老一辈精心的设计和测试,可以直接拿来就用。
c++标准库提供的向量(vector)类型从根本上解决了数组先天不足的问题(受限于一个固定的长度)
就像可以创建各种不同类型的数组一样,我们也可以创建各种不同的类型的向量:
-std::vector<type>vectorName;
并且,你还可以用它的size()方法查知某给定向量的当前长度
下面看一个例子vector.cpp
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
int main()
{
vector<string>names;
names.push_back("lvwendong");
names.push_back("lpp");
for( int i=0;i<names.size();i++)
{
cout<<names[i]<<"\n";
}
return 0;
}
c++的类型检查功能非常强大,如果你试图把一个其他类型的值放到一个字符串向量里,编译器会立刻报错。
把一些元素放到一个向量里以后,就可以用赋值操作符来改变他们的值了,就像对待数组元素那样:names[0]="lucy";
对于刚才的例子虽然工作的很好并也使用了一个标准的容器(向量容器),但它还是有个小问题。
就是在遍历向量里的各个元素时,我们仍把它视为一个c++数组来对待。
但是如果想改变另一种不提供此方法访问的容器(比如栈),我们就不得不对程序作出很多修改才得以实现
因为对容器里的各个元素进行遍历是一种十分常见的任务,所以应该有一种标准的方式来做这件事。
c++标准库提供的各种迭代器(iterator)就是这样来的。
迭代器是一种功能非常有限却非常实用的函数,提供一些基本的操作符:*、++、==、!=、=。
因为迭代器的功能室如此的基础,所以标准库里的每一种容器都支持。
通过使用迭代器,当在程序里改用另一种容器的时候就用不着修改那么多的代码了。
每一种容器都必须提供自己的迭代器,事实上每一种容器都将其迭代器以嵌套的方式定义于内部。
因为各种迭代器的接口相同,型号却不同,这就是所谓泛型程序设计的概念:所有操作行为都是用相同的接口,虽然它们的具体实现不同。
修改vector.cpp,使用迭代器。
vector1.cpp:
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
int main()
{
vector<string>names;
names.push_back("lvwendong");
names.push_back("lpp");
vector<string>::iterator iter = names.begin();
while( iter!=names.end() )
{
cout<<*iter<<"\n";
++iter;
}
return 0;
}
回顾刚才我们对向量示例程序的修改,别的先不说,用来遍历向量元素的循环比原来复杂了许多,可代码的行为还是老样子。
迭代器的真正价值体现在它们可以和所有的容器配合使用,而使用迭代器去访问容器元素的算法可以和任何一种容器配合使用
那么,下面我将带大家再修改一下这个例子,来演示算法的强大之处,在输出该容器里的元素之前,先按字母顺序对它们进行排序。
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
vector<string>names;
names.push_back("lvwendong");
names.push_back("lpp");
names.push_back("cgfg");
names.push_back("dfss");
names.push_back("rgfggf");
names.push_back("zang");
sort(names.begin(),names.end());
vector<string>::iterator iter = names.begin();
while( iter!=names.end() )
{
cout<<*iter<<"\n";
++iter;
}
return 0;
}