【C++知识点总结全系列 (06)】:STL六大组件详细总结与分析- 配置器、容器、迭代器、适配器、算法和仿函数

news2025/2/28 17:10:44

STL六大组件目录

  • 前言
  • 1、配置器
    • (1)What
    • (2)Why
    • (3)How
      • A.调用new和delete实现内存分配与销毁
      • B.STL Allocator
    • (4)allocator类
      • A.What
      • B.How
      • C.allocator的算法
  • 2、容器
    • (1)What
    • (2)Which(有哪些容器)
    • (3)序列容器(顺序容器)
      • A.Which
      • B.array:存储固定长度元素的序列
      • C.deque队列
      • D.vector
      • E.forward_list
      • F.list
      • G.string
      • H.tuple
    • (4)关联容器
      • A.What
      • B.Which
      • C.Why
      • D.pair
      • E.map
      • F.unordered_map
  • 3、迭代器
    • (1)What
    • (2)Why
    • (3)Which(迭代器类型)
      • A.输出迭代器
      • B.输入迭代器
      • C.单向迭代器
      • D.双向迭代器
      • E.随机访问迭代器
  • 4、适配器
    • (1)What
    • (2)Why
    • (3)栈适配器
    • (4)队列适配器
  • 5、算法
    • (1)What(什么是STL中的算法)
    • (2)Which
    • (3)\<algorithm\>
    • (4)cstdlib
      • (5)numric
  • 6、仿函数
    • (1)What
    • (2)Why(仿函数的作用)
      • A.可作为排序规则
      • B.作为判别式使用
      • C.可携带更多信息,拥有多种内部状态
      • D.作为算法 for_each 的返回值

前言

在这里插入图片描述
仿函数提供了一种调用算法的方式、算法通过迭代器对容器里边的数据进行访问和处理、迭代器是访问容器中数据的重要方式、而容器所占有的内存空间是由配置器分配和管理的。此外,适配器是对容器、迭代器或仿函数的一个封装。

1、配置器

(1)What

负责空间配置与管理,从实现角度来看,配置器是一个实现了动态空间配置、空间管 理、空间释放的类模板

(2)Why

动态内存管理(内存分配、对象构造、对象析构、内存释放、内存重新分配等)

(3)How

A.调用new和delete实现内存分配与销毁

在这里插入图片描述

B.STL Allocator

对象的构造由allocator类的construct负责,对象的释放由destroy负责
内存配置由allocate()负责,内存释放由deallocate()负责

(4)allocator类

A.What

C++11中预定义的配置器类,用于管理容器的内存分配是释放

B.How

allocator类的使用主要关注它的四个成员函数:

  • 分配内存:allocate()
  • 构造对象:construct(),在分配好的内存中构造对象
  • 销毁对象:destroy(),回收已分配的内存空间,释放数据对象
  • 回收内存:deallocate(),将内存空间归还给操作系统
//分配 10 个 string 类型的对象的内存(未初始化) 
std::allocator<string> alloca;
auto const p=alloca.allocate(10); //分配未构造的内存
alloca.construct(p,"zhangsan"); 
auto q=p;
alloca.construct(++q,"lisi"); 
alloca.construct(++q,"wangwu"); 
cout<<(*q)<<endl; //打印:wangwu
//使用完对象后,必须对每个构造的元素调用 destroy 类销毁它们 
while(q!=p)
{ 
	alloca.destroy(--q); 
}
//元素被销毁之后,可以重新使用 alloca,也可以归还给系统 
alloca.deallocate(p,10);

C.allocator的算法

在这里插入图片描述

//拷贝和填充未初始化内存的算法:在未初始化的内存中创建对象 
std::vector<int> vec_a{1,2,3,4,5};
std::allocator<int> alloca_int; 
int* p_int=alloca_int.allocate(vec_a.size()*2);//p_int 为 int 类型的指针
//拷贝元素到 alloca_int 的内存中去
std::uninitialized_copy(vec_a.begin(),vec_a.end(),p_int);
for(int i=0;i<vec_a.size();++i){cout<<*(p_int+i)<<" ";}cout<<endl;//打印:1 2 3 4 5
//将剩余的元素初始化为 100
std::uninitialized_fill_n(p_int,vec_a.size(),100);
for(int i=0;i<vec_a.size();++i){cout<<*(p_int+i)<<" ";}cout<<endl;//打印:100 100 100 100 100

2、容器

(1)What

本质是标准库中特定用于存储和管理数据的类模板

(2)Which(有哪些容器)

在这里插入图片描述

  • 序列容器(顺序容器):容器中的数据是有序的
  • 关联容器:通过键值对(key-valuepair)来组织和访问元素,将红黑树作为底层数据结构,用于维护 键值对集合,并提供高效的元素访问和操作能力,本质是类模板

(3)序列容器(顺序容器)

A.Which

array、deque、forwarrd_list、list、vector

B.array:存储固定长度元素的序列

在这里插入图片描述
基本使用:导入array、构建array对象、调用array对象函数、使用算法对容器元素进行操作

#include <array>
std::array<int, 6> array01{11,22,33,44,55,66};

非成员函数

  • get(array):

template <int Index, class T, size_t N> constexpr T& get(array<T,N>&arr> noexcept;

std::array<int,4> c0{0,1,2,3}; //创建并初始化一个array类对象c0
for(const int &iTmp:c0)
{
	cout<<" "<<iTmp;
}
int i1 = std::get<1>(c0); // 得到1
int i3 = std::get<3>(c0); // 得到3
  • swap(array01, array02):

template<class T, std::size_t N>
void swap(array<T, N>&arr01, array<T,N> &arr01);

//成员函数
arr01.swap(arr02);
//非成员函数
swap(arr01, arr02);
  • 其它非成员函数:
    在这里插入图片描述
    成员函数
成员函数说明
array()构造函数
at()返回指定位置的引用
font() / back()返回第一个元素 (最后一个)元素的引用
begin() / end()返回第一个(最后一个)元素的迭代器
cbegin() / cend()返回第一个(最后一个)元素的常量迭代器
rbegin() / rend()返回反向数据中第一个(最后一个)元素的迭代器
data()返回第一个元素的地址
empty()测试array对象中是否存在数据
fill()将所有元素替换为指定值
assign()同fill
size()返回array对象中元素的个数
swap()交换两个array对象的数据

C.deque队列

在这里插入图片描述
基本使用:导入deque、创建deque对象、调用对象函数、使用算法对容器中元素进行操作

#include <deque>
std::deque<int> q01(10); //指定队列长度
std::vector<int> vec{1,2,3,4,5}
std::deque<int> q02(vec.begin(),vec.end()); //q02有初始值

非成员函数:

  • swap(q01,q02):交换两个队列数据

成员函数:

成员函数说明
at()返回指定位置的引用
font() / back()返回第一个元素 (最后一个)元素的引用
begin() / end()返回第一个(最后一个)元素的迭代器
cbegin() / cend()返回第一个(最后一个)元素的常量迭代器
rbegin() / rend()返回反向数据中第一个(最后一个)元素的迭代器
data()返回第一个元素的地址
empty()测试容器中是否存在数据
fill()将所有元素替换为指定值
assign()同fill
size()返回array对象中元素的个数
swap()交换两个容器的数据
emplace()就地构造元素插入到deque指定位置
emplace_back() / emplace_front()就地构造元素插入到末尾(开头)
erase()从指定位置删除一个或多个元素
insert()在指定位置插入一个或多个元素
pop_back() / pop_front()清除deque末尾(开头)元素
push_back() / push_front()添加元素到末尾(开头)
resize()为deque指定新的大小

D.vector

在这里插入图片描述
基本使用:导入vector、构建vector对象、调用vector函数、使用算法对容器中元素进行处理

#include <vector>
std::vector<int> vecArr01;

非成员函数

  • hash():返回vector对象的哈希值
  • swap( vec01, vec02);

成员函数

成员函数说明
font() / back()返回第一个元素 (最后一个)元素的引用
begin() / end()返回第一个(最后一个)元素的迭代器
cbegin() / cend()返回第一个(最后一个)元素的常量迭代器
emplace_back()在末尾处添加元素
emplace()在指定位置插入就地构造的元素
push_back() / pop_back()添加(删除)末尾处的元素
sort()对容器中的元素进行排序
reverse()颠倒元素中的顺序
size()返回容器中元素的数量
shrink_to_fit()放弃额外的容量
swap()交换两个容器的元素

E.forward_list

在这里插入图片描述
基本使用:导入forward_list、创建对象、调用对象函数、使用算法对容器中元素进行处理

#include <forward_list>
std::forward_list flst01(10);

成员函数:

成员函数说明
font()返回第一个元素 (最后一个)元素的引用
begin() / end()返回第一个(最后一个)元素的迭代器
cbegin() / cend()返回第一个(最后一个)元素的常量迭代器
emplace_after()在指定位置之后创建元素
erase_after()删除指定位置之后的元素
insert_after()在指定元素之后添加元素
pop_front()删除起始处的一个元素
push_front()在起始处插入一个元素
sort()对容器中的元素进行排序
reverse()颠倒元素中的顺序

F.list

在这里插入图片描述
基本使用:导入list、构建list对象、调用list对象函数、使用算法对容器中元素进行处理

#include <list>
std::list<int> lst;

非成员函数:

  • swap(lst01, lst02);

成员函数:

成员函数说明
font() / back()返回第一个元素 (最后一个)元素的引用
begin() / end()返回第一个(最后一个)元素的迭代器
cbegin() / cend()返回第一个(最后一个)元素的常量迭代器
emplace_after()在指定位置之后创建元素
emplace_front()在起始位置处添加一个元素
emplace_after()在结尾位置处添加一个元素
erase()从列表中指定位置删除一个元素
insert()在指定位置插入一个或多个元素
pop_back() / pop_front()删除末尾(起始)元素
push_back() / push_front()在末尾(起始)处添加元素
sort()对容器中元素进行排序
splice()将自定义的列表从list对象中删除或加入

G.string

基本使用:导入string、创建对象、调用string对象的函数、使用算法对string对象中元素进行处理

#include <string>
std::string strFlePth = "D:\\a.text";

非成员函数:

  • getline(strSrc, line); //逐行提取srtSrc中的字符串
  • swap(str01, str02); //交换两个字符数组

专用化非成员模板函数:

函数名说明
stod() / stof() / stoi() / stold() / stoll() / stoul() / stoull()将string转为double / float / int / long double / unsigned long long
to_string()将其它类型转为string类型
to_wstring()转为宽字符串类型

H.tuple

What:

用于存储多个不同类型的元素的通用容器类模板

Why:

灵活地适应不同类型的元素,并提供相应的操作和访问方式;当我们希望将一些数据 组合成对象,但又不想自定义数据结构来表示该对象时,tuple 将非常有用

How:

构造tuple对象和初始化

// 默认构造函数
std::tuple<string, int, vector<double>> t0; 
cout << std::boolalpha << (std::get<1>(t0) == 0) << endl; // 打印:true
// 参数化构造函数
std::tuple<string, int, vector<double>> t1("zhangsan", 23, {32, 33, 34});
// 拷贝构造函数
auto t1_copyF(t1); cout << std::get<0>(t1_copyF) << endl; // 打印:zhangsan
// 移动构造函数
auto t1_mvF(std::move(t1_copyF)); cout << std::get<0>(t1_mvF) << endl; // 打印:zhangsan cout << std::boolalpha << (std::get<0>(t1_copyF) == "") << endl; // 打印:true
// 拷贝赋值运算符
auto t1_copy = t1; 
cout << std::get<0>(t1_copy) << endl; // 打印:zhangsan 
cout << std::get<0>(t1) << endl; // 打印:zhangsan
// 移动赋值运算符
cout << std::get<0>(t1) << endl; // 打印:zhangsan 
auto t1_mv = std::move(t1);
cout << std::get<0>(t1_mv) << endl; // 打印:zhangsan 
cout << std::boolalpha << (std::get<0>(t1) == "") << endl; // 打印:true

make_tuple

// make_tuple 
std::tuple<string, int, vector<double>> t2 = 
				std::make_tuple("lisi", 24, vector<double>({44.0, 45, 46}));
cout << std::get<0>(t2) << ", " << std::get<1>(t2) << ", {"
	<< std::get<2>(t2)[0] << "," << std::get<2>(t2)[1] << "," 
	<< std::get<2>(t2)[2] << "}" << endl;
函数名说明
get(tp)返回第i个元素的引用
typle_size<typleType:>::value返回元组的长度
tuple_element<i,tupleType>::type返回元组第i项的类型

(4)关联容器

A.What

通过键值对(key-valuepair)来组织和访问元素,将红黑树作为底层数据结构,用于维护 键值对集合,并提供高效的元素访问和操作能力,本质是类模板

B.Which

在这里插入图片描述

C.Why

  • 维护映射关系:一个值(也称为数据)与一个唯一的键相关联
  • 快速查找:通过以键作为索引,可以高效地查找、访问和修改相应的值
  • 自动排序:关联容器中的元素通常是自动根据键进行排序的,这样可以保持元素的有序性
  • 唯一性保证:关联容器中的键是唯一的,这意味着每个键只能关联一个值

D.pair

基本使用:导入pair、创建pair对象、调用对象的函数

#include <utility> 
std::pair<string,int> name_age{"赵家的狗",5000};

常见函数: make_pair()

#include <utility> 
std::pair<string,int> name_age{"赵家的狗",5000}; std::pair<string,int> mingDynasty_age("明朝",276); 
string songDynasty="宋朝"; int ageSong=247;
auto songDynasty_age=std::make_pair(songDynasty,ageSong); cout<<name_age.first<<","<<name_age.second<<endl;
cout<<mingDynasty_age.first<<","<<mingDynasty_age.second<<endl; cout<<songDynasty_age.first<<","<<songDynasty_age.second<<endl;

E.map

基本使用:导入库、创建对象、调用对象函数、使用算法对容器元素处理

#include <map>
std::map<int, string> map01;

非成员函数:

  • swap(map01, map02);

成员函数:

成员函数说明
begin() / end()返回第一个(最后一个)元素的迭代器
cbegin() / cend()返回第一个(最后一个)元素的常量迭代器
clear()清除容器中所有元素
contains()检查容器中是否包含具有指定键的元素
emplace()就地构造元素插入到map中
empty()判断容器是否为空
erase()从指定位置移除容器中的元素
get_allocator()返回map对象的副本
lower_bound()返回一个迭代器,迭代器指向键值大于等于指定键值的第一个元素
upper_bound()类比lower_bound()
swap()交换两个map元素

说明:set、multimap、multiset等和map函数差不多,这里就不继续陈列相关函数说明了,值得一提的是无序关联容器

F.unordered_map

在这里插入图片描述

无序容器使用一个哈希函数将元素映射到桶,访问元素时,先计算元素的哈希值,根 据哈希值找到桶,容器将具有一个特定哈希值的所有元素都保存在相同的桶中

桶接口:
在这里插入图片描述
成员函数:

成员函数说明
at查找具有指定键的元素
bucket()获取键值对的桶编号
hash_function()获取存储的哈希函数对象
rehash()重新生成哈希表

说明:其它成员函数类比于map类的成员函数

重载hasher()和eqOp()函数:

在这里插入图片描述
在这里插入图片描述

3、迭代器

(1)What

一种“泛型指针”,也叫“广义指针”,本质是重载了各种操作符的类模板

(2)Why

可以循环访问 C++ 标准库容器中的元素,而不必考虑容器的类型和存储细节

(3)Which(迭代器类型)

A.输出迭代器

输出迭代器说明
ostream_iterator用于将数据写入输出流,例如 std::cout
back_insert_iterator用于在容器的末尾插入元素, std::back_inserter(container)
front_insert_iterator用于在容器的开头插入元素, std::front_inserter(container)
insert_iterator用于在容器的指定位置插入元素, std::inserter(container,position)

ostream_iterator

std::ostream_iterator<int> it_cout(std::cout, " "); 
*it_cout = 100; 
++it_cout; 
*it_cout = 200;
std::cout << std::endl; // 打印:100 200

back_insert_iterator

std::vector<int> years{1894, 1927, 1928, 1935, 1937, 1945, 1949, 1951, 1956, 1959, 1964, 1973, 1978, 1998};
std::back_insert_iterator<std::vector<int>> it_inster_years_back(years); 
*it_inster_years_back = 2001; 
++it_inster_years_back;
*it_inster_years_back = 2008; 
for (auto const &item : years){ std::cout << item << std::endl;} // 打印:1894-2008

B.输入迭代器

输入迭代器说明
istream_iterator用于从输入流(如标准输入 cin)中按顺序读取数据的迭代器
istreambuf_iterator用于从输入流缓冲区中读取字符的迭代器
istream_token_iterator扩展了 istream_iterator,可以使用分隔符将输入流分割成单词或标记。可以使用自定义的分隔符来指定如何划分输入
std::ifstream in_stream2; 
in_stream2.open(sentences_file_path.c_str()); 
if (!in_stream2.is_open())
{
	std::cout << "Open failed!" << std::endl; 
}
std::istream_iterator<string> it_istream(in_stream2); 
std::istream_iterator<string> it_end;
while (it_istream != it_end)
{
	std::cout << *it_istream << std::endl; ++it_istream;
}

C.单向迭代器

一种只能向前遍历容器元素的迭代器,用于访问支持顺序访问的容器(如链表、单 向链表等)

单向迭代器说明
forward_list 迭代器用于遍历 forward_list(单向链表)容器的元素。它只能向前遍历,不支持反向遍历或随机访问
unordered_set 和 unordered_multiset 迭代器它们使用哈希表存储元素,不保证元素的顺序。迭代器按照插入顺序遍历。这些迭代器只支持向前遍历。
unordered_map 和 unordered_multimap 迭代器迭代器按照插入顺序遍历键值对。这些迭代器也只支持向前遍历

D.双向迭代器

双向迭代器说明
list 迭代器它支持双向遍历,可以使用 ++ 和 – 操作符向前或向后遍历元素
set 和 multiset 迭代器它们按照一定的排序规则存储元素,迭代器按照升序遍历
map 和 multimap 迭代器它们存储键值对,并按照键进行排序

E.随机访问迭代器

  • std::vector 的迭代器
  • std::deque 的迭代器
  • std::array 的迭代器
  • std::string 的迭代器

4、适配器

(1)What

标准库中的一种特殊容器类型,是对容器的一种封装:stack、queue、priority_queue
默认情况下:
stack 和 queue 是基于 deque 实现的
priority_queue 是基于 vector 实现的

(2)Why

封装细节,进一步解放程序员对底层代码的操作,使其只需关注业务逻辑

(3)栈适配器

std::stack<int> s;
s.push(1);
s.push(2);
s.push(3);
s.pop();
int iTop = s.top(); // 2

(4)队列适配器

std::queue<int> que;
que.push(1);
que.push(2);
que.push(3);
int iFir = que.front(); // 1
que.pop();
iFir = que.front(); // 2
int iLst = que.back(); // 3

5、算法

(1)What(什么是STL中的算法)

用来处理标准容器的函数模板

(2)Which

<algorithm>:提供了大量通用的算法函数,用于对各种容器中的元素进行操作和处理
<cstdlib>:stdlib.h的 C++版本,提供了动态内存管理、随机数生成、与环境交互、整数算术、搜索、排序、字符串转换以及多字节或宽字符处理等功能
<numeric>:定义了一些基础性的数值算法

(3)<algorithm>

函数名说明
adjacent_find搜索相等或满足指定条件的两个相邻元素
all_of测试所有元素都满足指定条件
binary_search测试有序范围中是否有指定要查找的值
sort对范围内的序列进行排序
find在指定范围内查找指定值
reverse反转指定范围内的元素
count计算指定范围内指定数据出现的次数

说明:由于该库存在大量算法,这里仅对几个常用函数进行介绍,读者在实践中,但凡需要对容器中的数据进行某种处理,就可以查看algorithm库是否存在您所需要的算法

(4)cstdlib

函数名说明
malloc分配指定字节数的内存块,如果内存不够,返回NULL
calloc(num, size)分配num个连续内存空间,每一块大小为size
free(ptr)释放指定内存
atof(const char *ch) | atoi |atol | atoll将char指针转为double、int、long等
srand(uint seed)设置随机数生成器的种子
rand()产生一个范围在0到RAND_MAX(32767)之间的随机整数
char getenv(const charname)返回一个指向环境变量的指针
abort()异常终止一个进程
exit(int state)程序中止执行,返回调用过程。参数state为0表示正常中止,非0表示非正常中止
qsort()对数组进行快速排序
abs() |labs()计算绝对值

(5)numric

函数名说明
accumulate求和
adjacent_difference计算相邻元素之间的差值(后一个减前一个元素)
inner_product对两个序列进行内积运算
partial_sum对指定范围内的元素进行局部求和

6、仿函数

(1)What

一种重载了 operator()函数调用符的类或类模板,行为类似函数

(2)Why(仿函数的作用)

A.可作为排序规则

class StudentScoreRule {
public: 
	bool operator()(Student stu01, Student stu02) 
	{
		return stu01.getScore() > stu02.getScore();
	}
};
int main()
{ 
	std::set<Student, StudentScoreRule> studentSet;
	studentSet.clear();
	Student zs("张三", 23, 168); 
	Student ls("李四", 24, 178); 
	Student ww("王五", 25, 188); 
	Student zl("赵六", 26, 144); 
	Student qq("钱七", 27, 177); 
	Student nb("牛八", 28, 288); 
	studentSet.insert({zs, ls, ww, zl, qq, nb});
	cout << "*****************************************" << endl; 
	for (auto stu : studentSet)
		cout << stu.getName() << "\t" << stu.getAge() << "\t" << stu.getScore() << endl; 
	cout << "*****************************************" << endl;
}

studentSet对象将按照学生的分数进行排序存储

B.作为判别式使用

class Number
{
public:
	int num; 
	Number(int num_) : num(num_) {} 
	Number() { num = 0; }
	bool operator()(int a) {
		return a % this->num == 0;
	}
};

//删除所有能被 2 整除的元素 
std::list<int> tmp_list;
for (int i = 1; i < 20; ++i) 
	tmp_list.emplace_back(i); 
auto pos = std::remove_if(tmp_list.begin(), tmp_list.end(), Number(2));
tmp_list.erase(pos, tmp_list.end());

C.可携带更多信息,拥有多种内部状态

class mySequence
{
private:
	int val; 
public:
	mySequence(int val_) : val(val_) {} 
	int operator()() {
		return this->val++;
	}
};
std::list<int> list01; 
std::generate_n(std::back_inserter(list01), 9, mySequence(1));

D.作为算法 for_each 的返回值

class Average {
private:
	int count_n; 
	double sum; public:
	Average(int val = 0, int count_n_ = 0) : sum(val), count_n(count_n_) {}
	void operator()(double x) {
		++count_n; 
		sum += x; 
	}
	double getAveValue() { return sum / count_n; }
}; 
std::set<double> money{10.88, 12.88, 14, 13, 16.88, 20, 21.98}; 
Average res = std::for_each(money.begin(), money.end(), Average()); 
cout << res.getAveValue() << endl;
//方法 2 cout << "**********************************************" << endl; 
double sum = 0;
std::for_each(money.rbegin(), money.rend(), [&sum](double x){ sum += x; }); 
cout << sum / money.size() << endl;

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

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

相关文章

世界智能产业博览会开幕 - 天空卫士汽车行业方案入选优秀案例

6月20日&#xff0c;以“智行天下、能动未来”为主题的2024世界智能产业博览会在国家会展中心&#xff08;天津&#xff09;开幕。主席向博览会致贺信并指出&#xff1a;中国高度重视人工智能发展&#xff0c;积极推动互联网、大数据、人工智能和实体经济深度融合&#xff0c;培…

网页设计入门:必备学习技巧和方法总结

网页设计是一个创造性和具有挑战性的设计领域。学习网页设计不仅需要审美能力&#xff0c;还需要设计师有扎实的专业知识来完成各种类型的网页设计项目。要想在网页设计领域脱颖而出&#xff0c;需要不断学习相关知识&#xff0c;提高专业技能。本文将分享网页设计的学习技巧和…

【原理】随机森林模型是怎么训练的

本文来自《老饼讲解-BP神经网络》https://www.bbbdata.com/ 目录 一、随机森林简介二、随机森林训练原理2.1. 随机森林的训练流程2.2. 随机森林训练的核心代码 用过随机森林的朋友都知道&#xff0c;随机森林是集成决策的一个经典代表&#xff0c;它通过训练多棵决策树&#xf…

未公开 GeoServer开源服务器wfs远程命令执行漏洞 已复现(CVE-2024-36401)

0x01 阅读须知 技术文章仅供参考&#xff0c;此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等&#xff08;包括但不限于&#xff09;进行检测或维护参考&#xff0c;未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成…

【面试系列】UI设计师高频面试题及详细解答

欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;欢迎订阅相关专栏&#xff1a; ⭐️ 全网最全IT互联网公司面试宝典&#xff1a;收集整理全网各大IT互联网公司技术、项目、HR面试真题. ⭐️ AIGC时代的创新与未来&#xff1a;详细讲解AIGC的概念、核心技术、…

bootloader原理介绍

bootloader解析 bootloader的引出 不知道你有没有想过这样一个问题&#xff0c;当你按下电源开关的那一瞬间&#xff0c;第一行代码是如何在芯片上运行起来的呢&#xff1f;我们都知道嵌入式软件代码&#xff0c;是需要通过一定的方式&#xff0c;烧录在硬件芯片中&#xff0c…

ubuntu安装搜狗\谷歌输入法

目录 1 安装搜狗输入法 1.1 安装Fcitx输入框架 1.2 下载搜狗输入法安装包 1.3 安装搜狗输入法 1.4 打开配置 1.5 选择fcitx 1.6 重启系统 1.7 配置输入法 1.8 添加搜狗输入法 1.9 使用 2 安装谷歌输入法 2.1 下载fcitx-googlepinyin 2.2 选择fcitx 2.3 重启系统 …

hive小练习 拓展

基于hive表小练习-CSDN博客的拓展 -- 1. 查询没有参与任意一门考试的学生姓名 LEFT JOIN操作时&#xff0c;数据库系统会从左表&#xff08;即LEFT JOIN关键字左边的表&#xff09;返回所有的行&#xff0c; 即使在右表&#xff08;即LEFT JOIN关键字右边的表&#xff09…

Python便捷数据处理库之Baisou使用详解

概要 Baisou,中文译名为“便捷数据处理库”,是一个基于Python的库,旨在简化数据处理和分析的过程。它拥有丰富的数据类型和函数,可以帮助开发者轻松地处理数据,进行统计分析,以及实现复杂的数据转换。Baisou的设计理念是“简单、高效、易用”,让开发者能够更加专注于业…

无线领夹麦克风哪个牌子好,口碑最好的麦克风品牌良心推荐

在自媒体行业迅速发展的背景下&#xff0c;无线领夹麦克风已成为提升音频质量的重要工具。它能够在多种环境中保持语音的清晰度&#xff0c;有效增强创作效率和作品的专业性。市场上有许多无线麦克风产品&#xff0c;但并非所有都兼具高性能与合理价格。基于我的个人使用经验&a…

Firewalld 防火墙基础

Firewalld 防火墙基础 一、Firewalld概述firewalld 简介firewalld 和 iptables 的关系firewalld 与 iptables service 的区别 二、Firewalld 网络区域区域介绍Firewalld数据处理流程 三、Firewalld 防火墙的配置方法firewall-config 图形工具“区域”选项卡“服务”选项卡改变防…

5.3.3、二维数组案例-考试成绩统计

代码 #include <iostream> using namespace std; #include <string>int main() {//二维数组案例-考试成绩统计//1、创建二维数组int scores[3][3] {{100,100,100},{90,50,100},{60,70,80},};string names[3] { "张三","李四","王五&quo…

基于微服务智能推荐健康生活交流平台的设计与实现(SpringCloud SpringBoot)+文档

&#x1f497;博主介绍&#x1f497;&#xff1a;✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示&#xff1a;文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐…

MATLAB—— 流程语句(1)

一、if elseif else end 语句 例子 x 88; % x表示成绩 if x>90 && x < 100 dj 1; % 等级为1级 elseif x>80 && x < 90 dj 2; % 等级为2级 elseif x>60 && x < 80 dj 3; % 等级为…

信息打点web篇---前端js打点

前言 欢迎来到我的博客 个人主页:北岭敲键盘的荒漠猫-CSDN博客 本文主要整理前端js代码的打点思路 本文只为学习安全使用&#xff0c;切勿用于非法用途。 一切未授权的渗透行为都是违法的。 前端js打点概念与目的 javascript文件属于前端语言&#xff0c;也就是说他的代码都…

AI商品图生成定制外包公司

&#x1f308; 深度剖析AI商品图生成定制外包公司 —— 触站AI&#xff0c;智能图像的魔法师 &#x1f9d9;‍♂️ &#x1f389;触站AI&#xff0c;以技术创新引领行业变革 &#x1f389;在这个AI技术飞速发展的时代&#xff0c;触站AI以其专业和专注&#xff0c;成为了深圳乃…

容嬷嬷给紫薇过生日:鬼畜搭台,AI带货

刚入7月&#xff0c;短视频平台已被AI视频续写占领。 类似于紫薇在地牢里被容嬷嬷喂西瓜、喂鸡翅、喂蛋糕。张学友在《旺角卡门》的经典镜头突然给你微笑、嘟嘴、甚至祝你生日快乐。甚至&#xff0c;还有吴京从打斗戏变成亲吻戏。 在AI续写的短视频里&#xff0c;你永远也想象…

Python小练习05

一 绘制如下图形。 #Q1 import turtle as t def draw(n):for i in range(n):t.left(30)t.fd(100)t.left(120)t.fd(100)t.left(120)t.fd(100)t.left(120)t.fd(100)t.right(90) t.penup() t.goto(-150,20) t.speed(0) t.pendown() t.pencolor("red") t.pensize(5) draw…

权限控制权限控制权限控制权限控制权限控制

1.权限的分类 视频学习&#xff1a;https://www.bilibili.com/video/BV15Q4y1K79c/?spm_id_from333.337.search-card.all.click&vd_source386b4f5aae076490e1ad9b863a467f37 1.1 后端权限 1. 后端如何知道该请求是哪个用户发过来的 可以根据 cookie、session、token&a…

5.2.3、冒泡排序

代码 #include <iostream> using namespace std;int main() {//冒泡排序升序int arr[9] { 4,2,8,0,5,7,1,3,9 };cout << "排序前&#xff1a;" << endl;for (int i 0; i < 9; i){cout << arr[i] << " ";}cout <<…