设为首页 加入收藏

TOP

3.3.2 vector的操作
2013-10-07 00:32:56 来源: 作者: 【 】 浏览:54
Tags:3.3.2 vector 操作

3.3.2  vector的操作

vector标准库提供许多类似于string对象的操作,表3-5列出了几种最重要的vector操作。

表3-5  vector操作

v.empty() 如果v为空,则返回true,否则返回false。
v.size() 返回v中元素的个数。
v.push_back(t) 在v的末尾增加一个值为t的元素。
v[n] 返回v中位置为n的元素。
v1 = v2 把v1的元素替换为v2中元素的副本。
v1 == v2 如果v1与v2相等,则返回true。
!=, <, <=, >, >= 保持这些操作符惯有的含义。

1. vector对象的size

empty和size操作类似于string类型的相关操作(3.2.3节)。成员函数size返回相应vector类定义的size_type的值。

使用size_type类型时,必须指出该类型是在哪里定义的。vector类型总是包括vector的元素类型:

vector::size_type        // ok
vector::size_type          // error

2. 向vector添加元素

push_back()操作接受一个元素值,并将它作为一个新的元素添加到vector对象的后面,也就是“插入(push)”到vector对象的“后面(back)”:

// read words from the standard input and store them as elements in a vector
string word;
vector text;        // empty vector
while (cin >> word) {
    text.push_back(word);  // append word to text
}

该循环从标准输入读取一系列string对象,逐一追加到vector对象的后面。首先定义一个空的vector对象text。每循环一次就添加一个新元素到vector对象,并将从输入读取的word值赋予该元素。当循环结束时,text就包含了所有读入的元素。

3. vector的下标操作

vector中的对象是没有命名的,可以按vector中对象的位置来访问它们。通常使用下标操作符来获取元素。vector的下标操作类似于string类型的下标操作(3.2.3节)。

vector的下标操作符接受一个值,并返回vector中该对应位置的元素。vector元素的位置从0开始。下例使用for循环把vector中的每个元素值都重置为0:

// reset the elements in the vector to zero
for (vector::size_type ix = 0; ix != ivec.size(); ++ix)
    ivec[ix] = 0;

和string类型的下标操作符一样,vector下标操作的结果为左值,因此可以像循环体中所做的那样实现写入。另外,和string对象的下标操作类似,这里用size_type类型作为vector下标的类型。

在上例中,即使ivec为空,for循环也会正确执行。ivec为空则调用size返回0,并且for中的测试比较ix和0。第一次循环时,由于ix本身就是0,则条件测试失败,for循环体一次也不执行。

关键概念:安全的泛型编程(www.cppentry.com)                                                       

习惯于C或Java编程(www.cppentry.com)的C++(www.cppentry.com)程序员可能会觉得难以理解,for循环的判断条件用!=而不是用<来测试vector下标值是否越界。C程序员难以理解的还有,上例中没有在for循环之前就调用size成员函数并保存其返回的值,而是在for语句头中调用size成员函数。

C++(www.cppentry.com)程序员习惯于优先选用!=而不是<来编写循环判断条件。在上例中,选用或不用某种操作符并没有特别的取舍理由。学习完本书第二部分的泛型编程(www.cppentry.com)后,你将会明白这个习惯的合理性。

调用size成员函数而不保存它返回的值,在这个例子中同样不是必需的,但这反映了一个良好的编程(www.cppentry.com)习惯。在C++(www.cppentry.com)中,有些数据结构(如vector)可以动态增长。上例中循环仅需要读取元素,而不需要增加新的元素。但是,循环可以容易地增加新元素,如果确实增加了新元素的话,那么测试已保存的size值作为循环的结束条件就会有问题,因为没有将新加入的元素计算在内。所以我们倾向于在每次循环中测试size的当前值,而不是在进入循环时,存储size值的副本。

我们将在第7章学习到,C++(www.cppentry.com)中有些函数可以声明为内联(inline)函数。编译器遇到内联函数时就会直接扩展相应代码,而不是进行实际的函数调用。像size这样的小库函数几乎都定义为内联函数,所以每次循环过程中调用它的运行时代价是比较小的。

4. 下标操作不添加元素

初学C++(www.cppentry.com)的程序员可能会认为vector的下标操作可以添加元素,其实不然:

vector ivec;   // empty vector
for (vector::size_type ix = 0; ix != 10; ++ix)
     ivec[ix] = ix; // disaster: ivec has no elements

上述程序试图在ivec中插入10个新元素,元素值依次为0到9的整数。但是,这里ivec是空的vector对象,而且下标只能用于获取已存在的元素。

这个循环的正确写法应该是:

for (vector::size_type ix = 0; ix != 10; ++ix)
     ivec.push_back(ix);  // ok: adds new element with value ix

必须是已存在的元素才能用下标操作符进行索引。通过下标操作进行赋值时,不会添加任何元素。

警告:仅能对确知已存在的元素进行下标操作                                           

对于下标操作符([]操作符)的使用有一点非常重要,就是仅能提取确实已存在的元素,例如:

vector ivec;      // empty vector
cout << ivec[0];        // Error: ivec has no elements!
 
vector ivec2(10); // vector with 10 elements
cout << ivec[10];      // Error: ivec has elements 0...9

试图获取不存在的元素必然产生运行时错误。和大多数同类错误一样,不能确保执行过程可以捕捉到这类错误,运行程序的结果是不确定的。由于取不存在的元素的结果是未定义的,因而不同的实现会导致不同的结果,但程序运行时几乎肯定会以某种有趣的方式失败。

本警告适用于任何使用下标操作的时候,如string类型的下标操作,以及将要简要介绍的内置数组的下标操作。

不幸的是,试图对不存在的元素进行下标操作是程序设计过程中经常会犯的严重错误。所谓的“缓冲区溢出”错误就是对不存在的元素进行下标操作的结果。这样的缺陷往往导致PC机和其他应用中最常见的安全问题。

习题                                                          

习题3.13  读一组整数到vector对象,计算并输出每对相邻元素的和。如果读入元素个数为奇数,则提示用户最后一个元素没有求和,并输出其值。然后修改程序:头尾元素两两配对(第一个和最后一个,第二个和倒数第二个,以此类推),计算每对元素的和,并输出。

习题3.14  读入一段文本到vector对象,每个单词存储为vector中的一个元素。把vector对象中每个单词转化为大写字母。输出vector对象中转化后的元素,每八个单词为一行输出。

习题3.15  下面程序合法吗?如果不合法,如何更正?

   vector ivec;
   ivec[0] = 42;

习题3.16  列出三种定义vector对象的方法,给定10个元素,每个元素值为42。指出是否还有更好的实现方法,并说明为什么。

【责任编辑:董书 TEL:(010)68476606】

回书目   上一节   下一节

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇15.3 禁止调整窗口大小 下一篇3.4 迭代器简介

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: