当前课程知识点:C++语言程序设计基础 > 第6章 数组、指针与字符串(二) > vector对象 > vector对象
vector对象
为什么需要vector?
封装任何类型的动态数组,自动创建和删除。
数组下标越界检查。
例6-18中封装的ArrayOfPoints也提供了类似功能,但只适用于一种类型的数组。
vector对象的定义
vector<元素类型> 数组对象名(数组长度);
例:
vector<int> arr(5)
建立大小为5的int数组
vector对象的使用
对数组元素的引用
与普通数组具有相同形式:
vector对象名 [ 下标表达式 ]
vector数组对象名不表示数组首地址
获得数组长度
用size函数
数组对象名.size()
例6-20 vector应用举例
#include <iostream>
#include <vector>
using namespace std;
//计算数组arr中元素的平均值
double average(const vector<double> &arr)
{
double sum = 0;
for (unsigned i = 0; i<arr.size(); i++)
sum += arr[i];
return sum / arr.size();
}
int main() {
unsigned n;
cout << "n = ";
cin >> n;
vector<double> arr(n); //创建数组对象
cout << "Please input " << n << " real numbers:" << endl;
for (unsigned i = 0; i < n; i++)
cin >> arr[i];
cout << "Average = " << average(arr) << endl;
return 0;
}
基于范围的for循环配合auto举例
#include <vector>
#include <iostream>
int main()
{
std::vector<int> v = {1,2,3};
for(auto i = v.begin(); i != v.end(); ++i)
std::cout << *i << std::endl;
for(auto e : v)
std::cout << e << std::endl;
}
大家好
欢迎回来继续学习
C++语言程序设计
这一节呢
我们来学习使用vector
vector是什么呢
是C++标准模板库
里面的一个类模板
它的作用是什么呢
为什么我们需要使用vector
vector其实
就像一个数组一样好用
但是
它比我们自己定义的数组
使用起来更加安全
更加方便
记得在前面我们讲过一个例题
那个例题封装了一个动态数组
在类里面
为什么我们要把动态数组
封装到类里面去呢
就是因为
每次我们使用动态数组的时候
都要用new去分配空间
然后用delete删除
这样的话呢
如果说你配合的delete删除
不能够及时
或者忘了删除
还会造成内存空间泄漏等等
既不方便 又不安全
那么将这样的动态数组
封装到类里面
把内存空间分配和释放
都在类里面定义好了
以后呢
使用的时候你只要用就行了
这样就更安全 更方便
但是也有个问题
我们自己封装的这个动态数组
大家还记得吧
它就只能用来容纳
point类型的数据
可是我们程序中
还存在着大量其他类型的数据
是不是我们要为
每一种类型的数据
都去定义一个
封装动态数组的类呢
那也太麻烦 太辛苦了吧
实际上呢
类模板里面的这个
vector类模板
就起到这样的作用
它可以用来容纳
任何类型的数组
只要在每次你使用vector
去构造一个新数组的时候
去构造一个新对象的时候
你告诉它
这一次我要容纳的数组
元素是什么类型
就可以了
那么我们一般数组
所能够进行的操作
这些功能它都有
而且呢
自动地分配内存空间
自动地删除
还能进行下标越界检查
确实是非常好用的
下面我们就来看
到底如何去定义
一个vector对象
我们看在定义
一个vector对象的时候
其实很简单
因为它是类模板
关于类模板
我们会在第九章
作详细介绍
但是现在呢
我先简单地给大家说一下
它大致的意思就是说
vector可以容纳任何类型的数组
那么这一次
我们想容纳什么类型
就在这个尖括号里
把类型名写在这儿
那么就相当于定制了一个
我们需要类型的这样一个数组类
然后构造这个类的对象
其实就是非常好用的
这样定义了vector对象以后
我们要使用的时候
就可以当普通数组一样用
就拿这个对象名当数组名用
所以可以用vector对象名
方括号下标的方式
去访问每一个元素
那么它比数组更方便的地方
还在于
它有一个size函数
可以自己返回数组的长度
也就是数组元素个数
这样的话
如果我们传送一个vector对象
给函数的话
我们就不用说
我们还要传送一个数组的长度了
它自己就可以计算出长度了
所以比用数组更方便
下面的例题就演示了
vector对象的用法
现在我们看呢
这是定义了一个
vector类模板的
double实例的这样一个对象
什么意思呢
vector
是标准库里面的一个类模板
我们前面
自己封装的一个动态数组类
它只能适用于存放点类的对象
那它不够通用
而vector是一个
相对非常通用的这么一个模板
你希望它
容纳什么类型的元素的数组
你就在后面注明这个类型就行了
然后它就生成这么一个类
所以vector是一个模板
给它指定了模板参数是double
它就实例化生成了一个类
这个类就专门用来存放
double类型的元素
所以现在我们定义了
这样一个对象arr
它呢是
这个对象呢
实际上它是一个
内嵌了一个数组
这个数组有n个元素
所以我们就可以像
访问普通数组一样
用数组名下标的方式
去访问它的每一个元素
为什么它就可以用下标
为什么
我自己封装的动态数组类
就不能用下标呢
在第八章
我们会讲运算符重载
实际上在vector里面
是重载了下标运算符的
所以才可以用
我们学过以后呢
我们自己也会在第九章
写一个类似的数据结构
我们自己来重载下标运算符
希望大家在第八章
在第九章中能够学会这一点
现在就知道
它可以像数组一样用
用数组名下标的方式去访问
很容易
还有呢
接下来我们要调一个
求平均值的函数
去求这个数组里面的
数据的平均值
这样的话呢
我们觉得怎么只传了一个对象
虽然它可以当数组名用
但是数组元素的个数没传过去
这个函数能知道怎么求平均值吗
我们看一下
在这里呢
确实只接受了一个对象引用
不知道它这里面的元素个数
但是for循环的时候
我们可以去调用这个size
也就是说
在vector对象里面
有一个很有用的size函数
它可以返回里面的元素个数
所以用这个
就可以控制循环了
这样我们就求了平均值
将结果返回
大家看这个vector
是不是很好用呢
下面我们来看一个
通过基于范围的for循环
配合auto类型
来遍历vector的例子
现在我们再看
用一个更方便的方法
用这个基于范围的for循环
来配合这种自动类型
遍历这个vector容器里面的数据
大家看
我们现在构造的这么一个对象v
里面容纳的是整数
int类型的数组
并且给它了初始值有三个元素
1 2 3
好 接下来我们要遍历这个数组
怎么遍历呢
我们也不用去计算
它的size
它有多少个元素了
直接就去调用对象v的begin函数
得到它的起始指针
这个指针呢
是个打引号的指针
是我们在第十章会给大家讲
类库里面的
stl库里面这个范型的类模板
范型的算法这些
所以我们暂时把它理解成
像指针一样
实际上它是一个迭代器
算它是面向对象的指针吧
它的起始
指向它的起始位置的这么
一个指针
控制它结束呢
是达到
指向它结束位置的这么个指针
每一轮循环呢
这个指针加1指向下一个元素
那么
这到底是个什么类型的指针呢
自动类型
大家看这自动类型到这儿
有用了吧
你给它的是什么类型
指针它就接受什么类型
随着这个初始值来定类型
这样就非常方便了
另外呢
我们再看
如果我们要是去遍历
全部的元素的话
我们还可以用这样的方式
就是用基于范围的for循环
每次这个e这个变量
都会从v这个对象中
依次取出一个数组元素来
进行处理
至于说取出的是什么类型的元素
e应该定义成什么类型
这个都不用管
给一个auto自动类型就行了
v里面的元素是什么类型
这个e就会随着定义成什么类型
-导学
--第1章导学
-计算机系统简介
--计算机系统简介
--计算机系统简介 测试题
-计算机语言和程序设计方法的发展
--计算机语言和程序设计方法的发展 测试题
-面向对象的基本概念
--面向对象的基本概念 测试题
-程序的开发过程
--程序的开发过程
--程序的开发过程 测试题
-信息的表示和储存
--计算机的数字系统
--数据的编码表示
--信息的表示和储存 测试题
-实验指导
-导学
--第二章导学
-C++语言概述
--C++语言概述 测试题
-基本数据类型、常量、变量
--程序举例
--基本数据类型、常量、变量 测试题
-运算与表达式
--运算与表达式 测试题
-实验二:简单程序设计(上)
-数据的输入和输出
--数据的输入和输出
--数据的输入和输出 测试题
-选择结构
--if语句
--switch语句
--选择结构 测试题
-循环结构
--for语句
--循环结构 测试题
-自定义类型
--自定义类型
--自定义类型
-第2章小结
--第二章小结
-实验二:C++简单程序设计(下)
-导学
--导学
-函数定义
--函数定义
--函数定义 测试题
-函数调用
--例3-2
--例3-3
--例3-4
--例3-5
--例3-6
--函数调用 测试题
-嵌套与递归
--例3-9
--例3-10
--嵌套与递归 测试题
-函数的参数传递
--函数的参数传递
--函数的参数传递 测试题
-引用类型
--引用类型 测试题
-含有可变参数的函数
--含有可变参数的函数 测试题
-内联函数
--内联函数 测试题
-constexpr函数
--CONSTEXPR函数课后习题
-带默认参数值的函数
--带默认参数值的函数 测试题
-函数重载
--函数重载 测试题
-C++系统函数
--C++系统函数习题
-第3章小结
--第三章小结
-实验三(上)函数的应用
-实验三(下)函数的应用
-导学
--导学
-面向对象程序的基本特点
--面向对象程序的基本特点 测试题
-类和对象
--类和对象的定义
--类和对象 测试题
-构造函数
--构造函数基本概念
--委托构造函数
--复制构造函数
--构造函数 测试题
-析构函数
--析构函数
--析构函数 测试题
-类的组合
--类的组合
--类的组合程序举例
--前向引用声明
--类的组合 测试题
-UML简介
--UML简介
--UML简介课后习题
-结构体与联合体
--结构体与联合体 测试题
-枚举类
--枚举类
--枚举类 测试题
-第4章小结
--第四章小结
-实验四(上)
--实验四(上)
-实验四(下)
--实验四(下)
-导学
--导学
-标识符的作用域与可见性
--标识符的作用域与可见性 测试题
-对象的生存期
--对象的生存期
--对象的生存期 测试题
-类的静态成员
--类的静态成员 测试题
-类的友元
--类的友元 测试题
-共享数据的保护
--共享数据的保护 测试题
-多文件结构和预编译命令
--多文件结构和预编译命令 测试题
-第5章小结
--小结
-实验五
--实验五
-导学
--导学
-数组的定义与初始化
--数组的定义与使用
--一维数组应用举例
--数组的定义与初始化 测试题
-数组作为函数的参数
--数组作为函数的参数 测试题
-对象数组
--对象数组
--对象数组 测试题
-基于范围的for循环
-指针的定义和运算
--指针的定义和运算 测试题
-综合实例
--综合实例
-实验六(上)
--实验六上
-指针与数组
--指针数组
--指针与数组 测试题
-指针与函数
--指针类型的函数
--指向函数的指针
--指针与函数 测试题
-对象指针
--对象指针
--对象指针 测试题
-动态内存分配
--动态内存分配 测试题
-智能指针
--智能指针
-vector对象
--vector对象
--vector对象 测试题
-对象复制与移动
--移动构造
--对象复制与移动 测试题
-字符串
--C风格字符串
--string类
--字符串 测试题
-第6章小结
--第六章小结
-综合实例
--综合实例
-实验六(下)
--实验六(下)