模版and初识vector
一、引言
在C语言中,不论是数组,还是结构体定义的数组,功能都比较欠缺,不是单纯的添加几个变量就能够解决的。缺少增删查改的功能,为了解决这个问题,C++决定填上C语言这个坑,但是填过坑的人都知道,想填一个坑必定需要在其他地方挖一个坑。这些坑呢,零零碎碎,等遇到我们再一一揭晓。C++的祖师爷本贾尼博士创造了vector这一容器,既然vector是容器,那它必然可以包含各种各样的数据。很多东西都具有相似性,容器本身就是要将相似的物品归位一类。这里需要用到一个模板的工具。

二、 vector的大概介绍(相当于数组,依照先后顺序排列)
vector是STL的六大组件之一,头文件:<vector>,与之前string不同的是vector的增删查改使用迭代器特别频繁。主要是基于迭代器的灵活性、适配性、安全。vector还有个别名是顺序表(sequence list),至于它为什么叫vector(向量),就不得而知了。既然有顺序表这个别名,那vector肯定与顺序表有着千丝万缕的联系,实际上vector的底层就是顺序表。在使用过程中记得按需实例化(模版的内容)。
三、模版(template)
模版本身可以理解为一个模具,分为函数模版和类模版,只要符合的内置类型(计算机规定的类型)或自定义类型都可以套用模版,编译器会根据函数模版或是类模版生成一个对应的函数或类(有多少种不同的类型,就会生成多少个),模版就像方程组中的未知量,直到编译时模板才会被编译器替换为准确类型,就像我们求方程时求x的大小一样,算一遍才会得出x的值。编译器也会根据接受到的变量类型或根据使用者的按需实例化将模版类型替换。遇到不同类型使用模版,编译器也会生成不同类型的函数和类,这样我们就可以将不同的类型复用在同一段代码上了,大大增加了代码的复用性,节省了时间。
//class和typename都可以用来定义模版类型
template<class + 自定义的类型名,typename + 自定义的类型名>//vector的使用
std::vector<int> /*按需实例化,编译器自动将模版类型替换该类型*/ v(初始化值);
//没有初始化值时,不需要加(),不然编译器分不清这是函数,还是类对象。//最好的初始化是使用{}(花括号),这样编译器默认只是一个变量
//当然{}中可以像数组那样写出多个值。
std::vector<int> v{ };
std::cout << v[0] << std::endl;
当然模版类型也可以给缺省参数。也就是给定一个确定的类型。如果没有类型的传入,编译器根据缺省参数生成一个确定的类型。
//class和typename在tmeplate的声明中是一样的,混着用都没关系
template<class T,class T1 = int>
//
template<typename T,typename T2 = double>
3.1函数模版
函数模版即在函数的形参的类型,与类模版不同的是他可以不需要按需实例化,因为函数只有在执行可执行文件时才会建立栈帧。而类模版则不同,在没有缺省参数时,需要按需实例化。
template<class T>
void swap(T& tmp1,T& tmp2)
{T tmp = tmp1;tmp1 = tmp;tmp2 = tmp;
}int main()
{int a = 11 , b = 13;swap<int>(a , b);return 0;
}
3.2类模版
类的声明就和内置类型一样需要开好空间,如果连类型都不确定,还怎么计算内存开空间呢?哪怕是一个空类也有一字节的空间。因为编译器还会根据类的地址来查找类中的函数。这就需要类的声明的做好按需实例化。
四、 vector的详细介绍
4.1 vector中的迭代器
vector类中虽然,的很多函数都会使用迭代器。即是因为迭代器方便实用,又是因为要与其他的STL组件接轨。迭代器与指针相似,但有些迭代器可能不是指针,可能是用类封装,这个以后有机会再讲。
在vector中的迭代器,分为正向迭代器和反向迭代器。正向迭代器(iterator)、反向迭代器(reverse_iterator)。顾名思义正向迭代器是由顺序表起始位置(begin())到最后一个位置的的下一个位置(end()),反向迭代器就是从最后一个位置(rbegin())到顺序表的起始位置的下一个位置(rend()),可以通过解引用操作符访问,自然也可以通过解引用操作符修改值。(除const迭代器以外)
#include<iostream>
//vector的头文件
//为了与C语言作区分,不加.h后缀
#include<vector>int main()
{std::vector<int> v;//尾插一个数据v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);v.push_back(5);std::vector<int>::reverse_iterator it = v.rbegin();while (it != v.rend()){std::cout << *it << " ";++it;}//不可访问,end()、rend(()函数都是从//std::cout << *(v.end()) << std::endl;//不论是reverse_iterator还是iterator//都是从正向或是反向的位置相加、减,前置后置加加、减减。std::vector<int>::reverse_iterator it = v.rbegin();while (it != v.rend()){std::cout << *it << " ";++it;}//std::cout << *(v.end()) << std::endl;return 0;
}
const迭代器只能访问,不能修改值。const迭代器直接往迭代器前加const_,直接const在迭代器前加const则会报错,不管迭代器的底层都是否为指针,它都是一个对访问方式的封装,并不是一个单纯的类型。
//初始化,当然也可以不加小括号,直接就大括号
std::vector<int> v({1,2,3,4,5,6});std::vector<int>::const_iterator it = v.begin();
while (it != v.end())
{std::cout << *it << " ";++it;
}
4.2 vector中的尾插函数
push_back()和string中的push_back()效果相差无几,都是往最后的位置插入类型元素。至于是什么类型就看声明时按需实例化的是什么类型。当然它也可以用来存储char类型。也可以按需实例化成string。
//这里用int类型做个示范
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5);//这里用string做一个示范
vector<string> vs;
vs.push_back("ABC");
vs.push_back("ABC");
vs.push_back("ABC");
vs.push_back("ABC");
4.3vector中的insert和erase函数
vector中的在指定位置插入和在删除指定位置。这里需要注意的是此insert、erase非string中的insert、erase。需要用迭代器,这里用迭代器自然是为了和STL的其他容器保持一致。但是至少也要重载一个下标插入、删除,所以C++某些设计还是不完善。
C++11的官网:cplusplus.com - The C++ Resources Network
C++11vector中的insert:vector::insert - C++ Reference (cplusplus.com)
C++11vector中的erase:vector::erase - C++ Reference (cplusplus.com)
std::vector<int> v{ 1,3,4 };
v.insert(v.begin() + 1, 2);
//注意迭代器失效的问题
for (auto e : v)
{std::cout << e << " " ;
}
std::cout << std::endl;
//注意end()、rbegin()都是顺序表之外的位置
//end()是末尾位置的下一个位置。
//rbegin()是开头的上一个位置。
v.erase(v.end() - 1);
for (auto e : v)
{std::cout << e << " ";
}
用迭代器访问时,注意insert()后迭代器位置就已经失效了,需要更新一下,这里原因是扩容导致的。因为内存上的堆区也并不是所有位置都可以访问的,也有些是无法访问的,我们要保证顺序表的连续性,只能另寻他处再复制拷贝下来。
//迭代器更新,insert会自动返回插入位置的迭代器
std::cout << std::endl;
std::vector<int> v1{ 1,3,4 };
std::vector<int>::iterator it = v1.begin() + 1;
it = v1.insert(it, 2);
while (it != v1.end())
{std::cout << *it << " ";++it;
}//错误示例: std::cout << std::endl;std::vector<int> v1{ 1,3,4 };std::vector<int>::iterator it = v1.begin() + 1;v1.insert(it, 2);while (it != v1.end()){std::cout << *it << " ";++it;}
4.4vector的下标访问
和string一样,vector也可以用下标来访问。这里size()和capacity()就不讲了,string中讲过了。
std::vector<int> v{ 1,3,4 };
for(int i = 0;i < v.size();++i)
{std::cout << v[i] << " ";
}
4.5vector拷贝构造和operator =
这是我们比较容易忽略的。顺嘴提醒一下。
std::vector<int> v{ 1 , 2 , 3 , 4 }
std::vector<int> v1 = v;
相关文章:
模版and初识vector
一、引言 在C语言中,不论是数组,还是结构体定义的数组,功能都比较欠缺,不是单纯的添加几个变量就能够解决的。缺少增删查改的功能,为了解决这个问题,C决定填上C语言这个坑,但是填过坑的人都知道…...
网站开发基础:HTML、CSS
前端开发主要使用的技术如 HTML、CSS 和 JavaScript 等。 简单制作一个网页 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>柒毓同学网站的首页</title><style>.c1{border: solid 1px g…...
IP协议讲解
IP协议 IP协议的本质:提供一种能力,将数据跨网络从A主机传输到B主机 4位版本号(version): 指定IP协议的版本, 对于IPv4来说, 就是4. 4位头部长度(header length): IP头部的长度是多少个32bit, 也就是 length * 4 的字节数. 4bit表示最大 的数字是15, 因…...
SpringMVC4-SpringMVC获取请求参数
目录 通过ServletAPI获取(不常用) 通过控制器方法的形参获取请求参数 RequestParam RequestHeader CookieValue 通过POJO获取请求参数 解决获取请求参数的乱码问题 test_param.html: <!DOCTYPE html> <html lang"en&qu…...
【C++】C++基础
目录 一. C关键字(C98) 二、C的第一个程序 三、命名空间 3.1.namespace的价值 3.2.namespace的定义 3.2.命名空间使用 总结:在项目当中第一、第二种方法搭配使用,第三种冲突风险非常大,仅适合练习使用。 四、C输入&输出 五、缺省…...
自动化运维工具 Ansible
Ansible 基础 Ansible 介绍 Ansible 是一个自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、 func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。 Ansible 的…...
深度学习:GAN图像生成
GAN的诞生背景 诞生: 2014年由Ian Goodfellow提出 创新性: 无监督学习:GAN 提供了一种新的方法来进行无监督学习,即不需要对训练数据进行标注就可以学习到数据的潜在分布。对抗训练:通过引入对抗机制,G…...
django基于python的房价分析可视化系统的设计与开发 h1y0i
目录 项目介绍技术栈具体实现截图Scrapy爬虫框架关键技术和使用的工具环境等的说明解决的思路开发流程爬虫核心代码展示系统设计论文书写大纲详细视频演示源码获取 项目介绍 大数据分析是现下比较热门的词汇,通过分析之后可以得到更多深入且有价值的信息。现实的科…...
Labview helper
IMAQ Advanced Setup Learn Geometric Pattern 2 VI 参数说明Curve Extraction Mode (0)指定VI如何识别图像中的曲线。如果您希望VI不对图像中对象的均匀性或图像背景做出任何假设,请将此选项设置为正常。如果您希望VI假定图像中的对象或图像背景由均匀的像素值组成…...
《安富莱嵌入式周报》第343期:雷电USB4开源示波器正式发布,卓越的模拟前端低噪便携示波器,自带100W电源的便携智能烙铁,NASA航空航天锂电池设计
周报汇总地址:嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 更新一期视频教程 【授人以渔】CMSIS-RTOS V2封装层专题视频,一期视频将常用配置和用法梳理清楚࿰…...
如何用JavaScript编写一个简单的计数器
在网页开发中,计数器是一种常见的功能,它可以帮助我们记录点击次数、显示时间等。下面我将介绍如何在HTML页面中使用JavaScript实现一个基本的计数器。如图: 1、 创建HTML结构 首先,我们需要创建一个基础的HTML结构来容纳我们的计…...
uniapp中实现评分组件,多用于购买商品后,对商品进行评价等场景
前言 uni-rate是uniapp框架中提供的一个评分组件。它可以用于用户评价、打分等场景。uni-rate组件可以根据设定的星星总数,展示用户评分的效果,用户可以通过点击星星或滑动星星的方式进行评分。同时,uni-rate组件也支持自定义星星图标、星星…...
算法笔记(三)——前缀和算法
算法笔记(三)——前缀和算法 文章目录 算法笔记(三)——前缀和算法一维前缀和二维前缀和寻找数组的中心下标除自身以外数组的乘积和为 K 的子数组和可被 K 整除的子数组连续数组矩阵区域和 前缀和算法是一种用空间换时间的算法&am…...
Nginx技术深度解析与实战应用
Nginx技术深度解析与实战应用 Nginx是一款轻量级、高性能的Web服务器、反向代理服务器及电子邮件(IMAP/POP3)代理服务器,由俄罗斯的程序设计师Igor Sysoev开发。Nginx以其内存占用少、启动迅速、高并发能力强等特性,在互联网项目…...
Maven Surefire Plugin
Maven Surefire Plugin 最新版本新特性详解 Maven Surefire Plugin 是用于运行单元测试和集成测试的重要工具,支持 JUnit、TestNG 等测试框架。插件的新版本引入了许多新特性和配置选项,这些功能提升了测试执行的性能、灵活性和并发能力。在本节中&…...
八、跳跃、闪避
一、人物跳跃功能 1、动画 设置一个bool值 条件设置为true 2、逻辑 实现跳跃,一定有IsGround;判断是否为地面,进行跳跃功能 写一个跳跃和一个条约结束方法 跳跃设置为false,结束设置为true 3、代码 public void Jump() {if…...
使用辅助分类器 GAN 进行条件图像合成
Conditional Image Synthesis with Auxiliary Classifier GANs Conditional Image Synthesis with Auxiliary Classifier GANs(简称AC-GANs)是一种用于改善生成对抗网络(GANs)进行图像合成的方法。在AC-GANs中,判别器…...
C#中的static关键字:静态成员与单例模式的实现
在C#中,static 关键字是一个非常重要的概念,它用于声明静态成员,这些成员属于类本身,而不是类的任何特定实例。使用 static 关键字可以定义静态类、静态字段、静态属性、静态方法等。此外,理解静态成员也对于实现如单例…...
【优选算法】(第八篇)
目录 串联所有单词的⼦串(hard) 题目解析 讲解算法原理 编写代码 最⼩覆盖⼦串(hard) 题目解析 讲解算法原理 编写代码 串联所有单词的⼦串(hard) 题目解析 1.题目链接:. - 力扣&#…...
告别PPT熬夜!Kimi+AIPPT一键生成PPT,效率upup!
Kimi AiPPT 一键生成PPT 还在为做PPT熬夜加班吗?还在为PPT排版抓狂吗?现在,有一个好消息要告诉所有“打工人”!Kimi和AIPPT强强联手,推出了一键生成PPT功能,让你告别PPT制作的痛苦! 以前做…...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...
深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...
Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...
AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...
