C++ STL vector基本原理和用法

【C++】STL和vector容器 质变算法,是指运算过程中会更改区间内的元素的内容,例如拷贝、替换、删除等;长久以来,软件届一直希望建立一种可重复利用的东西,C++的面向对象和泛型编程思想,目的就是复用性的提升,大多情况下,数据结构和算法都未能有一套标准,导致被迫从事大量重复工作,为了建立数据结构和算法的一套标准,诞生了STL。容器和算法之间的粘合剂,提供一种方法,使之能够依序寻访某个容器所含的各个元素,而又无需暴露该容器的内部表示方式,每个容器都有自己专属的迭代器,迭代器使用非常类似于指针,初学阶段可以理解为指针。 阅读详情

基本原理

以下是关于 std::vector 的基本原理讲解:

1. 数据存储结构

std::vector 在内部通常是使用一段连续的内存空间来存储元素,这一点和普通的C风格数组类似。这种连续存储的方式使得它能够实现快速的随机访问,因为可以通过简单的指针运算(基于元素类型的大小)来定位到任意位置的元素,例如,对于一个存储 int 类型元素的 vector,如果知道首地址,要访问索引为 n 的元素,在内存中就是首地址加上 n * sizeof(int) 的偏移量。

2. 内存管理机制

  • 初始内存分配:
    当创建一个 vector 时,它并不会立即分配很大的内存空间,通常会分配一个较小的初始容量(不同的标准库实现可能初始容量不同,有些可能是0,有些可能是一个较小的固定值,比如4或者8等)。例如,定义 std::vector<int> myVec; 时,它可能刚开始并没有分配实际可存储元素的内存块,只是进行了一些必要的内部状态初始化。

  • 扩容机制:
    随着不断向 vector 中添加元素(通过 push_back 等操作),当元素个数达到当前容量上限时,vector 就需要进行扩容操作以容纳更多元素。扩容过程一般涉及以下几个步骤:

    • 新内存分配:它会按照一定的策略分配一块更大的连续内存空间,常见的扩容倍数是1.5倍或者2倍左右(具体倍数由不同的STL实现决定)。例如,当前 vector 的容量是4,已经存储了4个元素,当再调用 push_back 添加第5个元素时,如果按照2倍扩容策略,就会另外开辟一块能容纳8个元素的新内存空间。
    • 元素复制或移动:接着把原来内存空间中存储的所有元素复制或者移动(如果元素类型支持移动语义,在C++11及以后通常优先采用移动,以提高效率)到新分配的内存空间中。这一步涉及对每个元素的操作,如果元素类型的拷贝构造函数或者移动构造函数开销较大,那么扩容操作的整体开销也会相应增大。
    • 释放旧内存:在成功将元素迁移到新内存空间后,会释放原来的那块内存空间,以避免内存泄漏。
  • 缩容机制(可选):
    有些 vector 的实现提供了手动缩容或者在特定条件下自动缩容的机制,不过不是所有标准库都保证有自动缩容功能。比如,当调用 vector 的 clear 函数清空所有元素后,部分实现可能会自动释放多余的内存空间,将容量减小;也可以通过类似 shrink_to_fit 这样的函数(如果标准库支持)来显式要求 vector 释放多余内存,使其容量尽量接近当前元素个数,不过这个函数只是一个建议性的操作,具体是否能真正缩容以及缩容到何种程度还是依赖具体的实现。

3. 迭代器实现原理

vector 的迭代器本质上是一种类似指针的对象,它重载了一些必要的运算符(如 *(解引用)、++(前置和后置自增)、--(前置和后置自减)、!=(不等比较)等),使其能够像指针一样遍历 vector 中的元素。

  • 普通迭代器(begin、end 等返回的迭代器):
    其内部通常就是直接持有指向 vector 中元素所在内存位置的指针。例如,begin 函数返回的迭代器指向 vector 的第一个元素所在内存地址,end 函数返回的迭代器指向最后一个元素后面的内存位置(形成左闭右开区间用于遍历等操作符合STL的通用约定)。当对迭代器进行自增操作时,就是按照元素类型的大小在内存中向后移动指针到下一个元素的位置,自减操作则相反,向前移动指针。

  • 反向迭代器(rbegin、rend 等返回的迭代器):
    反向迭代器的实现相对复杂一些,它一般会对普通迭代器进行适配,内部通过一些机制来实现从后往前遍历的效果。实际上,它可以看作是对普通迭代器的一种“包装”,在自增、自减等操作的语义上进行了反转,使其能够从 vector 的末尾元素开始,向开头方向依次访问元素。

4. 元素访问原理

  • 下标访问(operator[]):
    这个操作符重载的实现就是基于 vector 内部元素连续存储的特性,通过简单的指针算术运算来实现快速访问。它接收一个索引值作为参数,在内部会将这个索引值与元素类型的大小相乘(例如对于 int 类型就是乘以 sizeof(int)),然后加上首元素的地址(也就是 vector 内部管理的那块连续内存空间的起始地址),最后返回这个计算得到的内存地址对应的元素的引用,不过它不会进行边界检查,所以如果使用不当,访问越界就会导致未定义行为。

  • at 函数访问:
    at 函数和 operator[] 类似也是用于访问元素,但它内部会首先进行边界检查,判断传入的索引值是否在合法的范围(即大于等于0且小于 vector 的大小)内,如果越界则会抛出 std::out_of_range 类型的异常,避免了因越界访问带来的潜在错误隐患,相对更加安全。

5. 插入和删除元素原理

  • 末尾插入(push_back):
    在末尾添加元素时,如果当前 vector 还有剩余空间(即元素个数小于容量),那么直接在已有内存空间的末尾位置构造新元素即可,这个过程相对简单高效;但如果已经满容量需要扩容,就会触发上述的扩容流程后再添加元素。

  • 中间或开头插入(insert):
    当要在 vector 的中间或者开头位置插入元素时,需要先将插入位置及之后的所有元素依次向后移动,为新插入的元素腾出空间,然后再在腾出的位置构造新元素。元素移动的过程同样涉及到对每个元素的拷贝或移动操作,所以在元素个数较多的 vector 中进行这类插入操作相对来说效率较低,时间复杂度是线性的 O(n),其中 n 是 vector 的元素个数。

  • 删除元素(pop_back、erase 等):
    pop_back 操作相对简单,只是销毁 vector 末尾的元素(调用其析构函数,如果有的话),然后将元素个数减1即可;而 erase 操作在删除指定位置的元素时,需要将该位置后面的所有元素依次向前移动来填补删除元素后留下的空位,同样涉及到多个元素的拷贝或移动,效率方面也会受 vector 元素个数影响,在中间或开头位置删除元素时间复杂度为 O(n)。

总之,std::vector 通过巧妙的内存管理、迭代器设计以及对各种操作的底层实现,为开发者提供了一个方便、灵活且功能强大的动态数组容器,在了解其基本原理后能更好地掌握它的使用场景、性能特点以及避免一些因不当使用而可能出现的问题。 以下是对C++ STL(标准模板库)中vector的详细讲解:

常见用法

1. 概述

vector是C++ STL中非常常用的一个容器类,它提供了动态大小的数组功能,能够自动管理所存储元素的内存分配与释放,并且支持快速的随机访问。简单来说,你可以把它看作是一种可以根据需要自动扩容和缩容的数组,使用起来比普通的C风格数组更加方便、安全和灵活,广泛应用于各种需要存储和操作一组同类型元素的场景中。

2. 包含头文件

要使用vector容器,需要在代码中包含<vector>头文件,例如:

#include <vector>

3. 定义和初始化

  • 基本定义:
    定义一个vector对象的语法形式通常为 std::vector<元素类型> 变量名;,这里的“元素类型”可以是C++中的各种基本数据类型(如int、double、char等),也可以是自定义的结构体、类等类型。例如,定义一个存储整数的vector:
std::vector<int> myVector;
  • 初始化方式:
    • 默认初始化:像上面那样定义后,vector会被默认初始化为空,即其中不包含任何元素,其大小(通过size()成员函数获取)为0。
    • 指定初始大小和初始值:可以在定义时指定vector的初始大小以及每个元素的初始值,语法为 std::vector<元素类型> 变量名(元素个数, 初始值);。例如,创建一个包含5个初始值都为0的整数的vector:
std::vector<int> anotherVector(5, 0);

此时,anotherVector的大小为5,并且每个元素的值都是0。
- 使用初始化列表初始化:利用花括号{}包裹元素来初始化vector,这种方式在C++11及以后的版本中更加常用和方便。例如:

std::vector<int> initListVector = {1, 2, 3};

这个vector包含了3个元素,分别是1、2和3。
- 从其他vector复制或移动初始化:可以通过已有的vector对象来初始化一个新的vector,实现复制或移动语义(如果适用)。例如:

std::vector<int> sourceVector = {1, 2, 3};
// 复制初始化
std::vector<int> copiedVector(sourceVector);
// 移动初始化(假设C++11及以上,利用std::move函数实现移动语义)
std::vector<int> movedVector(std::move(sourceVector));

复制初始化会创建一个新的vector,其元素与源vector完全相同;而移动初始化则是将源vector的资源(如内存空间等)转移给新的vector,源vector在移动后通常处于一种有效但已转移资源的特殊状态(比如大小变为0等)。

4. 常用成员函数

  • 添加和删除元素相关函数:
    • push_back():用于在vector的末尾添加一个元素。例如:
std::vector<int> numbers;
numbers.push_back(5);  // 在末尾添加整数5
numbers.push_back(10); // 再添加整数10,此时numbers包含两个元素,分别是5和10
- **`pop_back()`**:与`push_back()`相反,它用于删除`vector`末尾的一个元素。例如:
std::vector<int> nums = {1, 2, 3};
nums.pop_back();  // 删除末尾的元素3,此时nums包含元素1和2
- **`insert()`**:可以在指定位置插入一个或多个元素。它有多种重载形式,常见的一种是 `iterator insert(iterator position, const T& value);`,其中`position`是指向插入位置的迭代器(可以通过`begin()`、`end()`等函数获取迭代器来指定位置),`value`是要插入的元素值。例如:
std::vector<int> vec = {1, 3};
auto it = vec.begin() + 1;  // 指向索引为1的位置(也就是元素3所在位置)
vec.insert(it, 2);  // 在索引为1的位置插入元素2,此时vec变为{1, 2, 3}

还可以一次插入多个相同元素,比如 iterator insert(iterator position, size_type n, const T& value); 形式可以在指定位置插入n个相同的value元素。
- erase():用于删除指定位置的一个或多个元素,同样有多种重载形式。例如,删除单个元素可以这样用:iterator erase(iterator position);,删除一段元素区间可以用 iterator erase(iterator first, iterator last);,其中first和last分别是要删除区间的起始和结束迭代器(左闭右开区间)。例如:

std::vector<int> v = {1, 2, 3, 4};
auto it = v.begin() + 1;  // 指向元素2
v.erase(it);  // 删除元素2,此时v变为{1, 3, 4}

删除一段元素示例:

std::vector<int> ve = {1, 2, 3, 4, 5};
auto start = ve.begin() + 1;  // 指向元素2
auto end = ve.begin() + 3;  // 指向元素4后面的位置(左闭右开区间概念)
ve.erase(start, end);  // 删除元素2和3,此时ve变为{1, 4, 5}
  • 访问元素相关函数:
    • at():用于安全地访问vector中的元素,它会进行边界检查,如果访问越界会抛出 std::out_of_range 异常。语法为 reference at(size_type n);,其中n是要访问元素的索引(从0开始计数)。例如:
std::vector<int> values = {10, 20, 30};
try {
    int element = values.at(1);  // 获取索引为1的元素,即20
    std::cout << element << std::endl;
} catch (const std::out_of_range& e) {
    std::cerr << "访问越界: " << e.what() << std::endl;
}
- **`operator[]`(下标运算符)**:也用于访问元素,它与数组的下标访问方式类似,但不会进行边界检查,如果访问越界会导致未定义行为,所以使用时要确保索引在合法范围内。例如:
std::vector<int> data = {5, 10};
int element = data[0];  // 获取第一个元素5,注意这里没有边界检查,需谨慎使用
- **`front()`**:返回`vector`的第一个元素的引用,可以用于获取或修改第一个元素的值。例如:
std::vector<int> firstVector = {1, 2};
int firstElement = firstVector.front();  // 获取第一个元素1
firstVector.front() = 10;  // 将第一个元素修改为10,此时firstVector变为{10, 2}
- **`back()`**:与`front()`相对,返回`vector`的最后一个元素的引用,同样可用于获取或修改最后一个元素的值。例如:
std::vector<int> lastVector = {3, 4};
int lastElement = lastVector.back();  // 获取最后一个元素4
lastVector.back() = 40;  // 将最后一个元素修改为40,此时lastVector变为{3, 40}
  • 获取容器信息相关函数:
    • size():返回vector中当前元素的个数,返回值类型是 std::vector<元素类型>::size_type(通常是无符号整数类型)。例如:
std::vector<int> sizeVector = {1, 2, 3};
std::vector<int>::size_type elementCount = sizeVector.size();  // 获取元素个数,这里elementCount的值为3
- **`capacity()`**:返回`vector`当前已经分配的内存空间能够容纳的元素个数,也就是它的容量。一般来说,随着不断向`vector`中添加元素,当元素个数接近容量时,`vector`会自动进行扩容操作来分配更多的内存空间。例如:
std::vector<int> capVector;
std::cout << "初始容量: " << capVector.capacity() << std::endl;  // 初始容量可能为0或者一个较小的值,取决于实现
capVector.push_back(1);
capVector.push_back(2);
std::cout << "添加元素后的容量: " << capVector.capacity() << std::endl;  // 容量可能已经自动扩容了
- **`empty()`**:判断`vector`是否为空,如果为空(即元素个数为0)则返回`true`,否则返回`false`。例如:
std::vector<int> emptyVector;
if (emptyVector.empty()) {
    std::cout << "该vector为空" << std::endl;
}
std::vector<int> nonEmptyVector = {1};
if (!nonEmptyVector.empty()) {
    std::cout << "该vector不为空" << std::endl;
}
  • 其他常用函数:
    • clear():用于清空vector中的所有元素,将其大小变为0,但不会释放已分配的内存空间(容量可能不会改变,除非后续有添加或删除元素等操作触发了内存重新分配)。例如:
std::vector<int> clearVector = {1, 2, 3};
clearVector.clear();
if (clearVector.empty()) {
    std::cout << "已清空vector,现在为空" << std::endl;
}
- **`resize()`**:可以改变`vector`的大小,如果新大小大于当前大小,会根据元素类型的默认构造函数(对于内置类型可能会进行未定义初始化,对于类类型会调用默认构造函数)或者指定的初始值来填充新增的元素;如果新大小小于当前大小,则会删除多余的元素。例如:
std::vector<int> resizeVector(3, 1);  // 初始化为{1, 1, 1}
resizeVector.resize(5, 0);  // 扩大为{1, 1, 1, 0, 0},新增元素初始化为0
resizeVector.resize(2);  // 缩小为{1, 1},删除后面的元素

5. 迭代器

vector支持迭代器来遍历容器中的元素,迭代器就像是指向容器中元素的指针,可以通过它来依次访问每个元素。常用的迭代器相关操作有:

  • begin()和end():begin()返回指向vector第一个元素的迭代器,end()返回指向vector最后一个元素后面位置的迭代器(形成一个左闭右开的区间概念,用于循环遍历等操作符合STL的通用设计模式)。例如,使用迭代器遍历vector的常见方式如下:
std::vector<int> iterVector = {1, 2, 3};
for (auto it = iterVector.begin(); it!= iterVector.end(); ++it) {
    std::cout << *it << " ";  // 输出每个元素,*it用于解引用迭代器获取元素值
}
// 输出: 1 2 3
  • rbegin()和rend():这两个函数分别返回反向迭代器,用于从后往前遍历vector,rbegin()指向最后一个元素,rend()指向第一个元素前面的位置(同样是左闭右开区间概念)。例如:
std::vector<int> reverseIterVector = {4, 5, 6};
for (auto rit = reverseIterVector.rbegin(); rit!= reverseIterVector.rend(); ++rit) {
    std::cout << *rit << " ";  // 从后往前输出元素,这里输出: 6 5 4
}

6. 内存管理与性能特点

  • 内存自动管理:vector会自动处理内存的分配和释放,当添加元素导致当前分配的内存空间不足时,它会自动进行扩容操作,通常是按照一定的倍数(不同的STL实现可能有不同的扩容策略,常见的是1.5倍或2倍等)分配新的更大的内存空间,然后将原有元素复制或移动到新空间中,并释放原来的内存。这种自动管理机制方便了开发者,但也可能在频繁扩容时带来一定的性能开销(尤其是元素类型的拷贝或移动成本较高时)。
  • 随机访问性能好:由于vector内部元素在内存中是连续存储的,类似于普通的数组,所以它支持快速的随机访问,通过下标运算符或者迭代器解引用访问元素的时间复杂度为常数时间 O(1)。
  • 插入和删除元素的性能特点:在vector末尾添加或删除元素(通过push_back()、pop_back())的操作通常比较高效,时间复杂度接近常数时间(平均情况,不考虑偶尔的扩容操作带来的影响);但在中间或者开头位置插入或删除元素(通过insert()、erase())可能相对较慢,因为需要移动插入或删除位置后面的所有元素,时间复杂度为线性时间 O(n),其中n是vector中元素的个数。

7. 应用场景

  • 存储一组同类型的数据:比如存储游戏中的玩家分数列表、学生的成绩数组等,方便进行数据的添加、删除、修改以及遍历统计等操作。
  • 作为函数参数传递数组:在函数间传递数组时,如果数组大小不确定或者可能会变化,使用vector作为参数传递要比传递普通C风格数组更加方便、安全,避免了传递数组长度等额外参数以及数组越界等风险。例如:
void processVector(const std::vector<int>& vec) {
    // 在这里可以安全地遍历vec等操作,不用担心越界问题
    for (int element : vec) {
        std::cout << element << " ";
    }
}
int main() {
    std::vector<int> data = {1, 2, 3};
    processVector(data);
    return 0;
}
  • 配合其他STL算法使用:vector可以很好地与STL中的各种算法(如排序算法std::sort、查找算法std::find等)配合使用,实现更复杂的数据处理功能。例如:
#include <algorithm>
std::vector<int> numbers = {5, 3, 1, 4, 2};
std::sort(numbers.begin(), numbers.end());  // 对vector中的元素进行排序

总之,vector是C++ STL中一个功能强大、使用方便的容器,掌握它的各种特性和使用方法对于高效地进行C++编程非常有帮助,能够满足很多常见的动态数组相关的编程需求。

C++STL中list, vector, map, set用法与区别 List封装了链表,Vector封装了数组, list和vector得最主要的区别在于vector使用连续内存存储的,他支持[]运算符,而list是以链表形式实现的,不支持[]。 Vector与list Vector对于随机访问的速度很快,但是对于插入尤其是在头部插入元素速度很慢,在尾部插入速度很快。 List对于随机访问速度慢得多,因为可能要遍历整个链表才能做到,但是对于插入就快的多了,不需要... 阅读详情

相关推荐

C++——STL之vector详解

学习了string之后,学习其他模板将会更容易上手,一起来看一下vector吧!vector是表示大小可以变化的数组的序列容器。

weixin_59055853的博客 2325

C++:STL容器

C++:STL容器

abcsdbv的博客 427

《STL系列》之vector原理及实现

《STL系列》之vector原理及实现

C/C++编程:STL vector原理分析

概述 vector和array非常相似。两者的唯一差别在于空间的灵活性。 array是静态空间,一旦配置了就不能改变。如果有扩容/缩容需求,那么需要程序员自己先申请一块新空间,然后将元素从旧址一一搬到新址,再把原来的空间归还给系统 vector是动态空间,随着元素的加入,内部机制会自动扩充容量以容纳新元素。 vector的迭代器 vector维护的是一个连续线性空间: 因为底层是线性的,所以支持随机存取 如果需要遍历元素,那么可以用一个普通指针作为迭代器。 也就是说,vector提供了一个随机存取迭

OceanStar的博客 2306

手把手教你用VMware虚拟机搭建PCAN开发环境:从Ubuntu安装到CAN通讯实战

本文详细指导如何在VMware虚拟机中搭建PCAN开发环境,涵盖从Ubuntu系统安装、VMware精细配置、PCAN-USB设备直通,到Linux驱动编译、can-utils工具集使用及完整CAN通讯测试的全过程。通过实战步骤与故障排查技巧,帮助开发者快速构建稳定高效的CAN总线开发与测试沙盒,特别适合车载诊断与嵌入式通讯应用。

weixin_29216353的博客 221

逆向实战:手把手教你分析Google DroidGuard虚拟机的加密与反调试(附Python脚本)

本文深入解析Google DroidGuard虚拟机的加密机制与反调试策略,提供从环境配置到逆向分析的完整实战指南。通过IDA Pro、Frida等工具链,详细剖析DroidGuard的信号拦截、内存校验等保护机制,并附Python脚本实现自动化分析,助力Android安全研究人员突破GMS核心组件的安全防护。

weixin_32428571的博客 308

STL中vector的原理

参考链接 C++ vector实现原理 STL之vector容器用法 简介 vector 实际上是一个动态数组,预先指向一段连续的已分配好的内存空间。 原理 通俗地讲,当在 vector 中插入元素且 vector 当前的容量不足以存放时,vector 会重新开辟一段新的内存空间,将原有的数据全部拷贝到新空间后并插入新数据后,再将原有的空间段进行释放。 内部原理 vector 内部主要实现了 3 个迭代器,分别指向实际头尾、最大容量的尾部; size() 是实际大小,capicity() 是实际容量,

ZefinNg的博客 777

AIGC游戏本地化:用AI实现多语言自动翻译

游戏本地化是游戏全球化战略的关键环节,传统人工翻译方式成本高、周期长。本文旨在探讨如何利用AIGC技术实现高效、准确、低成本的游戏多语言自动翻译解决方案。我们将覆盖从文本翻译到语音合成的完整本地化流程,重点关注AI技术在游戏特定语境下的应用优化。文章首先介绍游戏本地化的核心挑战和AI解决方案,然后深入讲解关键技术原理,接着通过实战项目演示具体实现,最后讨论应用场景和未来趋势。AIGC:人工智能生成内容,指利用AI技术自动生成文本、图像、音频等内容本地化(Localization)

AI 领航者的博客 1336

带你深入理解STL中的vector

vector底层是一个动态数组,包含三个迭代器,start和finish之间是已经被使用的空间范围,end_of_storage是整块连续空间包括备用空间的尾部。当空间不够装下数据(vec.push_back(val))时,会自动申请另一片更大的空间(1.5倍或者2倍),然后把原来的数据拷贝到新的内存空间,接着释放原来的那片空间【vector内存增长机制】。当释放或者删除(vec.clear())里面的数据时,其存储空间不释放,仅仅是清空了里面的数据。

m0_61227789的博客 2065

分布式优化 (Distributed Optimization) 算法详解及案例分析

分布式优化是一种将优化问题分解为多个子问题并在多个计算节点上并行求解的方法。其目标是通过分布式计算资源高效地求解大规模优化问题。

闲人编程的博客 2707

第一章 DRM 子系统概述:1.2 专栏定位与技术覆盖范围

本专栏系统解析Linux内核DRM图形子系统的核心技术,涵盖GEM对象管理、TTM内存机制、DRM-Fence同步等核心模块,深入剖析DMA-BUF共享、DMA_Resv资源管理等关键技术。通过解读内核源码与用户态接口(libdrm),结合进程管理、匿名inode等底层机制,构建完整的DRM知识体系。专栏兼顾深度与易懂性,辅以实际应用场景分析,既适合图形驱动开发新手入门,也可满足资深工程师进阶需求,帮助读者掌握从内核实现到应用开发的全栈知识。

图形/计算GPU的驱动与虚拟化技术分享园地 3019

【STL】vector的实现原理

一、概述 vector的数据安排以及操作方式与array极为相似,两者的不同主要在于空间运用的灵活性。array是静态空间,一旦存满,就得分配更大的空间,所有琐碎的操作都得客户自己完成。而vector是动态空间,内部可以自行扩充,容纳新元素。 vector的实现技术,关键在于其对大小的控制以及重新分配时的数据移动效率。本章所采用vector版本为 SGI STL 2.91版本。 二、vector定义摘要 以下是vector部分定义的代码摘录。 _Alloc是SGI STL的空间配置器,具体详见【STL】空间

qq_43142509的博客 986

【基于 CasADi 的欠驱动无人船实时非线性模型预测控制(NMPC)实现与避碰仿真】MATLAB开源复现

本文提出了一种基于CasADi的欠驱动无人船实时非线性模型预测控制(NMPC)方法,实现了轨迹跟踪与避碰功能。研究采用三自由度USV动力学模型,集成静态与动态障碍物避碰约束,并满足国际海上避碰规则(COLREGS)。通过CasADi+IPOPT数值优化求解,实现了毫秒级实时控制。文章详细介绍了USV建模、NMPC控制器设计、避碰约束建模以及CasADi实现流程,包括核心求解流程和轨迹生成方法。实验结果表明,该方法能有效实现复杂环境下的轨迹跟踪与避碰功能。

vor234的博客 1394

【STL】顺序容器之vector用法总结

        标准库类型vector表示对象的集合,其中所有对象的类型都相同,集合中的每个对象都有一个与之对应的索引,索引用于访问对象。

WYuan的博客 721

内模控制(IMC)——理论、应用与实践

内模控制方法的核心思想是利用被控对象的数学模型(即内模)构建控制器,使得控制器可以“预知”被控系统的动态响应,从而在控制输入中提前补偿模型的固有特性和扰动影响。常见的内模控制结构中,将系统分为无延迟部分和扰动部分,并利用内部模型预测输出值,再通过反馈回路进行误差修正。utuimctufbtutui​mctuf​bt其中,uimctu_imc(t)ui​mct为内模预测得到的预补偿控制量,ufbtu_fb(t)uf​bt。

闲人编程的博客 2630

多图详解VSCode搭建Python开发环境

本文通过多图的方式详细介绍了VSCode搭建Python开发环境,希望能对学习Python的同学们有所帮助。 文章目录 1. VSCode的介绍和安装 2. 安装插件 2.1 安装中文插件 2.2 安装Python插件 2.3 安装远程插件 3. 远程连接服务器 3.1 配置ssh 3.2 运行代码 3.3 调试代码

weixin_43178406的博客 8万+

C++ vector的用法(整理)

C++ vector的用法(整理) vector 是向量类型,它可以容纳许多类型的数据,如若干个整数,所以称其为容器。vector 是C++ STL的一个重要成员,使用它时需要包含头文件: #include&lt;vector&gt;; 一、vector 的初始化:可以有五种方式,举例说明如下: (1) vector&lt;int&gt; a(10); //定义了10个整型元素...

wkq0825的专栏 74万+

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

【C++】STL---vector基本用法介绍

详细介绍了STL-vector中的基本用法。

m0_74352571的博客 2412

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

[C++ STL] vector 详解

vector是STL中的一个容器,实现了动态数组的功能。它可以存储任意类型的元素,并提供了一系列的操作函数,如插入、删除、访问等。动态大小:vector的大小可以根据需要进行动态调整,可以随时增加或减少元素的数量。连续存储:vector的元素在内存中是连续存储的,可以通过下标快速访问元素。头部插入删除效率较低:由于在头部插入或删除元素时需要进行大块内存的复制或移动,导致效率较低。随机访问效率高:由于元素的连续存储,可以通过下标直接访问任意位置的元素。

石墨博客 1687

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

【C++STL】“vector“用法 入门必备 超详细

vector是表示可变大小数组的序列容器。就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问,和数组一样高效。但是又不像组,它的大小是可以动态改变的,而且它的大小会被容器自动处理。本质讲,vector使用动态分配数组来存储它的元素。当新元素插入时候,这个数组需要被重新分配大小为了增加存储空间。其做法是,分配一个新的数组,然后将全部元素移到这个数组。

小小小智_x0__0x_的博客 1819

C++_STL之vector篇

注:C++中若使用vector需包含头文件<vector>.

h_number_1的博客 1650

【C++STL】vector的详细用法和底层原理

本文详细介绍了C++ STL中vector容器的使用方法,包括创建方式、常用成员函数和算法操作。主要内容包括:1. vector的创建方式及初始化方法;2. 迭代器、容量管理、元素访问和修改器等常用函数;3. push_back、insert、erase等元素操作方法;4. sort、unique、reverse等算法操作;5. 查找最值的方法;6. vector扩容机制及优化建议。文章通过代码示例展示了vector的各种用法,并比较了不同操作之间的区别,如push_back与emplace_back的效率

tangsl1552的博客 1606

C++STL(string和vector)

学习目标:vector中存放自定义数据类型,并打印输出//自定义数据类型public:mAge = age;//存放对象//创建数据it!= v.end();it++) {//放对象指针//创建数据it!= v.end();test02();return 0;

qq_55882840的博客 1921

STL vector 和 QT QVector的用法差别实例

1.STL与数据结构 STL是C++里最常用的容器(但不是最好的容器)。很多人在计算机学习阶段,对计算机的数据结构课程是一塌糊涂的;这种一塌糊涂的感觉,甚至伴随着很多计算机软件工程师的长期的职业周期。当然,这其实并不能够完全怪计算机学习者,相当一部分原因是中国大学的计算机学习的教材把明明很简单的事物弄成非常复杂的事物。大学的数据结构教材,一般是张乃孝的《算法与数据结构》和严蔚敏《数...

wangzhezhilu001的专栏 2710

C++中vector的用法

【C++STL】之vector的用法。本文主要讲解了C++STL中的vector的定义及初始化和一些vector的常用用法。如果你觉得本文对你有所帮助的话,还望不吝惜您的三连支持一下我哦!

H1727548的博客 2266

C++ stl容器之vector用法

vector容器用法

hutaotaotao的博客 1275
上一篇: windows C++ TCP客户端
下一篇: C++ STL(标准模板库)中类型萃取(Type Traits)原理
越甲八千
博客等级 码龄11年 2953粉丝 553原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值