当前位置: 首页 > news >正文

从零到一学习c++(基础篇--筑基期七-vector与迭代器)

  从零到一学习C++(基础篇) 作者:羡鱼肘子

温馨提示1:本篇是记录我的学习经历,会有不少片面的认知,万分期待您的指正。

 温馨提示2:本篇会尽量用更加通俗的语言介绍c++的基础,用通俗的语言去解释术语。

 温馨提示3:看本篇前可以先了解前篇的内容,知识体系会更加完整哦。

从零到一学习c++(基础篇--筑基期六-string)-CSDN博客

标准库类型vector 

1. 什么是vector?

vector 的基本概念

定义
  • vector 是一个 动态数组(dynamic array),属于C++标准库中的 顺序容器(sequential container)。

  • 头文件#include <vector>

  • 命名空间std::vector<T>

核心特性
  1. 动态大小:元素数量可以动态增长或缩减。

  2. 连续存储:元素在内存中连续存放,支持快速随机访问(通过下标)。

  3. 类型安全:所有元素必须是相同类型 T

  4. 自动内存管理:内存由 vector 自动分配和释放。

2. 基本用法

声明与初始化
#include <vector>
using namespace std;// 初始化方式
vector<int> v1;             // 默认初始化,空vector
vector<int> v2(v1);         // 拷贝v1的元素(v1和v2类型必须相同)
vector<int> v3 = v1;        // 等价于v2(v1)
vector<int> v4(5, 10);      // 5个元素,每个初始化为10
vector<int> v5(5);          // 5个元素,默认值初始化(int为0)
vector<int> v6{1, 2, 3};    // 列表初始化(C++11)
vector<int> v7 = {1, 2, 3}; // 等价于v6
添加元素
  • push_back():在尾部插入元素。

  • emplace_back()(C++11):直接在容器尾部构造元素(更高效)。

  • insert():在指定位置插入元素(效率较低,需移动后续元素)。

vector<int> v;
v.push_back(42);          // 插入42
v.emplace_back(42);       // 直接构造42(避免复制)
v.insert(v.begin(), 100); // 在头部插入100
温馨小贴士:

为什么emplace_back()更高效?

1. push_back 的工作原理

假设你有一个类 Person:class Person {
public:Person(string name, int age) {cout << "构造函数被调用" << endl;}Person(const Person& other) {cout << "拷贝构造函数被调用" << endl;}
};

当你使用 push_back 时:

vector<Person> people;
people.push_back(Person("Alice", 25));

发生了什么呐?

  1. 构造临时对象:先调用构造函数 Person("Alice", 25),创建一个临时对象。

  2. 拷贝到容器:再调用拷贝构造函数,将这个临时对象复制到 vector 的内存中。

  3. 销毁临时对象:临时对象被销毁。

多了一次额外的拷贝操作呢!

2. emplace_back 的工作原理

改用 emplace_back

people.emplace_back("Alice", 25);

发生了什么?

  1. 直接构造:直接在 vector 的内存空间中调用构造函数 Person("Alice", 25)

  2. 没有临时对象不创建临时对象,因此没有拷贝操作

3. 为什么更高效?

  • push_back:需要先构造对象,再拷贝到容器(如果对象很大,拷贝成本高)。

  • emplace_back:直接在容器内存中构造对象,跳过了临时对象和拷贝步骤

  • 性能提升:尤其对复杂对象(如包含大量数据的类)效果显著。

4. 技术原理

  • 可变参数模板emplace_back 使用 C++11 的可变参数模板,可以接受任意数量和类型的参数。

  • 完美转发:将这些参数直接传递给对象的构造函数,实现“原地构造”(in-place construction)。

5. 对比示例

情况1:简单类型(如 int

vector<int> v;
v.push_back(20);      // 构造临时int(20),然后复制(或移动)
v.emplace_back(20);   // 直接构造,没有区别(但对int来说,优化不明显)
  • 对简单类型,性能差异不大,但 emplace_back 仍更优。

情况2:复杂对象

class BigData {
public:BigData(int size) { /* 分配大量内存 */ }BigData(const BigData& other) { /* 深拷贝,成本高! */ }
};vector<BigData> vec;
vec.push_back(BigData(1000));    // 1次构造 + 1次拷贝(代价高)
vec.emplace_back(1000);          // 仅1次构造(无拷贝)
  • 对复杂对象,emplace_back 节省了深拷贝的时间。

6. 什么时候用 emplace_back

  • 当对象的构造函数需要参数时,优先用 emplace_back

  • 需要插入临时对象或直接传递参数时,用它更高效。

  • 简单类型(如 int)可以用,但性能提升不明显。

总结:emplace_back 通过直接在容器内存中构造对象,避免了临时对象的创建和拷贝操作,是 C++11 后更高效的插入方式! 😊

访问元素
  • v[n]:通过下标访问,不检查越界(类似数组)。

  • v.at(n):通过下标访问,越界抛出 std::out_of_range 异常。

  • v.front():返回第一个元素。

  • v.back():返回最后一个元素。

cout << v[0];       // 访问第0个元素(不检查越界)
cout << v.at(1);    // 访问第1个元素(越界会抛出异常)(推荐)
cout << v.front();  // 第一个元素(即v[0])
cout << v.back();   // 最后一个元素(即v[v.size()-1])
删除元素

  • pop_back():删除尾部元素。

  • erase():删除指定位置的元素(返回指向下一个元素的迭代器)。

  • clear():清空所有元素。

v.pop_back();      // 删除最后一个元素
v.clear();         // 清空所有元素
v.erase(v.begin() + 1); // 删除第2个元素(迭代器位置)
大小与容量
vector 的内存管理
  • size():当前元素个数。

  • capacity():当前分配的存储空间能容纳的元素数量。

  • resize(n):调整 size 为 n,多出的元素默认初始化。

  • reserve(n):预分配至少能容纳 n 个元素的内存(避免频繁扩容)。 

动态扩容机制
  • 当插入元素超过当前 capacity 时,vector 会重新分配更大的内存(通常是翻倍)。

  • 扩容成本需要拷贝所有元素到新内存,并释放旧内存。

  • 优化策略:如果预先知道元素数量,使用 reserve() 减少扩容次数。

int size = v.size();      // 当前元素个数
bool isEmpty = v.empty(); // 是否为空
v.resize(10);             // 调整大小为10(多出的元素默认初始化)
int cap = v.capacity();   // 当前分配的内存能容纳的元素数量
v.reserve(100);           // 预分配内存(避免频繁扩容)vector<int> v;
v.reserve(100); // 预分配100个元素的内存
for (int i = 0; i < 100; ++i) {v.push_back(i); // 不会触发扩容
}

3. 遍历vector

方法1:下标遍历
for (int i = 0; i < v.size(); i++) {cout << v[i] << " ";
}
方法2:迭代器遍历

vector 的迭代器
  • 迭代器提供了统一的访问容器元素的方式。

  • begin() 和 end() 返回指向首元素和尾后元素的迭代器。

  • 范围for循环(C++11)底层依赖迭代器。

for (auto it = v.begin(); it != v.end(); it++) {cout << *it << " ";
}
温馨小贴士:
  • vector 的迭代器是 随机访问迭代器(支持 it + n 操作)。

  • 修改 vector(如 push_back)可能导致迭代器失效。

以下操作会导致 vector 的迭代器、指针或引用失效:
  • 插入元素如果引发扩容,所有迭代器失效。

  • 删除元素:被删除元素之后的迭代器失效

  • 性能建议
  • 避免在中间位置频繁插入或删除(时间复杂度 O(n))。

  • 优先使用 emplace_back 代替 push_back(减少拷贝开销)。

  • vector<int> v = {1, 2, 3};
    auto it = v.begin();
    v.push_back(4); // 可能导致扩容,it失效!
    cout << *it;    // 未定义行为!

方法3:范围循环(C++11+)
for (auto num : v) {cout << num << " ";
}

 对比其他容器

容器特点
vector动态数组,尾部操作高效,支持随机访问,内存连续
list双向链表,任意位置插入/删除高效,不支持随机访问
deque双端队列,头尾插入/删除高效,支持随机访问
array固定大小数组,不支持动态扩容

4. 重要特性小结

动态扩容
  • 当插入元素超过当前容量时,vector会自动分配更大的内存(通常是当前容量的2倍)。

  • 频繁扩容会影响性能,可以用 reserve() 预先分配足够空间。

元素连续存储
  • 所有元素在内存中是连续存放的,类似数组。

  • 支持指针算术操作(例如 &v[0] 是首元素地址)。

5. 注意事项

  1. 越界访问v[i]不会检查越界,但v.at(i)会抛出std::out_of_range异常。

  2. 迭代器失效

    • 在修改vector(如插入、删除)后,旧的迭代器可能失效。

    • 例如,push_back可能导致内存重新分配,之前的迭代器指向无效地址。

  3. 性能

    • 尾部插入/删除(push_back/pop_back)高效(O(1)时间)。

    • 中间插入/删除需要移动元素,效率较低(O(n)时间)。

6. 示例代码

#include <vector>
#include <iostream>
using namespace std;int main() {vector<int> v;          // 空vectorv.reserve(10);          // 预分配内存for (int i = 0; i < 10; ++i) {v.emplace_back(i);  // 插入0~9}// 修改元素v[0] = 100;// 删除偶数for (auto it = v.begin(); it != v.end(); ) {if (*it % 2 == 0) {it = v.erase(it); // erase返回下一个有效迭代器} else {++it;}}// 输出结果for (int num : v) {cout << num << " ";}// 输出:100 1 3 5 7 9return 0;
}

7. 什么时候用vector?

  • 需要频繁在尾部添加/删除元素。

  • 需要随机访问元素(通过下标)。

  • 不确定元素数量,需要动态调整大小。

通过以上的学习,我们接触到了一个新的词:迭代器 ,那么什么是迭代器呢?

迭代器 (强化概念)

1. 迭代器的基本概念

什么是迭代器?
  • 迭代器是访问和操作容器(如 vectorlistmap 等)元素的通用机制。

  • 行为类似指针:可以解引用(*it)访问元素,用箭头操作符(->)访问成员,支持移动(++it--it)。

  • 迭代器是容器和算法之间的桥梁,使得算法可以独立于容器类型工作。

为什么需要迭代器?
  • 提供统一的元素访问方式,避免直接操作容器内部结构。

  • 支持泛型编程(例如 sort() 函数可以对所有支持随机访问迭代器的容器排序)。

2. 迭代器的基本操作

获取迭代器
vector<int> v = {1, 2, 3};
auto it_begin = v.begin(); // 指向第一个元素的迭代器
auto it_end = v.end();     // 指向尾后元素(最后一个元素的下一个位置)
常用操作
操作说明
*it解引用,获取迭代器指向的元素
it->mem访问元素的成员(等价于 (*it).mem
++it / it++移动到下一个元素
--it / it--移动到上一个元素(仅双向或随机访问迭代器支持)
it1 == it2判断两个迭代器是否指向同一位置
it + n / it - n随机访问迭代器支持跳跃(如 vector

3. 迭代器类型

迭代器类别

C++ 标准库定义了 5 类迭代器(从功能弱到强排序):

  1. 输入迭代器(Input Iterator):只读,单遍扫描(如 istream_iterator)。

  2. 输出迭代器(Output Iterator):只写,单遍扫描(如 ostream_iterator)。

  3. 前向迭代器(Forward Iterator):可读写,多遍扫描(如 forward_list 的迭代器)。

  4. 双向迭代器(Bidirectional Iterator):可前向和后向移动(如 list 的迭代器)。

  5. 随机访问迭代器(Random Access Iterator):支持所有指针算术操作(如 vectordeque 的迭代器)。

不同容器的迭代器类型
容器迭代器类型
vector随机访问迭代器
deque随机访问迭代器
list双向迭代器
forward_list前向迭代器
map/set双向迭代器

4. 迭代器的使用

遍历容器
vector<int> v = {1, 2, 3};
// 使用迭代器遍历
for (auto it = v.begin(); it != v.end(); ++it) {cout << *it << " ";
}
// 使用范围for循环(底层依赖迭代器)
for (int num : v) {cout << num << " ";
}
修改元素
vector<int> v = {1, 2, 3};
auto it = v.begin();
*it = 100; // 将第一个元素改为100

5. 迭代器失效问题

何时失效?
  • 向容器中添加或删除元素可能导致迭代器失效(尤其是 vector 和 string)。

  • 具体场景

    1. 添加元素

      • 如果引发扩容(push_back 导致 size > capacity),所有迭代器失效。

    2. 删除元素

      • 被删除元素之后的迭代器失效。

示例
vector<int> v = {1, 2, 3};
auto it = v.begin();
v.push_back(4);      // 可能导致扩容,it 失效!
cout << *it << endl; // 未定义行为!
如何避免?
  • 在修改容器后,重新获取迭代器。

  • 使用返回值更新迭代器(例如 erase() 返回删除后的下一个有效迭代器)。

vector<int> v = {1, 2, 3, 4};
auto it = v.begin();
while (it != v.end()) {if (*it % 2 == 0) {it = v.erase(it); // erase 返回下一个有效迭代器} else {++it;}
}

6. 特殊迭代器

1. const_iterator
  • 用于只读访问容器元素,不能修改元素。

  • 通过 cbegin() 和 cend() 获取。

vector<int> v = {1, 2, 3};
vector<int>::const_iterator cit = v.cbegin();
// *cit = 10; // 错误:不能修改元素
2. 反向迭代器(reverse_iterator)
  • 从后向前遍历容器,通过 rbegin() 和 rend() 获取。

  • 仅双向或随机访问迭代器支持。

vector<int> v = {1, 2, 3};
for (auto rit = v.rbegin(); rit != v.rend(); ++rit) {cout << *rit << " "; // 输出 3 2 1
}
3. 插入迭代器(insert_iterator)
  • 用于向容器中插入元素(如 back_inserterfront_inserter)。

  • 示例:

vector<int> v = {1, 2, 3};
auto back_it = back_inserter(v); // 插入到尾部
*back_it = 4; // v变为 [1, 2, 3, 4]

7. 迭代器与算法

标准库算法(如 sortfind)通过迭代器操作容器:

vector<int> v = {3, 1, 4, 2};
sort(v.begin(), v.end()); // 排序 [1, 2, 3, 4]
auto it = find(v.begin(), v.end(), 3); // 查找元素3的位置

8. 迭代器辅助函数

advance 和 distance
  • advance(it, n):将迭代器移动 n 步。

  • distance(it1, it2):计算两个迭代器之间的距离。

  • 注意:distance 的时间复杂度取决于迭代器类型(随机访问迭代器为 O(1),其他为 O(n))。

vector<int> v = {1, 2, 3, 4, 5};
auto it = v.begin();
advance(it, 3);       // it 指向4
cout << *it << endl;  // 输出4
cout << distance(v.begin(), it) << endl; // 输出3

9. 注意事项

  1. 不要解引用 end() 迭代器:它指向尾后元素,不可解引用。

  2. 迭代器类型必须匹配:不同容器的迭代器类型不同,不能混用。

  3. 谨慎处理迭代器失效:修改容器后,迭代器可能失效。

相关文章:

从零到一学习c++(基础篇--筑基期七-vector与迭代器)

从零到一学习C&#xff08;基础篇&#xff09; 作者&#xff1a;羡鱼肘子 温馨提示1&#xff1a;本篇是记录我的学习经历&#xff0c;会有不少片面的认知&#xff0c;万分期待您的指正。 温馨提示2&#xff1a;本篇会尽量用更加通俗的语言介绍c的基础&#xff0c;用通俗的语言去…...

PKI及SSL协议分析

PKI的基本组成&#xff0c;完整的PKI系统必须具有权威认证机构(CA)、数字证书库、密钥备份及恢复系统、证书作废系统、应用接口&#xff08;API&#xff09;等基本构成部分&#xff0c;构建PKI也将围绕着这五大系统来着手构建。 任务一&#xff1a;搭建CA服务器 本任务初步了…...

请解释 JavaScript 中的函数式编程,优缺点是什么?

一、对JavaScript函数式编程的理解 函数式编程&#xff08;Functional Programming&#xff0c;FP&#xff09;是一种编程范式&#xff0c;它将计算视为数学函数的求值&#xff0c;并避免改变状态和可变数据。 在JavaScript中&#xff0c;函数式编程具有以下几个关键特性&…...

WPS接入DeepSeek模型

1.wps 下载安装 WPS-支持多人在线协作编辑Word、Excel和PPT文档_WPS官方网站 &#xff08;最好是安装最新的wps&#xff09; 2.offieceAi工具下载安装 软件下载 | OfficeAI助手 下载后安装下载下来的两个工具。安装路径可以自行修改 3.打开WPS,点击文件-》 选项-》信任中心 勾…...

头条百度批量采集软件说明文档

旧版说明文档《头条号文章批量采集软件4.0版本说明文档&#xff01;头条/微头条文章批量采集》 头条的采集软件已经更新了好多个版本了&#xff0c;一直没有做详细的介绍文档&#xff0c;最近更新了一些功能进去&#xff0c;一块来写一下说明文档。 1、主界面 2、头条作者采集…...

网络安全架构师怎么考 网络安全 架构

安全通信网络 随着现代技术的不断发展&#xff0c;等级保护对象通常通过网络实现资源共享和数据交互&#xff0c;当大量的设备连成网络后&#xff0c;网络安全成了最为关注的问题。按照“一个中心&#xff0c;三重防御”的纵深防御思想&#xff0c;边界外部通过广域网或城域网…...

Vue 3 30天精进之旅:Day 21 - 项目实践:打造功能完备的Todo应用

前言 经过前20天的学习&#xff0c;我们已经掌握了Vue 3的核心概念、组合式API、路由、状态管理等关键技术。今天将通过一个完整的项目实践——Todo应用&#xff0c;将所学知识融会贯通。我们将为Todo应用添加编辑、删除、过滤等进阶功能&#xff0c;并优化代码结构。 一、项目…...

2025年02月11日Github流行趋势

项目名称&#xff1a;unsloth 项目地址url&#xff1a;https://github.com/unslothai/unsloth项目语言&#xff1a;Python历史star数&#xff1a;27175今日star数&#xff1a;1024项目维护者&#xff1a;danielhanchen, shimmyshimmer, Erland366, Datta0, xyangk项目简介&…...

嵌入式硬件篇---原码、补码、反码

文章目录 前言简介八进制原码、反码、补码1. 原码规则示例问题 2. 反码规则示例问题 3. 补码规则示例优点 4. 补码的运算5. 总结 十六进制原码、反码、补码1. 十六进制的基本概念2. 十六进制的原码规则示例 3. 十六进制的反码规则示例 4. 十六进制的补码规则示例 5. 十六进制补…...

PCM与G711A互转

PCM与G711A互转 工具类&#xff08;Java&#xff09;调用方法&#xff08;Kotlin&#xff09; 工具类&#xff08;Java&#xff09; public class G711Code {private final static int SIGN_BIT 0x80;private final static int QUANT_MASK 0xf;private final static int SEG…...

MapReduce简单应用(三)——高级WordCount

目录 1. 高级WordCount1.1 IntWritable降序排列1.2 输入输出格式1.3 处理流程 2. 代码和结果2.1 pom.xml中依赖配置2.2 工具类util2.3 高级WordCount2.4 结果 参考 本文引用的Apache Hadoop源代码基于Apache许可证 2.0&#xff0c;详情请参阅 Apache许可证2.0。 1. 高级WordCo…...

C# 数据验证Regex

Regular Expression&#xff0c;简称 Regex,是一种用于匹配和处理文本的强大工具。它通过定义特定的模式&#xff0c;可以用来搜索、替换或提取字符串中的特定内容。 先引入命名空间 using System.Text.RegularExpressions; Intege(整数) 必须是正整数 //必须是正整数publi…...

Jenkins+gitee 搭建自动化部署

Jenkinsgitee 搭建自动化部署 环境说明&#xff1a; 软件版本备注CentOS8.5.2111JDK1.8.0_211Maven3.8.8git2.27.0Jenkins2.319最好选稳定版本&#xff0c;不然安装插件有点麻烦 一、安装Jenkins程序 1、到官网下载相应的版本war或者直接使用yum安装 Jenkins官网下载 直接…...

C/C++混合读入cin与scanf问题

因为C/C在某些时候是如此的融洽&#xff0c;以至于很多时候可能会混用&#xff0c;就比如 scanf与cin或getline(cin, ..)这是一个严肃的问题。因为随意混用&#xff0c;可能导致&#xff0c;在某些特殊时刻&#xff0c;读取混乱。所以本篇的意义就是为了缕清混用机制 一、scan…...

矩阵 NFC 碰一碰发视频源码搭建技术解析,支持OEM

一、引言 在移动互联与物联网飞速发展的当下&#xff0c;NFC&#xff08;Near Field Communication&#xff0c;近场通信&#xff09;技术凭借其便捷、快速的数据传输特性&#xff0c;在众多领域得到广泛应用。本文将深入探讨如何搭建矩阵 NFC 碰一碰发视频的源码&#xff0c;…...

Log4j定制JSON格式日志输出

1.前言 log4j是Java中一个强大的日志记录框架&#xff0c;通过简单的配置便可以在程序中进行日志打印与记录。关于log4j博主最近碰到一个需求&#xff0c;需要将程序运行过程中的日志按给定的json模板输出&#xff0c;本文记录一下log4j如何配置json格式的日志打印。 2.日志配…...

Spring依赖注入方式

写在前面&#xff1a;大家好&#xff01;我是晴空๓。如果博客中有不足或者的错误的地方欢迎在评论区或者私信我指正&#xff0c;感谢大家的不吝赐教。我的唯一博客更新地址是&#xff1a;https://ac-fun.blog.csdn.net/。非常感谢大家的支持。一起加油&#xff0c;冲鸭&#x…...

【C++八股】什么是函数指针,如何定义和使⽤场景

函数指针是指向函数的指针变量&#xff0c;它存储的是一个函数的地址&#xff0c;允许通过指针间接调用函数。使用函数指针可以动态地选择和调用函数&#xff0c;或者将函数作为参数传递给其他函数。 1. 函数指针的定义 函数指针的定义与普通指针稍有不同。它需要声明指向特定…...

DeepSeek 入驻 Cursor —— 表现能否超越 Claude?

DeepSeek 刚刚在 Cursor 平台上线了它的两款模型&#xff1a;DeepSeek V3 和 R1。目前&#xff0c;许多开发者&#xff08;包括我们在内&#xff09;主要依赖 Claude 3.5 Sonnet&#xff08;最新版本 claude-3-5-sonnet-20241022&#xff09;作为主要语言模型&#xff0c;因此我…...

skynet-src/atomic.h:25:23: 致命错误:stdatomic.h:没有那个文件或目录

skynet-src/atomic.h:25:23: 致命错误&#xff1a;stdatomic.h&#xff1a;没有那个文件或目录 故事背景&#xff0c;又接了一个新项目&#xff0c;要搞开发环境啊。skyent的框架。ubuntu已经跑起来了&#xff0c;但是内网是centos的跑不起来。只能怀疑是环境问题了&#xff0…...

docker compose部署nexus

整个工具的代码都在Gitee或者Github地址内 gitee&#xff1a;solomon-parent: 这个项目主要是总结了工作上遇到的问题以及学习一些框架用于整合例如:rabbitMq、reids、Mqtt、S3协议的文件服务器、mongodb github&#xff1a;GitHub - ZeroNing/solomon-parent: 这个项目主要是…...

IBM服务器刀箱Blade安装Hyper-V Server 2019 操作系统

案例:刀箱某一blade,例如 blade 5 安装 Hyper-V Server 2019 操作系统(安装进硬盘) 刀箱USB插入安装系统U盘,登录192.168... IBM BlandeCenter Restart Blande 5,如果Restart 没反应,那就 Power Off Blade 然后再 Power On 重启后进入BIOS界面设置usb存储为开机启动项 …...

Python的顺序结构和循环结构

文章目录 一、条件语句&#xff08;1&#xff09;条件语句的定义&#xff08;2&#xff09;条件语句的语法&#xff08;a&#xff09;单分支 if&#xff08;b&#xff09;双分支 if-else&#xff08;c&#xff09;多分支 if-elif-elif-...-else &#xff08;3&#xff09;注意事…...

[python SQLAlchemy数据库操作入门]-30.掌握 SQLAlchemy:优雅应对数据库异常的艺术

哈喽,大家好,我是木头左! 捕获和处理 SQLAlchemy 异常 在实际应用中,需要根据不同的异常类型采取不同的处理策略。下面是一个示例,展示了如何捕获和处理 SQLAlchemy 的异常。 from sqlalchemy import create_engine, Column, Integer, String, exc from sqlalchemy.ext.…...

编译和链接【三】

文章目录 编译和链接【三】前言系列文章入口编译过程词法分析语法分析语义分析生成中间代码汇编链接 编译和链接【三】 前言 在我大一的时候&#xff0c; 我使用VC6.0对C语言程序进行编译链接和运行 &#xff0c; 然后我接触了VS&#xff0c; Qt creator等众多IDE&#xff0c…...

11苍穹外卖之Apache ECharts(数据可视化图表、后端传数据)

课程内容 Apache ECharts 营业额统计 用户统计 订单统计 销量排名Top10 功能实现&#xff1a;数据统计 数据统计效果图&#xff1a; 1. Apache ECharts 1.1 介绍 Apache ECharts 是一款基于 Javascript 的数据可视化图表库&#xff0c;提供直观&#xff0c;生动&#…...

Grafana-使用Button修改MySQL数据库

背景 众所周知&#xff0c;Grafana是一个用来展示数据的平台&#xff0c;但是有时候还是会有需求说能不能有一个按钮&#xff0c;点击的时候再对数据库进行修改&#xff0c;从而达到更新数据的效果 经过多方查证&#xff0c;终于实现了一个简单的&#xff0c;点击button执行sq…...

C++11语法及库详解

目录 一、c11语法 1. 自动类型推导 (auto) 2. 基于范围的 for 循环 3. Lambda 表达式 4. 智能指针 5. 右值引用和移动语义 6. nullptr 关键字 7. constexpr 关键字 8. 初始化列表 9. std::thread 多线程支持 10. std::function 和 std::bind 11. std::unordered_map…...

数据库,数据表的增删改查操作

一.数据库的基本操作 &#xff08;1&#xff09;创建数据库 创建数据库就是在数据库系统中划分一块存储数据的空间&#xff0c;方便数据的分配、放置和管理。在MySQL中使用CREATE DATABASE命令创建数据库&#xff0c;语法格式如下: CREATE DATABASE数据库名称; 注&#xff1a…...

Python——批量图片转PDF(GUI版本)

目录 专栏导读1、背景介绍2、库的安装3、核心代码4、完整代码总结专栏导读 🌸 欢迎来到Python办公自动化专栏—Python处理办公问题,解放您的双手 🏳️‍🌈 博客主页:请点击——> 一晌小贪欢的博客主页求关注 👍 该系列文章专栏:请点击——>Python办公自动化专…...

RocketMQ面试题:原理部分

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…...

中间件-安装Minio-集成使用(ubantu-docker)

目录 1、安装docer 2、运行以下命令拉取MinIO的Docker镜像 3、检查当前所有Docker下载的镜像 4、创建目录 5、创建Minio容器并运行 6、SDK操作 FileUploader.java 1、安装docer 参考这篇&#xff1a;Linux安装Docker 2、运行以下命令拉取MinIO的Docker镜像 docker pull…...

vue3: const一个function怎么写呢?

问&#xff1a; 用ref或者reactive定一个一个const refCharts ref(function xxx (config){ xxxxx,xxxxx xxxx,xxxx })请问怎么写&#xff1f; 回答&#xff1a; 在 Vue 3 中&#xff0c;ref 和 reactive 是两种常用的响应式数据定义方式。ref 用于定义单个响应式对象或原始值…...

【JVM详解三】垃圾回收机制

一、对象是否存活 强引用&#xff1a;Object obj new Object(); 只要强引用还在&#xff0c;垃圾收集器永远不会回收掉被引用的对象。在不用对象的时将引用赋值为 null&#xff0c;能够帮助垃圾回收器回收对象。比如 ArrayList 的 clear() 方法实现。软引用&#xff08;SoftRe…...

dbeaver 安装之后出现mysql连接异常问题

1.手动下载mysql驱动程序 参考文档DBeaver连接mysql驱动下载失败怎么办&#xff1f;-CSDN博客 2.添加对应的下载程序到dbeaver 【DBeaver】缺少mysql驱动_dbeaver连接mysql缺少驱动-CSDN博客 配置mysql 地址端口账户等即可使用...

Android Studio历史版本下载

Android Studio历史版本下载 历史版本所在网站: https://developer.android.google.cn/studio/archive 等待加载 1、&#xff08;需要点击switch to english&#xff09;然后出现Terms and conditions 2、滑到最下面&#xff0c;点击I agree to the terms&#xff0c;之后才会…...

【每日一题 | 2025】2.3 ~ 2.9

个人主页&#xff1a;GUIQU. 归属专栏&#xff1a;每日一题 文章目录 1. 【2.3】P8784 [蓝桥杯 2022 省 B] 积木画2. 【2.4】P8656 [蓝桥杯 2017 国 B] 对局匹配3. 【2.5】[ABC365D] AtCoder Janken 34. 【2.6】P8703 [蓝桥杯 2019 国 B] 最优包含5. 【2.7】P8624 [蓝桥杯 2015…...

国产编辑器EverEdit - 迷你查找

1 迷你查找 1.1 应用场景 某些场景下&#xff0c;用户不希望调出复杂的查找对话框&#xff0c;此时可以使用迷你查找窗口。 1.2 使用方法 选择主菜单查找 -> 迷你查找&#xff0c;或使用快捷键Ctrl Alt F&#xff0c;会在右上角弹出迷你查找窗口&#xff0c;如下图所示…...

制药行业 BI 可视化数据分析方案

一、行业背景 随着医药行业数字化转型的深入&#xff0c;企业积累了海量的数据&#xff0c;包括销售数据、生产数据、研发数据、市场数据等。如何利用这些数据&#xff0c;挖掘其价值&#xff0c;为企业决策提供支持&#xff0c;成为医药企业面临的重大挑战。在当今竞争激烈的…...

第40天:Web开发-JS应用VueJS框架Vite构建启动打包渲染XSS源码泄露代码审计

#知识点 1、安全开发-VueJS-搭建启动&打包安全 2、安全开发-VueJS-源码泄漏&代码审计 一、Vue搭建创建项目启动项目 1、Vue 框架搭建->基于nodejs搭建&#xff0c;安装nodejs即可 参考&#xff1a;https://cn.vuejs.org/ 已安装18.3或更高版本的Node.js 2、Vue 创建…...

2.10学习总结

今天接着看了数据结构&#xff0c;但是跟指针有关的看不懂&#xff08;万恶的指针&#xff09;&#xff0c;写了考试的补题。 #include <stdio.h> #include <stdlib.h> int a[1000005]; int main() {int n,i,x0;scanf("%d",&n);for(i1;i<n;i){x;i…...

MySQL 中可以通过添加主键来节省磁盘空间吗?(译文)

从历史上看&#xff0c;MySQL 不需要在表上定义显式主键&#xff0c;直到今天默认都是这样。不过&#xff0c;这种要求是通过两种复制方法施加的&#xff1a;组复制和 Percona XtraDB 集群 &#xff08;PXC&#xff09;&#xff0c;默认情况下不允许使用没有主键的表。对于缺少…...

Django在终端创建项目(pycharm Windows)

1.选择目录 选择或新建一个文件夹&#xff0c;作为项目保存的地方 2.右键在终端打开 3.确定django-admin.exe安装位置 找到自己安装django时&#xff0c;django-admin.exe安装的位置&#xff0c;例如 4.运行命令 使用django-admin.exe的绝对路径&#xff0c;在刚才打开的终端…...

IDEA接入DeepSeek

IDEA 目前有多个途径可以接入deepseek&#xff0c;比如CodeGPT或者Continue&#xff0c;这里借助CodeGPT插件接入&#xff0c;CodeGPT目前用的人最多&#xff0c;相对更稳定 一、安装 1.安装CodeGPT idea插件市场找到CodeGPT并安装 2.创建API Key 进入deepseek官网&#xf…...

Linux 内核自旋锁spinlock(二)--- ticket spinlock

文章目录 前言一、ticket spinlock二、源码分析2.1 spin_lock_init2.2 spin_lock2.2 spin_unlock 参考资料 前言 自旋锁是 Linux 内核中最底层的互斥机制。因此&#xff0c;它们对内核的安全性和性能有着巨大的影响&#xff0c;因此对各种&#xff08;特定架构的&#xff09;自…...

Elixir语言的计算机基础

Elixir语言的计算机基础 引言 Elixir是一种现代的编程语言&#xff0c;建立在Erlang虚拟机&#xff08;BEAM&#xff09;上&#xff0c;专注于并发、分布式系统和容错能力。随着互联网的发展&#xff0c;应用程序的需求变得越来越复杂&#xff0c;Elixir凭借其高效的性能、灵…...

MindStudio制作MindSpore TBE算子(二)算子测试

在上一节中&#xff0c;成功制作了Mindspore的Add算子&#xff0c;具体可以查看MindStudio制作MindSpore TBE算子&#xff08;一&#xff09;算子制作&#xff0c;这一节&#xff0c;一起看看如何对算子进行测试。 建议参考以下内容一起食用&#xff1a; 算子代码实现 MindSpor…...

深度解读城市地下网管管廊改造要点

引 言 近日国家发改委和住建部联合发布通知&#xff08;后附&#xff09;&#xff0c;要求各地抓紧编制“城市地下管网和综合管廊建设改造实施方案”并于12月27日前报国家发改委和住建部相关司处&#xff0c;逾期未报的城市&#xff08;县、区&#xff09;&#xff0c;视同自愿…...

Docker 部署 redis | 国内阿里镜像

一、简易单机版 1、镜像拉取 # docker hub 镜像 docker pull redis:7.0.4-bullseye # 阿里云镜像 docker pull alibaba-cloud-linux-3-registry.cn-hangzhou.cr.aliyuncs.com/alinux3/redis_optimized:20240221-6.2.7-2.3.0 2、运行镜像 docker run -itd --name redis \n …...

Day88:加载游戏图片

在游戏开发中,加载和显示图片是非常常见的需求,尤其是在 2D 游戏 中,角色、背景、道具、敌人等都需要用图片来表示。今天,我们将学习如何在 Python 游戏开发中使用 Pygame 加载并显示图片。 1. 加载游戏图片的基本步骤 在 Pygame 中加载图片通常需要以下几个步骤: 导入 P…...