STL vector基本用法

news2024/11/24 10:54:27

目录

  • vector介绍
  • vector的使用
    • vector的定义
    • vector接口函数
      • 构造函数和赋值重载
      • 迭代器
      • 元素访问
      • vector容量相关函数
      • vector增加 删除 修改操作
      • 关系操作符

vector介绍

  • vector是可变大小数组的序列容器。
  • 像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自动处理。

思考一个问题:可以用vector<char>替代string吗?
答案是不能:原因有二
1.结构不同,string要求最后又'\0',为了更好的兼容C,string的函数都会对'\0'处理,但是vector的函数不会
2.string中又许多独特的接口函数

vector的使用

vector的定义

template < class T, class Alloc = allocator<T> > class vector;

vector的定义是模板的形式,因为会有不同类型的模板
有2个模板参数,
class T指的是元素的类型,在类中有别名为value_type,因为类中进行了typedef T value_type
class Alloc = allocator<T>是空间配置器(内存池),有缺省值,通常我们不用传这个参数


vector接口函数

构造函数和赋值重载

构造函数说明
vector()无参构造
vector(size_type n,const value_type& val = value_type())构造并初始化n个val
vector (const vector& x);拷贝构造
vector (InputIterator first, InputIterator last);使用迭代器进行初始化构造

vector()无参构造我们不必多说

vector(size_type n,const value_type& val = value_type())value_type就是T,是typedef出来的
val的缺省值value_type()其实就是容器中元素类型的构造函数,以无参构造出的值为缺省值

这里T的类型假如是自定义类型Date,那么缺省值是Date(),就是默认构造函数,我们都可以理解
如果T类型 为内置类型,比如int,那么int()是什么意思呢?
这里其实是C++中的优化,int()其实会就是0

void test1()
{
	vector<int> v(5, 2); //22222
}

vector (const vector& x);拷贝构造,也没什么多说的

vector (InputIterator first, InputIterator last);,这里的迭代器可以是自己容器的,也可以是其他容器的,甚至可以是数组的

void test1()
{
	vector<int> v1(5, 98); 

	vector<int> v2(v1.begin(), v1.end());//相同类型的迭代器
	for (auto e : v2)
	{
		cout << e << " ";  
		e++;
	}//输出98 98 98 98 98
	cout << endl;

	vector<char> v3(v1.begin(), v1.end());//相同容器不同元素类型的迭代器
	for (auto e : v3)
	{
		cout << e << " ";
		e++;
	}//输出b b b b b
	cout << endl;

	int nums[] = { 1,2,3,4,5,6 };
	vector<int> v4(nums, nums + sizeof(nums) / sizeof(int));//数组
	for (auto e : v4)
	{
		cout << e << " ";
		e++;
	}//输出1 2 3 4 5 6 
	cout << endl;
}

赋值重载

vector& operator= (const vector& x);
void test2()
{
	vector<char> v1(10, 'x');
	vector<char> v2;
	v1 = v2;//xxxxxxxxxx
}

迭代器

这里的迭代器也是指针
用法和前面的string的迭代器类似

void test2()
{
	int nums[] = { 1,2,3,4,5,6,7,8,9,10 };
	vector<int> v(nums, nums + 10);
	vector<int>::iterator it = v.begin();
	while (it != v.end())
	{
		cout << *it << " ";
		it++;
	}//1 2 3 4 5 6 7 8 9 10
	cout << endl;

	vector<int>::reverse_iterator rit = v.rbegin();
	while (rit != v.rend())
	{
		cout << *rit << " ";
		rit++;
	}//10 9 8 7 6 5 4 3 2 1
	cout << endl;

	const vector<int> cv(nums, nums + 10);
	vector<int>::const_iterator cit = cv.cbegin();
	while (cit != cv.cend())
	{
		cout << *cit << " ";
		cit++;
	}//1 2 3 4 5 6 7 8 9 10
	cout << endl;

	vector<int>::const_reverse_iterator crit = cv.crbegin();
	while (crit != cv.crend())
	{
		cout << *crit << " ";
		crit++;
	}//10 9 8 7 6 5 4 3 2 1
	cout << endl;
}


元素访问

operator[]
vector中也重载了[]

reference operator[] (size_type n);//读写
const_reference operator[] (size_type n) const;//只读

用法和string::operator[]一样
还是会assert断言判断是否下标越界

at

 reference at (size_type n);
const_reference at (size_type n) const;

用法和at相似
如果下标越界,就会抛出异常


front和back

front返回第一个元素
back返回最后一个元素
这两个函数不常用,完全可以用[]替代:   v.front()–>v[0]   v.back()–>v[v.size()-1]



data

value_type* data() noexcept;
const value_type* data() const noexcept;

返回指向内存数组的直接指针


vector容量相关函数

函数说明
size获取数据个数
max_size获取最大数据个数
capacity获取容量大小
empty判空
shrink_to_fit缩减至适合容量
resize调整size
reserve调整capacity

这几个函数在string也都有,用法都相似

这里只有reserve 函数和string中略有区别
如果 n 大于当前的矢量容量,函数会使容器重新分配存储空间,将容量增加到 n(或更大)。
在所有其他情况下,函数调用不会导致重新分配,向量容量也不会受到影响。

这里与string中的reserve不同,如果n<capacity(),string中的reserve可能会减少,取决于编译器
但是vector中的n<capacity()也不会减少capacity

capacity的代码在vs和g++下分别运行会发现,vs下capacity是按1.5倍增长的,g++是按2倍增长的。
但是也不要固化的认为,具体增长多少是根据具体的需求定义的。vs是PJ版本STL,g++是SGI版本STL。

reserve只负责开辟空间,如果确定知道需要用多少空间,reserve可以缓解vector增容的代价缺陷问题。

resize会影响size()和capacity()

下面有一个情况,我们先用无参构造出一个vector<int>类型对象,再用reserve函数开出空间,如果我们用[]去赋值会发生什么呢?

void test3()
{
	vector<int> v;
	v.reserve(20);
	v[0] = 1;
	v[1] = 2;
}

答案是,程序会报错
在这里插入图片描述
原因是,虽然用reserve(20)开辟了20个空间,但是此时size()为0
然后我们再通过[]去赋值,operator[]函数内部有assert断言,这里就会报错

所以像上面的那个情况,需要使用resize函数,resize既可以改变size也可以改变capacity

void test3()
{
	vector<int> v;
	v.resize(20);
	v[0] = 1;
	v[1] = 2;
}

vector增加 删除 修改操作


push_back

void push_back (const value_type& val);

作用:尾插一个元素

pop_back

void pop_back();

作用:删除最后一个元素


insert

iterator insert (iterator position, const value_type& val);

void insert (iterator position, size_type n, const value_type& val);

template <class InputIterator>
    void insert (iterator position, InputIterator first, InputIterator last);

前面string类型的insert函数,都是在size_t类型的pos位置插入
而vector中的insert都是在迭代器position位置处插入

  • iterator insert (iterator position, const value_type& val),在position迭代器位置处插入val
  • void insert (iterator position, size_type n, const value_type& val),在position迭代器位置处插入nval
  • template <class InputIterator> void insert (iterator position, InputIterator first, InputIterator last);在迭代器position位置处插入[frist,last]迭代器区间中的内容
void test4()
{
	vector<int> v;
	v.push_back(0);
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	v.push_back(5);
	v.push_back(6);
	v.push_back(7);

	v.insert(v.begin() + 3,100);//0 1 2 (100) 3 4 5 6 7
	v.insert(v.begin(), 2, 10);//(10 10) 0 1 2 100 3 4 5 6 7

	int num[] = { 12,13,14,15 };
	v.insert(v.begin() + 1, num, num + 4);//10 (12 13 14 15) 10 0 1 2 100 3 4 5 6 7

	for (auto e : v)
	{
		cout << e<<" ";
		e++;

	}
}


erase

iterator erase (iterator position);
iterator erase (iterator first, iterator last);

iterator erase (iterator position)删除迭代器position位置处元素
iterator erase (iterator first, iterator last)删除[first,last]迭代器区间中的内容

void test5()
{
	vector<int> v;
	v.push_back(0);
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	v.push_back(5);
	v.push_back(6);
	v.push_back(7);

	//0 1 2 3 4 5 6 7
	v.erase(v.begin()); //1 2 3 4 5 6 7

	v.erase(v.begin() + 2, v.end());//1 2
}

上面的eraseinsert会涉及到迭代器失效,迭代器失效我们之后会进行了解



swap

void swap (vector& x);

交换两个vector的数据空间



clear

void clear();

清除内容
使size()值变为0,不改变capacity()的值


关系操作符

vector中也支持各种关系操作符的重载,这些函数为非成员函数重载
在这里插入图片描述

关系操作符对于string很实用,但是关系操作符对于vector用处不大

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

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

相关文章

Dockers搭建个人网盘、私有仓库,Dockerfile制作Nginx、Lamp镜像

目录 1、使用mysql:5.6和 owncloud 镜像&#xff0c;构建一个个人网盘。 &#xff08;1&#xff09;下载mysql:5.6和owncloud镜像 &#xff08;2&#xff09;创建启动mysql:5.6和owncloud容器 &#xff08;3&#xff09;在浏览器中输入网盘服务器的IP地址&#xff0c;进行账…

stm32单片机/51单片机蜂鸣器不响(proteus模拟)

蜂鸣器不发生原因就1个&#xff1a;电压不够 所以需要提高蜂鸣器2端的电压&#xff1a;可以采用的方法有&#xff1a; 1提高蜂鸣器电阻&#xff0c;这样根据分压原理&#xff0c;可以提升蜂鸣器2段电压 2更改蜂鸣器的工作电压为更小的值&#xff0c;这个可以通过在proteus内…

虚拟机中docker承载的微服务注册到nacos无法访问问题

今天将一个项目中的部分子系统部署&#xff0c;部署到虚拟机的docker里运行&#xff0c;结果外部无法访问。查看nacos&#xff0c;显示服务已经成功注册。 后来发现&#xff0c;该服务的IP地址外部无法访问&#xff1a; 估计172.17.0.0是docker自身的网段&#xff0c;在上面跑…

【MyBatis面试题(20道)】

文章目录 MyBatis 面试题&#xff08;20道&#xff09;基础1.说说什么是MyBatis&#xff1f;2.Hibernate和MyBatis有什么区别&#xff1f;3.MyBatis使用过程&#xff1f;生命周期&#xff1f;4.在mapper中如何传递多个参数&#xff1f;5.实体类属性名和表中字段名不一样&#x…

BDA初级分析——SQL多表连接应用

一、用SQL拼接数据 三个初始数据 问题1&#xff1a;在所有的数据里&#xff0c;销售额最高的产品品类名是什么&#xff1f; 问题2&#xff1a;是否有什么产品是在所观测的时间里没有被购买过的&#xff1f; 拼接数据&#xff1a;JOIN join&#xff0c;加入 作用&#xff1…

crontab下定时任务批量注释和批量放开

背景&#xff1a;实际项目中我们在Linux系统中用crontab配置了上百个定时任务&#xff0c;有的时候做配置修改等需要同时注释掉这些任务&#xff0c;让它们都不在执行&#xff0c;找了一会儿终于发现了解决办法&#xff0c;&#x1f604; 模拟项目中的任务如下 我就随机写了两…

最快的JS甘特图:Bryntum Gantt 5.5.1 Crack

最快的JS甘特图 Bryntum Gantt 是一个超快速且完全可定制的甘特图套件&#xff0c;适用于您的 React / Angular / Vue / JS 应用程序。 快如闪电 甘特图是用纯 JavaScript / ES6 构建的&#xff0c;并使用非常快速的渲染引擎。这意味着您可以加载大型数据集&#xff0c;并且仍然…

MNN学习笔记(八):使用MNN推理Mediapipe模型

1.项目说明 最近需要用到一些mediapipe中的模型功能&#xff0c;于是尝试对mediapipe中的一些模型进行转换&#xff0c;并使用MNN进行推理&#xff1b;主要模型包括&#xff1a;图像分类、人脸检测及人脸关键点mesh、手掌检测及手势关键点、人体检测及人体关键点、图像嵌入特征…

嵌入式:ARM Day6

作业:完成cortex-A7核UART总线实验 目的&#xff1a;1.输入a,显示b&#xff0c;将输入的字符的ASCII码下一位字符输出 2.原样输出输入的字符串 源码&#xff1a; uart4.h #ifndef __UART4_H__ #define __UART4_H__#include "stm32mp1xx_rcc.h" #incl…

个人论坛项目测试报告

目录 0.项目概述及部分测试用例展示 以下是部分测试用例&#xff1a; 进行一般的性能测试性能测试 1.摘要及版本修订记录 2.功能介绍 3.测试范围 3.1.功能性 3.2.可靠性 3.3.易用性 4.测试资源 4.1.人员介绍 4.2.测试环境 4.2.测试工具 5.测试策略 5.2.功能测试…

Vivado使用入门之三:I/O约束

一、导图概览 二、I/O约束 2.1 I/O约束的内容 I/O约束主要是对port的位置和电气特性进行设置&#xff0c;进入菜单栏Window的IO Ports&#xff0c;可以查看可约束的相关内容。 一些port的常用特性解释如下 Name: port的名称 Direction:port的输入输出类型&#xff0c;有三种…

后端开发12.商品模块

概述 简介 商品模块这个设计的非常复杂 效果图 数据库

【LeetCode-中等题】15. 三数之和

题目 题解一&#xff1a;双指针法 图解参考链接&#xff1a;画解算法&#xff1a;15. 三数之和 详解参考代码随想录讲的非常好 梦破碎的地方&#xff01;| LeetCode&#xff1a;15.三数之和 代码&#xff1a; class Solution {public List<List<Integer>> thre…

第 7 章 排序算法(5)(希尔排序)

7.8希尔排序 7.8.1简单插入排序存在的问题 我们看简单的插入排序可能存在的问题. 数组 arr {2,3,4,5,6,1} 这时需要插入的数 1(最小), 这样的过程是&#xff1a; {2,3,4,5,6,6} {2,3,4,5,5,6} {2,3,4,4,5,6} {2,3,3,4,5,6} {2,2,3,4,5,6} {1,2,3,4,5,6} 结论: 当需要插入的数…

Influxdb数据库(centos7)

Influxdb数据库 1、简介与使用场景 简介 InfluxDB是一个由InfluxData开发的开源时序型数据库&#xff0c;专注于海量时序数据的高性能读、高性能写、高效存储与实时分析等&#xff0c;在DB-Engines Ranking时序型数据库排行榜上排名第一&#xff1a; InfluxDB广泛应用于DevOps…

odoo 设备增加二维码 python生成二维码的一个有意思的问题

odoo 设备增加二维码 python生成二维码的一个有意思的问题 在odoo设备集成中根据客户要求&#xff0c;增加了一个二维码&#xff0c;想包含一些信息&#xff0c;用python的二维码库qrcode&#xff0c;qrcode是二维码生成的Python开源库。 代码如下: ewmny 设备&#xff1a; …

开源远程控制硬件 BliKVM v4测试 1000公里外远程重装系统

测试准备 测试时间&#xff1a;20230818 测试硬件&#xff1a;BliKVM v4 文档 BliKVM v4是一款生产就绪、即插即用的 KVM-over-IP 设备&#xff0c;为专业用户提供了远程服务器或工作站管理的便捷解决方案。 它基于Linux并且完全开源。 借助 BliKVM&#xff0c;您可以轻松打…

机器学习算法-随机森林

目录 机器学习算法-随机森林 &#xff08;1&#xff09;构建单棵决策树。 决策树的构建过程 决策树的构建一般包含三个部分&#xff1a;特征选择、树的生成、剪枝。 机器学习算法-随机森林 机器学习算法-随机森林 随机森林是一种监督式学习算法&#xff0c;适用于分类和回…

9万字企业数字化技术中台、数据中台、工业互联网建设方案WORD

导读&#xff1a;原文《9万字企业数字化技术中台、数据中台、工业互联网建设方案WORD》&#xff08;获取来源见文尾&#xff09;&#xff0c;本文精选其中精华及架构部分&#xff0c;逻辑清晰、内容完整&#xff0c;为快速形成售前方案提供参考。 目录 1 概述 1.1. 数字化企…

SPI ServiceLoader.load()无法加载实现类

[TOC](SPI ServiceLoader.load()无法加载实现类) 问题描述 项目是maven结构&#xff0c;其中的resources里结构如下&#xff1a; 解决方案 改为如下结构&#xff1a; 原因分析 问题出现的原因是&#xff1a;创建Directory时用点号隔开了 META-INFO.services ,结果META-…