1、vector的动态增长

  当添加元素时,如果vector空间大小不足,则会以原大小的两倍另外配置一块较大的新空间,然后将原空间内容拷贝过来,在新空间的内容末尾添加元素,并释放原空间。vector的空间动态增加大小,并不是在原空间之后的相邻地址增加新空间,因为vector的空间是线性连续分配的,不能保证原空间之后有可供配置的空间。因此,对vector的任何操作,一旦引起空间的重新配置,指向原vector的所有迭代器就会失效。

vector的size(),capacity(),reserve(),resize()函数:

vector对象的内存布局如下图所示:

start迭代器指向已用空间的首元素,finish指向已用空间的尾元素的下一个位置,end_of_storage指向可用空间的末尾。
     size()函数返回的是已用空间大小,capacity()返回的是总空间大小,capacity()-size()则是剩余的可用空间大小。当size()和capacity()相等,说明vector目前的空间已被用完,如果再添加新元素,则会引起vector空间的动态增长。
     由于动态增长会引起重新分配内存空间、拷贝原空间、释放原空间,这些过程会降低程序效率。因此,可以使用reserve(n)预先分配一块较大的指定大小的内存空间,这样当指定大小的内存空间未使用完时,是不会重新分配内存空间的,这样便提升了效率。只有当n>capacity()时,调用reserve(n)才会改变vector容量。
    resize()成员函数只改变元素的数目,不改变vector的容量。
 
程序说明:
    分配了两个容器a,b。其中每次往a中添加1个元素,共添加10次。使用reserve()预先为b分配一块10个元素大小的空间,之后才每次往b中添加1个元素,共添加10次。当b空间满后,再往其中添加1个元素。之后使用reserve()为b分配一块15(比原空间小)个元素大小的空间。再使用resize()将b的元素个数改变为5个。
    观察上述过程中size()和capacity()大小的变化。
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> a;
cout << "a.size(): " << a.size() << " a.capacity(): " << a.capacity() << endl;
for (int i = 0; i < 10; i++)
{
a.push_back(i);
cout << "a.size(): " << a.size() << " a.capacity(): " << a.capacity() << endl;
}
cout << endl;
vector<int> b;
b.reserve(10);
for (int i = 0; i < 10; i++)
{
b.push_back(i);
cout << "b.size(): " << b.size() << " b.capacity(): " << b.capacity() << endl;
}
b.push_back(11);
cout << "b.size(): " << b.size() << " b.capacity(): " << b.capacity() << endl;
cout << endl;
b.reserve(15);
cout << "after b.reserve(15):" << endl;
cout << "b.size(): " << b.size() << " b.capacity(): " << b.capacity() << endl;
b.resize(5);
cout << "after b.resize(5):" << endl;
cout << "b.size(): " << b.size() << " b.capacity(): " << b.capacity() << endl;
return 0;
}
输出:
a.size(): a.capacity():
a.size(): a.capacity():
a.size(): a.capacity():
a.size(): a.capacity():
a.size(): a.capacity():
a.size(): a.capacity():
a.size(): a.capacity():
a.size(): a.capacity():
a.size(): a.capacity():
a.size(): a.capacity():
a.size(): a.capacity():
b.size(): b.capacity():
b.size(): b.capacity():
b.size(): b.capacity():
b.size(): b.capacity():
b.size(): b.capacity():
b.size(): b.capacity():
b.size(): b.capacity():
b.size(): b.capacity():
b.size(): b.capacity():
b.size(): b.capacity():
b.size(): b.capacity():
after b.reserve():
b.size(): b.capacity():
after b.resize():
b.size(): b.capacity():
现象:a重新分配空间共5次,每次都为之前空间的2倍。b在未超出reserve()预分配的空间时没有重新分配。
结论:
    1. 空的vector对象,size()和capacity()都为0
    2. 当空间大小不足时,新分配的空间大小为原空间大小的2倍。
    3. 使用reserve()预先分配一块内存后,在空间未满的情况下,不会引起重新分配,从而提升了效率。

4. 当reserve()分配的空间比原空间小时,是不会引起重新分配的。

    5. resize()函数只改变容器的元素数目,未改变容器大小(capacity())。

2、vector的用法

(1)头文件

#include<vector>

(2)声明以及初始化

vector<int> vec;        //声明一个int型向量
vector<int> vec(5); //声明一个初始大小为5的int向量
vector<int> vec(10, 1); //声明一个初始大小为10且值都是1的向量
vector<int> vec(tmp); //声明并用tmp向量初始化vec向量
vector<int> tmp(vec.begin(), vec.begin() + 3); //用向量vec的第0个到第2个值初始化tmp
int arr[5] = {1, 2, 3, 4, 5};
vector<int> vec(arr, arr + 5); //将arr数组的元素用于初始化vec向量
//说明:当然不包括arr[4]元素,末尾指针都是指结束元素的下一个元素,
//这个主要是为了和vec.end()指针统一。
vector<int> vec(&arr[1], &arr[4]); //将arr[1]~arr[4]范围内的元素作为vec的初始值

(3)基本操作

1️⃣容量

  • 向量大小: vec.size();
  • 向量最大容量: vec.max_size();
  • 更改向量大小: vec.resize();
  • 向量真实大小: vec.capacity();
  • 向量判空: vec.empty();
  • 减少向量大小到满足元素所占存储空间的大小: vec.shrink_to_fit(); //shrink_to_fit

2️⃣修改

  • 多个元素赋值: vec.assign(); //类似于初始化时用数组进行赋值
  • 末尾添加元素: vec.push_back();
  • 末尾删除元素: vec.pop_back();
  • 任意位置插入元素: vec.insert();
  • 任意位置删除元素: vec.erase();
  • 交换两个向量的元素: vec.swap();
  • 清空向量元素: vec.clear();

3️⃣迭代器

  • 开始指针:vec.begin();
  • 末尾指针:vec.end(); //指向最后一个元素的下一个位置
  • 指向常量的开始指针: vec.cbegin(); //意思就是不能通过这个指针来修改所指的内容,但还是可以通过其他方式修改的,而且指针也是可以移动的。
  • 指向常量的末尾指针: vec.cend();

4️⃣元素的访问

  • 下标访问: vec[1]; //并不会检查是否越界

    • at方法访问: vec.at(1);   //以上两者的区别就是at会检查是否越界,是则抛出out of range异常
  • 访问第一个元素: vec.front();
  • 访问最后一个元素: vec.back();
  • 返回一个指针: int* p = vec.data(); //可行的原因在于vector在内存中就是一个连续存储的数组,所以可以返回一个指针指向这个数组。这是是C++11的特性

5️⃣算法

遍历

vector<int>::iterator it;
for (it = vec.begin(); it != vec.end(); it++)
cout << *it << endl;
//或者
for (size_t i = 0; i < vec.size(); i++) {
cout << vec.at(i) << endl;
}

【校招面试 之 C/C++】第20题 C++ STL(二)之Vector的更多相关文章

  1. 【校招面试 之 网络】第3题 HTTP请求行、请求头、请求体详解

    1.HTTP请求报文解剖 HTTP请求报文由3部分组成(请求行+请求头+请求体): 下面是一个实际的请求报文: ①是请求方法,GET和POST是最常见的HTTP方法,除此以外还包括DELETE.HEA ...

  2. 【校招面试 之 网络】第2题 TCP的可靠传输、流量控制、滑动窗口

    1.可靠传输 (1)三次握手 TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接: (1)第一次握手:建立连接时,客户端A发送SYN包(SYN=j)到服务器B,并进入SYN_S ...

  3. 【校招面试 之 网络】第1题 TCP和UDP

    TCP UDP1.TCP与UDP基本区别  (1)基于连接与无连接  (2)TCP要求系统资源较多,UDP较少:   (3)UDP程序结构较简单(头只有8个字节:源端口号.目标端口号.长度.差错)   ...

  4. 剑指offer 面试20题

    面试20题: 题目:表示数值的字符串 题:请实现一个函数用来判断字符串是否表示数值(包括整数和小数).例如,字符串"+100","5e2","-123 ...

  5. 记2016腾讯 TST 校招面试经历,电面、笔试写代码、技术面、hr面,共5轮

    (出处:http://www.cnblogs.com/linguanh/) 前序: 距离  2016 腾讯 TST 校招面试结束已经5天了,3月27日至今,目前还在等待消息.从投简历到两轮电面,再到被 ...

  6. 墙裂推荐!2020Android阿里&腾讯&百度&字节&美团校招面试汇总

    基本情况 2021届硕士生,Android开发岗 此文主要是2020年年初春招实习的面试和正式校招面试经验汇总,最终校招拿到了腾讯,百度,美团等offer 主要包括阿里4面,腾讯实习4面和校招4面,字 ...

  7. WEB前端面试选择题解答(共36题)

    第1题 ["1", "2", "3"].map(parseInt) A:["1", "2", &qu ...

  8. 牛客网 Java 工程师能力评估 20 题 - 详解

    牛客网 Java 工程师能力评估 20 题 - 详解 不知在看博客的你是否知道 牛客网,不知道就太落后了,分享给你 : 牛客网 此 20 题,绝对不只是 20 题! 免责声明:本博客为学习笔记,如有侵 ...

  9. 《面试八股文》之 JVM 20卷

    微信公众号:moon聊技术 关注选择" 星标 ", 重磅干货,第一 时间送达! [如果你觉得文章对你有帮助,欢迎关注,在看,点赞,转发] 大家好,我是 moon. <面试八股 ...

随机推荐

  1. WDA编译失败问题

    1.放假回来,wda编译失败,报错如下 2018-09-25 10:03:09.020964+0800 WebDriverAgentRunner-Runner[335:33309] +[CATrans ...

  2. Access-Control-Allow-Origin 跨域问题

    1.同源.同源策略(Same origin policy) 同源指的是协议,端口,域名全部相同. 同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺 ...

  3. Android RIL Architecture

    Android RIL Architecture   by Gomathi Sankar   Introduction   The Article explains about the buildin ...

  4. 理解 tornado.gen

    转自:http://blog.xiaogaozi.org/2012/09/21/understanding-tornado-dot-gen/ 理解 tornado.gen SEP 21ST, 2012 ...

  5. unity3d工程下的data file作用

    projectData文件夹中的data file: 1. Player settings – globalgamemanagers and globalgamemanagers.assets fil ...

  6. 微软&中科大提出新型自动神经架构设计方法NAO

    近期,来自微软和中国科学技术大学的刘铁岩等人发表论文,介绍了一种新型自动神经架构设计方法 NAO,该方法由三个部分组成:编码器.预测器和解码器.实验证明,该方法所发现的架构在 CIFAR-10 上的图 ...

  7. AJAX相关总结

    AJAX即"Asynchronous Javascript And XML"(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术. AJAX = 异步 J ...

  8. Web 跨域请求

    在前端开发过程中,难免和服务端产生数据交互.一般情况我们的请求分为这么几种情况:   1. 只关注发送,不关注接收  2.不仅要发送,还要关注服务端返回的信息       a.  同域请求      ...

  9. 2.Triangle (三角形)

    1.等腰直角三角形: https://www.cnblogs.com/FlyingLiao/p/9869040.html 2.1任意三角形: <!DOCTYPE html> <htm ...

  10. Table-Driven Design 表驱动设计

    注:本文所有代码来自 http://www.codeproject.com/Articles/42732/Table-driven-Approach 在许多程序中,经常需要处理那些拥有种种色色不同特性 ...