C++ Vecctor容器浅析

Vector的定义

  • 向量(Vector)是一个封装了动态大小数组的顺序容器(Sequence Container)。跟任意其它类型容器一样,它能够存放各种类型的对象。可以简单的认为,向量是一个能够存放任意类型的动态数组。
  • vector是对象的集合,其中所有对象的类型都相同。集合中的每个对象都有一个与之对应的索引,索引用于访问的对象。
  • vector是模板而不是类型,由vector生成的类型必须包含vector中元素的类型,比如vector<int>。
  • vector不可以将引用作为其元素,因为引用不是对象。

定义和初始化vector对象

  • 和任何类型一样,vector模板模板控制着定义和初始化向量的方法。
Vector<T> v1v1是一个空的vector,潜在的元素是T类型的,执行默认初始化
Vector<T> v2(v1)

v2中包含v1中所有元素的副本

Vector<T> v2 = v1等效于v2(v1),v2中包含v1中所有元素的副本
Vector<T> v3(n,val)v3中包含n个重复的元素,每个元素的数值都是val
Vector<T> v4(n)v3包含了n个重复地执行值初始化的对象
Vector<T> v5{a,b,c.......}v5包含了初始值个数的元素,每个元素被赋予相应的初始数值
Vector<T> v5={a,b,c.....}等效于Vector<T> v5{a,b,c.......}
  • 使用方法,先定义一个空的vector,当运行的时候将获取到的元素数值逐一添加。
  • vector之间进行赋值拷贝,需要逐一一个前提,那就是类型必须是一致的。
    vector<int> ivec;vector<int> ivec2(ivec);vector<int> ivec3 = ivec;vector<string>ivec4 = ivec;//错误,类型不符合

列表初始化vector对象 

  • 使用拷贝初始化时(即使用=),只可以提供一个初始数值
  • 使用提供的是一个类内初始值,则可以使用拷贝初始化或者使用花括号的形式进行初始化
  • 如果提供的是初始元数值的列表,则只能把初始值都放在圆括号里面进行列表初始化,但是不能放在圆括号里面。
  • 例如: vector<string> v1 = {"a","ccc","ddd"}; //正确,列表初始化
  • 例如: vector<string> v1 = ("a","ccc","ddd"); //错误,不可以使用圆括号

创建指定数量的元素

  • 还可以使用vector对象容纳的元素数量和所有元素的统一初始值来初始化vector对象。
  • vector<int> v1(10,-1);//创建10个int类型的元素,每个元素的数值都被初始化为-1
  • vector<string> v2(10,"hi!");//创建10个string类型的元素,每个元素的数值都被初始化为hi!

值初始化

  • 可以只提供vector对象容纳的元素数量,而不提供初始数值。此时库会创建一个值初始化的元素初值,并将其赋值给容器中所有的元素。这个初值由vector对象中的元素类型决定。
  • 如果vector的对象元素类型是内置类型的,比如int,则元素初始值会被自动设置为0;如果是string类型的,则元素由类默认初始化。

限制要求

  • 1,有些类必须明确的提供初始值,如果vector对象中元素的类型不支持默认初始化,就必须提供初始的元素值
  • 2,如果只提供了元素的数量没有提供元素的初始值,只能使用直接初始化。vector<int> v1 = 10;//错误,使用直接初始化

列表初始值还是元素的数量

  • 初始化的真实含义依赖于传递初始值的时候使用的是花括号还是圆括号

    vector<int> v1 (10); //v1有10个元素,每个元素的数值都是0vector<int> v2 {10}; //v2有1个元素,元素的数值是10vector<int> v3(10,1); //v3有10个元素,每个元素的数值都是1vector<int> v4{10,1};//v4有2个元素,元素的数值分别是10和1

向vector中添加元素

  • 直接初始化常见于三种场景:1,初始值已知且数量较少;2,初始值是另外一个vector对象的副本;3,所有元素的初始值一致
  • 使用函数push_back将元素添加到vectro容器的末尾,下面的例子是将100个元素押入容器中
    vector<int> vInt;for(int i = 0;i !=100 ;i++){v2.push_back(i);}
  • 从标准输入中读取单词,将其作为vector对象的元素进行存储
    string word;vector<string> text;   //空的vector对象while (cin >> word){text.push_back(word);}
  •  循环体内部包含了有向vector对象添加元素的语句,则不可以使用范围for循环。

其他vector操作

v.empty()如果v不含有任何元素,返回为真;否则返回为假
v.size()

返回元素的个数

v.push_back(t)向v的末尾添加一个数值为t的元素
v[n]返回v中第n个位置上元素的引用
v1=v2用v2中的元素拷贝替换v1中的元素
v1={a,b,c...}

用列表中的元素拷贝替换v1中的元素

v1 == v2 v1和v2相等当且仅当元素数量相同,且对应位置上的元素值都相等
v1 != v2 
< <= >= >以字典序比较大小
  • 访问vector中的元素和访问string对象中字符的方式差不多,也是通过元素在vector对象上的位置。 例如可以使用范围for语句来处理vector中所有元素。
    vector<int> v {1,2,3,4,5,6,7,8,9};for(auto &i : v){   //对于v中每个元素进行处理,其中i是一个引用i *= i;}for(auto &i : v){cout << i << " " << endl;}

第一个循环把控制变量i定义成引用类型,这样就可以通过i给v的元素赋值

  • 要使用size_type的时候,需要指定它是由哪种类型定义的。例如:vector<int>::size_type   //正确

计算Vector内对象的索引

  • 可以通过下标运算符来获取指定的元素;还可以通过计算得到vector内对象的索引,然后直接获取索引位置上的元素。
  •  计算得到vector内对象的索引,举个例子,对于输入的成绩进行归档,每10分一个档次。计算方式是将其除以10就能得到对应的分数段索引,例如65/10 = 6;42/10 = 4;一旦计算得到了分数段索引,就可以把它作为vector对象的下标,进而可以获取该分数段的计算值并加1。
//  以10分为一个分数段统计成绩的数量,0~9,10~19,...,90~99,100vector<unsigned> scores(11,0);    //11个分数段,全部初始化为0unsigned grade;while(cin >> grade){                    //读取成绩if(grade <= 100 ){                  //只处理有效的成绩++scores[grade / 10];           //将对应分数段的计数值加1}if(grade == 'T'){                   //输入字符T,退出程序break;}}for(auto i : scores){                   //输出存储的字段信息cout << i << " " << endl;}

不可以使用下标的形式添加元素

    vector<int> ivec;//空的vector对象for(decltype(ivec.size()) ix = 0; ix != 10; ix++){ivec[ix] = ix;//严重错误,vector不包含任何的元素}
  • 正确的方法是通过push_back的方法,将元素逐一押入容器中。
  • vector对象的下标运算符可以用于访问已经存在的元素,但是不可以用于添加元素。 

容器的特性

顺序序列

  • 顺序容器中的元素按照严格的线性顺序排序。可以通过元素在序列中的位置访问对应的元素。

动态数组

能够感知内存分配器的(Allocator-aware)

  • 容器使用一个内存分配器对象来动态地处理它的存储需求

基本函数实现

1.构造函数

  • vector():创建一个空vector
  • vector(int nSize):创建一个vector,元素个数为nSize
  • vector(int nSize,const t& t):创建一个vector,元素个数为nSize,且值均为t
  • vector(const vector&):复制构造函数
  • vector(begin,end):复制[begin,end)区间内另一个数组的元素到vector中

2.增加函数

  • void push_back(const T& x):向量尾部增加一个元素X
  • iterator insert(iterator it,const T& x):向量中迭代器指向元素前增加一个元素x
  • iterator insert(iterator it,int n,const T& x):向量中迭代器指向元素前增加n个相同的元素x
  • iterator insert(iterator it,const_iterator first,const_iterator last):向量中迭代器指向元素前插入另一个相同类型向量的[first,last)间的数据

3.删除函数

  • iterator erase(iterator it):删除向量中迭代器指向元素
  • iterator erase(iterator first,iterator last):删除向量中[first,last)中元素
  • void pop_back():删除向量中最后一个元素
  • void clear():清空向量中所有元素

4.遍历函数

  • reference at(int pos):返回pos位置元素的引用
  • reference front():返回首元素的引用
  • reference back():返回尾元素的引用
  • iterator begin():返回向量头指针,指向第一个元素
  • iterator end():返回向量尾指针,指向向量最后一个元素的下一个位置
  • reverse_iterator rbegin():反向迭代器,指向最后一个元素
  • reverse_iterator rend():反向迭代器,指向第一个元素之前的位置

5.判断函数

  • bool empty() const:判断向量是否为空,若为空,则向量中无元素

6.大小函数

  • int size() const:返回向量中元素的个数
  • int capacity() const:返回当前向量所能容纳的最大元素值
  • int max_size() const:返回最大可允许的vector元素数量值

7.其他函数

  • void swap(vector&):交换两个同类型向量的数据
  • void assign(int n,const T& x):设置向量中第n个元素的值为x
  • void assign(const_iterator first,const_iterator last):向量中[first,last)中元素设置成当前向量元素

8.补充完善

  • push_back 在数组的最后添加一个数据
  • pop_back 去掉数组的最后一个数据
  • at 得到编号位置的数据
  • begin 得到数组头的指针
  • end 得到数组的最后一个单元+1的指针
  • front 得到数组头的引用
  • back 得到数组的最后一个单元的引用
  • max_size 得到vector最大可以是多大
  • capacity 当前vector分配的大小
  • size 当前使用数据的大小
  • resize 改变当前使用数据的大小,如果它比当前使用的大,则填充默认值
  • reserve 改变当前vecotr所分配空间的大小
  • erase 删除指针指向的数据项
  • clear 清空当前的vector
  • rbegin 将vector反转后的开始指针返回(其实就是原来的end-1)
  • rend 将vector反转构的结束指针返回(其实就是原来的begin-1)
  • empty 判断vector是否为空
  • swap 与另一个vector交换数据

基本用法

  • #include < vector> 
    using namespace std;

简单的介绍

  1. Vector<类型>标识符
  2. Vector<类型>标识符(最大容量)
  3. Vector<类型>标识符(最大容量,初始所有值)
  4. Int i[5]={1,2,3,4,5}
    Vector<类型>vi(I,i+2);//得到i索引值为3以后的值
  5. Vector< vector< int> >v; 二维向量//这里最外的<>要有空格。否则在比较旧的编译器下无法通过

相关知识的引用

模板

  • 模板本身不是类或者函数,相反可以把模板看做是编译器生成类或者函数的说明。编译器根据模板创建类或者函数的过程称为实例化,当使用模板的时候,需要指出编译器把类或者函数实例化成为哪种类型。
  • 对于类模板来讲,提供一些额外的类来指定将模板实例化成为什么样的类。需要提供的信息是由模板来决定的,即在模板名字的后面跟上一段尖括号,在括号上放上相关的信息。
  • 以vector为例,提供的额外信息是vector内所存放对象的类型
vectorr<int> ivec;//ivec保存int类型的对象
vector<Sales_item> Sales_vec;//保存Sales_item类型的对象
vector<vector<string>> file;//该向量的元素是vector对象

缓冲区溢出

  • 通过下标访问不存在的元素会导致缓冲区溢出。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/447064.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++primer第二章2.4节对于const限定符相关内容进行详解

const限定符 const对象一旦创建后其数值就不会被再次改变&#xff0c;因此const对象必须初始化。const对象只在文件中有效在不同的文件中使用不同的const来定义不同的常量&#xff0c;那么每个文件定义的变量只会在自己所属的文件中有效。如果想让多个文件共享同一个const变量…

二分法的常见问题

mid(leftright)/2; mid (high - low) / 2 low; 这样写可以防止left right溢出 ,不过数足够大是时候该溢还是溢 为什么要取右边中间数呢&#xff1f;这是因为在区间里 只有 2 个元素的时候&#xff0c;把[left…right]划分成[left…mid - 1]和[mid…right]这两个区间&#x…

演示IPFS的一个完整的流程以及针对部分概念的详解

整体的流程 1&#xff0c;创建ipfs节点 通过ipfs init在本地计算机建立一个IPFS节点本文有些命令已经执行过了&#xff0c;就没有重新初始化。部分图片拷贝自先前文档&#xff0c;具体信息应以实物为准 $ ipfs init initializing IPFS node at /Users/CHY/.ipfs generating 2…

c++ 算法的时间复杂度

一般ACM或者笔试题的时间限制是1秒或2秒。 在这种情況下&#xff0c;C代码中的操作次数控制在 10^7为最佳。 下面给出在不同数据范国下&#xff0c;代码的时间复杂度和算法该如何选择&#xff1a; 1.n≤ 30,指数级别&#xff0c;dis剪枝&#xff0c;状态压缩dp 2.n < 100 &g…

简单工厂模式实现计算器

#include <iostream> #include <vector> #include <string> #include <iostream> #include <map> using namespace std; #define __THROW_ZERO do {cerr << "The dividend is 0" << endl; exit(1);}while(0);/* 简单工厂处…

TDengine安装教程

TDengine安装教程 前言 TDengine的安装十分简单&#xff0c;可以有以下三种安装方式&#xff0c;源码安装、通过Docker容器进行安装、通过安装包进行安装。但是使用源码安装较为复杂&#xff0c;通过docker的方式最为简单&#xff0c;但是需要一定docker相关的知识&#xff0…

C++中size_t的学习

size_t的定义 size_t是一种数据相关的无符号类型&#xff0c;它被设计得足够大以便能够存储内存中任意对象的大小。设计 size_t 就是为了适应多个平台&#xff0c;size_t等效于unsigned short int 或者 unsigned long int 类型&#xff0c;这个过程是动态匹配的。在需要通过数…

策略模式解决商店打折问题

#include <bits/stdc.h> using namespace std; /*策略模式解决商店打折问题*/class Cashsuper { private:/* data */ public:virtual double addcash(double cash) 0;double Getresult(double money){return addcash(money);} };class Cashnormal : public Cashsuper {p…

android 软件首次运行时引导页左右滑动效果

很多手机软件在安装后首次运行都会进入到引导页面&#xff0c;再次运行时会进入到主页面。 多了不说了&#xff0c;先看效果图&#xff1a; 代码如下&#xff1a; main.xml <?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:an…

C++中size_type类型详解

介绍 是和string类类型和vector类类型定义相关的类型&#xff0c;用以保存任意string对象或vector对象的长度&#xff0c;标准库类型将size_type定义为unsigned类型string抽象意义是字符串&#xff0c; size&#xff08;&#xff09;的抽象意义是字符串的尺寸&#xff0c; str…

单一职责原则 实现贪吃蛇代码的封装

单一职责原则(SRP),就一个类而言&#xff0c;应该仅有一个引起它 变化的原因。 一个c语言的贪吃蛇代码 如何使用单一职责原则封装成c面向对象呢 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<string.h> #include<stdlib.h> #include <wi…

android ProgressBar实现扫描SD卡文件 + SimpleAdapter绑定ListView

代码 activity_main.xml <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.android.com/tools"android:layout_width"match_parent"android:layout_height"match_parent"to…

C++标准库函数begin和end函数

主要的目的 为了让指针更加简单、安全&#xff0c;引入了begin和end函数&#xff0c;这两个函数和容器中两个同名的成员函数类似。但是由于数组毕竟不是类类型&#xff0c;因此这两个函数不是成员函数。正确的使用形式就是将数组作为他们的参数int ia[] {0,1,2,3,4,5,6,7,8,9…

dex分包之--------multidex包的配置使用

目录&#xff1a;一、前言二、产生原因三、MultiDex的简要原理四、MultiDex的使用 一、前言 首先说一下我遇到的情况&#xff0c;最近接手了一个项目是在已有的项目里进行更新添加一些功能&#xff0c;然后该项目导了N多的包&#xff0c;在我使用Android Studio的run”App”直…

C++ primer第六章函数的学习

介绍 首先介绍函数的定义和声明&#xff0c;包括如何传入参数以及函数如何返回结果。C语言允许使用重载函数&#xff0c;即几个不同的函数可以使用向同一个名字。所以接下来介绍重载函数的方法&#xff0c;以及编译器选择如何从函数的若干重载的形式中选取一个与调用模板相互匹…

C语言指针作为函数参数 以及智能指针作为函数参数

总所周知指针作为函数参数传递的时候 传递的是指针的拷贝&#xff08;指针也是变量&#xff09; 这里提供四种指针的传递方法 改到实际的指针。 #include <stdio.h> #include <memory> #include <iostream> using namespace std; void test1(char **string)…

Android Studio打包和引用aar

一、简介 Android 库在结构上与 Android 应用模块相同。它可以提供构建应用所需的一切内容&#xff0c;包括源代码、资源文件和 Android 清单。不过&#xff0c;Android 库将编译到您可以用作 Android 应用模块依赖项的 Android 归档 (AAR) 文件&#xff0c;而不是在设备上运行…

C++ primer第六章6.4函数的学习 之函数的重载

6.4 函数的重载 函数的名字相同但是形参的列表不同&#xff0c;将其称之为重载函数 void print(const char *cp); void print(const int *beg,const int * end); void print(const int ia[],size_t size); 形如上面所展现的这样&#xff0c;当调用这些函数的时候&#xff0c;…

C++有限状态机的实现

//待完善 有限状态机是一个很常用的技术&#xff0c;在流程控制和游戏AI中都比较实用&#xff0c;因为状态机编程简单又很符合直觉。与有限状态机类似的是设计模式中的状态模式。本文是参考《Programming Game AI by Example》 一、 记得最开始工作时候也接触过有限状态机&…