专栏首页编程珠玑C++之旅-vector

C++之旅-vector

前言

标准库类型vector表示对象集合,并且所有的对象类型相同。由于它常常“容纳”其他对象,因此常称作容器。vector也是一个类模板。编译器根据模板创建类型或函数的过程称为实例化,当使用模板时,需要指出编译器应把类或函数实例化成何种类型。

初始化

与string类型一样,vector也有很多种方式进行初始化:

vector<int> v1;    //v1是一个空的vector,它包含的元素是int类型
vector<int> v2(v1);  //v2包含了v1中的副本
vector<int> v2 = v1; //等价于v2(v1)
vector<string> v3(3,"hello"); //包含3个重复string元素,每个元素的值为“hello”
vector<string> v4(8);         //包含了8个string类型的vector,执行8次初始化   
vector<char> v5{'a','b','c'};   //包含了三个char类型的元素,并都有相应的初始值
vector<T> v5={'a','b','c'};       //等价于v5{'a','b','c'}

通常情况,我们可以只提供元素数量,而不需要提供初始值,库会根据类型自动进行一个值初始化,例如:

vector<int> v6(6);   //6个元素,并且每个元素都初始化为0

以下是一些常见错误的初始化:

vector<int> a = "hello"; //错误,vector a只能存储int类型
vector<int> b = 8;     //错误,如果需要使得元素值为8,则需要使用直接初始化的方式并且指定元素个数
vector<string> c("hello"); //错误,字符串字面值不能用于构建vector的对象

特别注意,以下几种情况是有区别的:

vector<int> v1(8)    //包含8个元素,每个元素被初始化为0
vector<int> v2{8}   //包含一个函数,元素值为8
vector<int> v3(8,1)  //包含8个元素,值都为1
vector<int> v3{8,1}  //包含两个元素,值分别为8和1

vector基本操作

vector有以下基本操作:

vector<int> v;
v.push_back(10); //将10添加到v
v.push_back(8);  //将8添加到v的尾部
v.empty();      //如果v不包含任何元素,返回真
v.size()        //返回元素个数
v[1]             //返回第2个元素的引用

注意:定义一个空vector,再在运行向其中添加元素,会比创建时指定容量大小,再添加,会更加高效

解释:通常vector将元素连续存储,当添加的元素超出了原先分配的大小时,就需要重新申请空间,并把原来的元素移到新的位置。vector实现通常会比空间需求分配更大的空间,以避免在添加元素时频繁地重新分配空间并进行移动。既然如此,在一开始就设定大小,并且对其进行初始化就显得没有必要,初始化反而会影响效率,除非vector将要保存的元素都是一样的。

特别注意,不能使用下标形式添加元素,例如:

v[2] = 10;

因为添加之前,不存在下标为2的元素。下标运算符只能用于访问已经存在的元素

迭代器

所有的标准容器都可以使用迭代器。这些容器类型都拥有名为begin和end的成员,分别返回指向第一个元素和尾元素的下一个位置。 例如,可以像下面的方式使用begin和end:

#include <iostream>
#include<string>
#include<vector>
using namespace std;
int main ()
{
    /*将字符串中的字母都转换为大写*/
    string s ("hello world");
    for (auto it = s.begin (); it != s.end (); ++it)
    {
      *it = toupper (*it);
    }
    cout << s << endl;
}

声明迭代器类型it指向s.begin(),遍历每一个元素,将其转换为大写。其中++it让迭代器类型指向下一个元素,直到it指向s.end()。这里使用!=作为循环判断条件是因为很多迭代器并没有<运算符,因此并非所有的标准库类型都可以使用它。但是==和!=是所有标准库容器都定义了的。

对于迭代器之间,可以使用算数运算,例如it=it+2迭代器it的位置向前移动了两个元素,而两个迭代器相减,得到它们之间的元素间隔数。

总结

  • vector是模板而不是类型,不存在包含引用的vector,因为引用不是对象。
  • 下标运算符只能用于访问已经存在的元素。
  • 不能使用下标形式添加元素。
  • 定义一个空vector,再在运行向其中添加元素,会比创建时指定容量大小,再添加,会更加高效。

本文分享自微信公众号 - 编程珠玑(shouwangxiansheng),作者:守望先生

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-11-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 函数参数的传值和传指针有什么区别?

    我们可能听过C语言中的传值和传指针,在其他语言中,也有传引用一说,那么他们到底有什么区别呢?如果你还不能准确地分辨,就该好好了解一下了。

    编程珠玑
  • 彻底理清重载函数匹配

    前面我们讲到了《什么是函数重载?》,有了函数重载之后,就需要确定某次调用需要选用哪个函数。这个过程可以称之为函数匹配或者重载确定。大多数情况下,我们都很容易能够...

    编程珠玑
  • 540 Single Element in a Sorted Array

    Given a sorted array consisting of only integers where every element appears twi...

    编程珠玑
  • C++STL中vector使用策略(一)

    mathor
  • C++STL vector详解(杂谈)

    介绍 这篇文章的目的是为了介绍std::vector,如何恰当地使用它们的成员函数等操作。本文中还讨论了条件函数和函数指针在迭代算法中使用,如在remove_i...

    Angel_Kitty
  • STL vector list deque区别与实现

        向量 相当于一个数组     在内存中分配一块连续的内存空间进行存储。支持不指定vector大小的存储。STL内部实现时,首先分配一个非常大的内存空间预...

    阳光岛主
  • STL-->vector

    verctor vector类似于C语言中的数组,它维护一段连续的内存空间,具有固定的起始地址,因而能非常方便地进行随机存取,即 [] 操作符,但因为它的内...

    用户4492257
  • Leetcode 867. Transpose Matrix

    版权声明:博客文章都是作者辛苦整理的,转载请注明出处,谢谢! https://blog.csdn....

    Tyan
  • 【leetcode】Path Sum II

    Given a binary tree and a sum, find all root-to-leaf paths where each path's sum...

    阳光岛主
  • c++中vector向量几种情况的总结(1)

    vector 是同一种类型的对象的集合,每个对象都有一个对应的整数索引值。标准库将负责管理与存储元素相关的内存。我们把 vector 称为容器,是因为它可以包含...

    随心助手

扫码关注云+社区

领取腾讯云代金券