设为首页 加入收藏

TOP

3.3.3 其他vector操作(2)
2013-10-07 16:27:05 来源: 作者: 【 】 浏览:84
Tags:3.3.3 其他 vector 操作

3.3.3  其他vector操作(2)

结果显示:没有成绩在30分以下的,30分至39分有1个、40分至49分有1个、50分至59分没有、60分至69分有2个、70分至79分有3个、80分至89分有2个、90分至99分有4个,还有1个是满分。

在具体实现时使用一个含有11个元素的vector对象,每个元素分别用于统计各个分数段上出现的成绩个数。对于某个成绩来说,将其除以10就能得到对应的分数段索引。注意:两个整数相除,结果还是整数,余数部分被自动忽略掉了。例如,42/10=4、65/10=6、100/10=10等。一旦计算得到了分数段索引,就能用它作为vector对象的下标,进而获取该分数段的计数值并加1:

  1. // 以10分为一个分数段统计成绩的数量:0--9, 10--19, ... 90--99, 100  
  2. vector<unsigned> scores(11, 0); // 11个分数段,全都初始化为0  
  3. unsigned grade;  
  4. while (cin >> grade) {          // 读取成绩  
  5.     if (grade <= 100)           // 只处理有效的成绩  
  6.         ++scores[grade/10];         // 将对应分数段的计数值加1  

在上面的程序中,首先定义了一个vector对象存放各个分数段上成绩的数量。此例中,由于初始状态下每个元素的值都相同,所以我们为vector对象申请了11个元素,并把所有元素的初始值都设为0。while语句的条件部分负责读入成绩,在循环体内部首先检查读入的成绩是否合法(即是否小于等于100分),如果合法,将成绩对应的分数段的计数值加1。

执行计数值累加的那条语句很好地体现了C++(www.cppentry.com)程序代码的简洁性。表达式

  1. ++scores[grade/10]; // 将当前分数段的计数值加1 

等价于

  1. auto ind = grade/10;            // 得到分数段索引  
  2. scores[ind] = scores[ind] + 1;  // 将计数值加1 

上述语句的含义是:用grade除以10来计算成绩所在的分数段,然后将所得的结果作为变量scores的下标。通过运行下标运算获取该分数段对应的计数值,因为新出现了一个属于该分数段的成绩,所以将计数值加1。

如前所述,使用下标的时候必须清楚地知道它是否在合理范围之内(参见3.2.3节,第95页)。在这个程序里,我们事先确认了输入的成绩确实在0到100之间,这样计算所得的下标就一定在0到10之间,属于0到scores.size()-1规定的有效范围,一定是合法的。

不能用下标形式添加元素

刚接触C++(www.cppentry.com)语言的程序员也许会认为可以通过vector对象的下标形式来添加元素,事实并非如此。下面的代码试图为vector对象ivec添加10个元素:
 

  1. vector<int> ivec; // 空 vector对象  
  2. for (decltype(ivec.size()) ix = 0; ix != 10; ++ix)  
  3.     ivec[ix] = ix; // 严重错误:ivec不包含任何元素 

然而,这段代码是错误的:ivec是一个空vector,根本不包含任何元素,当然也就不能通过下标去访问任何元素!如前所述,正确的方法是使用push_back:
 

  1. for (decltype(ivec.size()) ix = 0; ix != 10; ++ix)  
  2.       ivec.push_back(ix); // 正确:添加一个新元素,该元素的值是ix 

vector对象(以及string对象)的下标运算符可用于访问已存在的元素,而不能用于添加元素。

提示:只能对确知已存在的元素执行下标操作!

关于下标必须明确的一点是:只能对确知已存在的元素执行下标操作。例如,
 

  1. vector<int> ivec;       // 空 vector对象  
  2. cout << ivec[0];        // 错误:ivec不包含任何元素  
  3. vector<int> ivec2(10);  // 含有10个元素的vector对象  
  4. cout << ivec2[10];      // 错误:ivec2元素的合法索引是从0到9 


试图用下标的形式去访问一个不存在的元素将引发错误,不过这种错误不会被编译器发现,而是在运行时产生一个不可预知的值。

不幸的是,这种通过下标访问不存在的元素的行为非常常见,而且会产生很严重的后果。所谓的缓冲区溢出(buffer overflow)指的就是这类错误,这也是导致PC及其他设备上应用程序出现安全问题的一个重要原因。

确保下标合法的一种有效手段就是尽可能使用范围for语句。

3.3.3节练习

练习3.16:编写一段程序,把练习3.13中vector对象的容量和具体内容输出出来。检验你之前的回答是否正确,如果不对,回过头重新学习3.3.1节(第97页)直到弄明白错在何处为止。

练习3.17:从cin读入一组词并把它们存入一个vector对象,然后设法把所有词都改写为大写形式。输出改变后的结果,每个词占一行。

练习3.18:下面的程序合法吗?如果不合法,你准备如何修改?

  1. vector<int> ivec;  
  2. ivec[0] = 42; 

练习3.19:如果想定义一个含有10个元素的vector对象,所有元素的值都是42,请列举出三种不同的实现方法。哪种方法更好呢?为什么?

练习3.20:读入一组整数并把它们存入一个vector对象,将每对相邻整数的和输出出来。改写你的程序,这次要求先输出第1个和最后1个元素的和,接着输出第2个和倒数第2个元素的和,以此类推。

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇3.3.3 其他vector操作(1) 下一篇2.2.1 变量定义

评论

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

·Redis 分布式锁全解 (2025-12-25 17:19:51)
·SpringBoot 整合 Red (2025-12-25 17:19:48)
·MongoDB 索引 - 菜鸟 (2025-12-25 17:19:45)
·What Is Linux (2025-12-25 16:57:17)
·Linux小白必备:超全 (2025-12-25 16:57:14)