C++ Primer 学习笔记_8_标准库类型(续2) -- iterator



标准库类型(三)

--iterator

序言:

迭代器是一种检查容器内元素并遍历容器元素的数据类型。

所有的标准库容器都定义了相应的迭代器类型,而只有少数的容器支持下标操作;因此,现代C++更倾向于使用迭代器而不是下标操作访问容器元素。

正文:

1、容器的iterator类型

每个标准库容器类型都定义了一个名为iterator的成员;

[cpp] view plaincopyprint?

  1. vector<int>::iterator iter;
vector<int>::iterator iter;

2、begin和end操作

由end操作返回的迭代器指向vector的“末端元素的下一个”,通常称为“超出末端迭代器”。表明了它指向了一个不存在的元素。

如果vector为空,则begin返回的迭代器与end返回的迭代器相同。

通常,end返回的迭代器只代表一个哨兵作用,表示我们已经处理完vector中的所有元素。

[cpp] view plaincopyprint?

  1. for (vector<int>::iterator iter = ivec.begin(); iter != ivec.end(); ++iter)
  2. *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?

  1. for (vector<int>::const_iterator iter = ivec.begin();iter != ivec.end(); ++iter)
  2. {
  3. cout << *iter << endl;  //ok
  4. *iter = 0;              //ERROR
  5. }
    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?

  1. const vector<int>::iterator iter = ivec.begin();
  2. *iter = 0;  //OK
  3. ++iter;     //ERROR
	const vector<int>::iterator iter = ivec.begin();
	*iter = 0;	//OK
	++iter;		//ERROR

[cpp] view plaincopyprint?

  1. //P87 习题3.17 (1)
  2. int main()
  3. {
  4. freopen("input.txt","r",stdin);
  5. vector<int> ivec;
  6. int value;
  7. while (cin >> value)
  8. {
  9. ivec.push_back(value);
  10. }
  11. for (vector<int>::iterator iter = ivec.begin(); iter < ivec.end() - 1; iter += 2)
  12. {
  13. cout << *iter + *(iter + 1) << endl;
  14. }
  15. if(ivec.size() % 2)
  16. {
  17. cout << "The last element " << *(ivec.end() - 1)
  18. << " is not been summed!" << endl;
  19. }
  20. return 0;
  21. }
//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?

  1. //(2)
  2. int main()
  3. {
  4. freopen("input.txt","r",stdin);
  5. vector<string> strVec;
  6. string value;
  7. while (cin >> value)
  8. {
  9. strVec.push_back(value);
  10. }
  11. for (vector<string>::iterator iter = strVec.begin(); iter != strVec.end(); ++iter)
  12. {
  13. for (string::size_type i = 0; i != iter -> size(); ++i)
  14. {
  15. (*iter)[i] = toupper((*iter)[i]);
  16. }
  17. }
  18. size_t cnt = 1;
  19. for (vector<string>::iterator iter = strVec.begin(); iter != strVec.end(); ++iter)
  20. {
  21. cout << *iter << ‘ ‘;
  22. ++ cnt;
  23. if (!(cnt % 8))
  24. {
  25. cout << endl;
  26. }
  27. }
  28. return 0;
  29. }
//(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?

  1. /*
  2. *使mid指向ivec最靠近正中间的元素。
  3. *不能使用:
  4. *vector<int>::iterator mid = (ivec.begin() + ivec.end()) / 2;
  5. *因为将两个迭代器相加是为定义的!
  6. */
  7. vector<int>::iterator mid = ivec.begin() + ivec.size()/2;
  8. /*
  9. *difference_type类型可以保证足够大以存储任何两个迭代器之间的距离。
  10. */
  11. 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长度的操作都会使已存在的迭代器失效!!!

时间: 2024-12-21 15:54:02

C++ Primer 学习笔记_8_标准库类型(续2) -- iterator的相关文章

C++ Primer 学习笔记_7_标准库类型(续1) -- vector类型

 标准库类型(二) --vector类型 引子: vector是同一种类型的对象的集合,每个对象都有一个对应的整数索引值.和string对象一样,标准库将负责管理与存储元素相关的内存. 我们将vector称之为容器,一个容器中的所有对象都必须是同一类型的! [cpp] view plaincopyprint? #include <vector> using std::vector; #include <vector> using std::vector; [模板] vector

C++ Primer 学习笔记_9_标准库类型(续3) -- biteset

 标准库类型(四) --biteset 序言: 位是用来保存一组项或条件的yes/no信息[标识]的简洁方法. [cpp] view plaincopyprint? #include <bitset> using std::bitset; #include <bitset> using std::bitset; 正文: 1.bitset对象的定义和初始化 和vector对象不同的是:bitset类型对象的区别在于其长度而不是类型.在定义bitest时,要在尖括号中说明给出他的长

C++ Primer 学习笔记_6_标准库类型 -- 命名空间using与string类型

 标准库类型(一) --命名空间using与string类型 引: 标准库类型是语言组成部分中更基本的哪些数据类型(如:数组.指针)的抽象! C++标准库定义的是高级的抽象数据类型: 1.高级:因为其中反映了更复杂的概念: 2.抽象:因为我们在使用时不需要关心他们是如何表示的,我们只需要知道这些抽象数据类型支持哪些操作就可以了. 正文: 一.命名空间的using声明 1. using std::cin; ::运算符的作用含义是右操作数的名字可以在左操作数的作用域中找到. 格式: [cpp]

C++ Primer(第五版)学习笔记_8_标准模板库_map映照容器

C++ Primer(第五版)学习笔记_8_标准模板库_map映照容器 map映照容器的元素数据是由一个键值和一个映照数据组成的,键值与映照数据之间具有一一映照的关系. map映照容器的数据结构也是采用红黑树来实现的. 1.map创建.元素插入和遍历访问 #include <iostream> #include <stdio.h> #include <vector> #include <map> #include <string> using n

C++ Primer 学习笔记_11_标准模板库_stack、queue队列容器与priority_queue优先队列容器

C++ Primer 学习笔记_11_标准模板库_stack.queue队列容器与priority_queue优先队列容器 1.stack堆栈 stack堆栈是一个后进先出(Last In First Out,LIFO)的线性表,插入和删除元素都只能在表的一端进行.插入元素的一端称为栈顶,而另一端称为栈底.插入元素叫入栈(Push),删除元素叫出栈(Pop).下图是堆栈示意图 堆栈只提供入栈,出栈,栈顶元素访问和判断是否为空等几种方法.采用push()方法将元素入栈:采用pop()方法出栈:采用

C++ Primer 学习笔记_14_标准模板库_bitset位集合容器

C++ Primer 学习笔记_14_标准模板库_bitset位集合容器 bitset容器是一个bit位元素的序列容器,每个元素只占一个bit位,取值为0或1,因而很节省内存空间.下图是一个bitset的存储示意图,它的10个元素只使用了两个字节的空间. 使用bitset需要声明头文件"#include <bitset>" 1.创建bitset对象 创建bitset对象时,必须要指定容器的大小.bitset对象的大小一经定义,就不能修改了.下面这条语句就定义了bitset对

C++ Primer 学习笔记_23_标准模板库_stack.

C++ Primer 学习笔记_11_标准模板库_stack.queue队列容器与priority_queue优先队列容器 1.stack堆栈 stack堆栈是一个后进先出(Last In First Out,LIFO)的线性表,插入和删除元素都只能在表的一端进行.插入元素的一端称为栈顶,而另一端称为栈底.插入元素叫入栈(Push),删除元素叫出栈(Pop).下图是堆栈示意图 堆栈只提供入栈,出栈,栈顶元素访问和判断是否为空等几种方法.采用push()方法将元素入栈:采用pop()方法出栈:采用

C++ Primer 学习笔记_13_标准模板库_list双向链表容器

C++ Primer 学习笔记_13_标准模板库_list双向链表容器 list容器实现了双向链表的数据结构,数据元素是通过链表指针串连成逻辑意义上的线性表,这样,对链表的任一位置的元素进行插入.删除和查找都是超快速的.下图是双向循环链表的结构示意图. list的每个节点有三个域:前驱元素指针域.数据域和后继元素指针域.前驱元素指针域保存了前驱元素的首地址:数据域则是本节点的数据:后继元素指针域则保存了后继元素的首地址.list的头结点的前驱元素指针域保存的是链表中尾元素的首地址,而list的尾

C++ Primer 学习笔记_10_标准模板库_map和set的对比

C++ Primer 学习笔记_10_标准模板库_map和set的对比   set multiset 创建 set<int> str multiset<string> str 插入 str.insert(8) str.insert("abc") 遍历 set<int>::iterator iter multiset< string >::iterator iter 输出 *iter *iter 删除 n = str.erase(8) 删除