标准库类型(三)
--iterator
序言:
迭代器是一种检查容器内元素并遍历容器元素的数据类型。
所有的标准库容器都定义了相应的迭代器类型,而只有少数的容器支持下标操作;因此,现代C++更倾向于使用迭代器而不是下标操作访问容器元素。
正文:
1、容器的iterator类型
每个标准库容器类型都定义了一个名为iterator的成员;
[cpp] view plaincopyprint?
- vector<int>::iterator iter;
vector<int>::iterator iter;
2、begin和end操作
由end操作返回的迭代器指向vector的“末端元素的下一个”,通常称为“超出末端迭代器”。表明了它指向了一个不存在的元素。
如果vector为空,则begin返回的迭代器与end返回的迭代器相同。
通常,end返回的迭代器只代表一个哨兵作用,表示我们已经处理完vector中的所有元素。
[cpp] view plaincopyprint?
- for (vector<int>::iterator iter = ivec.begin(); iter != ivec.end(); ++iter)
- *iter = 0;
for (vector<int>::iterator iter = ivec.begin(); iter != ivec.end(); ++iter) *iter = 0;
3、++iter表示向前移动迭代器指向容器中的下一个元素。
4、由于end操作返回的迭代器并不指向任何元素,因此不能对他进行解引用和自增操作。
5、如果两个迭代器对象指向同一个元素,则他们相等,==运算符返回真,!=运算符返回假。
6、const_iterator
该类型只能用于读取容器内的元素,而不能改变其值。我们对const_iterator类型解引用时,则可以得到一个指向const对象的引用。
[cpp] view plaincopyprint?
- for (vector<int>::const_iterator iter = ivec.begin();iter != ivec.end(); ++iter)
- {
- cout << *iter << endl; //ok
- *iter = 0; //ERROR
- }
for (vector<int>::const_iterator iter = ivec.begin();iter != ivec.end(); ++iter) { cout << *iter << endl; //ok *iter = 0; //ERROR }
7、不要把const_iterator对象与const的iterator对象混淆。
[cpp] view plaincopyprint?
- const vector<int>::iterator iter = ivec.begin();
- *iter = 0; //OK
- ++iter; //ERROR
const vector<int>::iterator iter = ivec.begin(); *iter = 0; //OK ++iter; //ERROR
[cpp] view plaincopyprint?
- //P87 习题3.17 (1)
- int main()
- {
- freopen("input.txt","r",stdin);
- vector<int> ivec;
- int value;
- while (cin >> value)
- {
- ivec.push_back(value);
- }
- for (vector<int>::iterator iter = ivec.begin(); iter < ivec.end() - 1; iter += 2)
- {
- cout << *iter + *(iter + 1) << endl;
- }
- if(ivec.size() % 2)
- {
- cout << "The last element " << *(ivec.end() - 1)
- << " is not been summed!" << endl;
- }
- return 0;
- }
//P87 习题3.17 (1) int main() { freopen("input.txt","r",stdin); vector<int> ivec; int value; while (cin >> value) { ivec.push_back(value); } for (vector<int>::iterator iter = ivec.begin(); iter < ivec.end() - 1; iter += 2) { cout << *iter + *(iter + 1) << endl; } if(ivec.size() % 2) { cout << "The last element " << *(ivec.end() - 1) << " is not been summed!" << endl; } return 0; }
[cpp] view plaincopyprint?
- //(2)
- int main()
- {
- freopen("input.txt","r",stdin);
- vector<string> strVec;
- string value;
- while (cin >> value)
- {
- strVec.push_back(value);
- }
- for (vector<string>::iterator iter = strVec.begin(); iter != strVec.end(); ++iter)
- {
- for (string::size_type i = 0; i != iter -> size(); ++i)
- {
- (*iter)[i] = toupper((*iter)[i]);
- }
- }
- size_t cnt = 1;
- for (vector<string>::iterator iter = strVec.begin(); iter != strVec.end(); ++iter)
- {
- cout << *iter << ‘ ‘;
- ++ cnt;
- if (!(cnt % 8))
- {
- cout << endl;
- }
- }
- return 0;
- }
//(2) int main() { freopen("input.txt","r",stdin); vector<string> strVec; string value; while (cin >> value) { strVec.push_back(value); } for (vector<string>::iterator iter = strVec.begin(); iter != strVec.end(); ++iter) { for (string::size_type i = 0; i != iter -> size(); ++i) { (*iter)[i] = toupper((*iter)[i]); } } size_t cnt = 1; for (vector<string>::iterator iter = strVec.begin(); iter != strVec.end(); ++iter) { cout << *iter << ' '; ++ cnt; if (!(cnt % 8)) { cout << endl; } } return 0; }
8、迭代器的算术操作
[cpp] view plaincopyprint?
- /*
- *使mid指向ivec最靠近正中间的元素。
- *不能使用:
- *vector<int>::iterator mid = (ivec.begin() + ivec.end()) / 2;
- *因为将两个迭代器相加是为定义的!
- */
- vector<int>::iterator mid = ivec.begin() + ivec.size()/2;
- /*
- *difference_type类型可以保证足够大以存储任何两个迭代器之间的距离。
- */
- difference_type = iter1 – iter2;
/* *使mid指向ivec最靠近正中间的元素。 *不能使用: *vector<int>::iterator mid = (ivec.begin() + ivec.end()) / 2; *因为将两个迭代器相加是为定义的! */ vector<int>::iterator mid = ivec.begin() + ivec.size()/2; /* *difference_type类型可以保证足够大以存储任何两个迭代器之间的距离。 */ difference_type = iter1 – iter2;
9、谨记:任何改变vector长度的操作都会使已存在的迭代器失效!!!