STL容器及其算法

C++ 標準庫容器詳解:特性、用法與場景選型

容器是 C++ 標準庫(STL)的核心組件,用于存儲和管理數據。不同容器因底層實現不同,在性能、功能和適用場景上差異顯著。本文系統梳理vectorlistsetmap等常用容器,從核心特性、API 用法到場景選型進行全方位解析,幫助開發者精準選擇合適的容器。

一、容器分類與核心差異概覽

C++ 容器按功能可分為序列式容器(側重元素順序)和關聯式容器(側重元素查找),核心差異如下表:

容器類型所屬類別底層實現核心特性核心操作復雜度(插入 / 刪除 / 查找)
vector序列式動態數組內存連續,支持隨機訪問,尾部操作高效尾部增刪 O (1);中間增刪 O (n);查找 O (n)
list序列式雙向鏈表內存不連續,不支持隨機訪問,任意位置增刪高效已知位置增刪 O (1);查找 O (n)
set關聯式(無序)紅黑樹元素唯一,自動按 key 排序,支持范圍查詢增刪查 O (log n)
unordered_set關聯式(無序)哈希表元素唯一,無序,查找效率高(平均)增刪查平均 O (1);最壞 O (n)
map關聯式(有序)紅黑樹鍵值對存儲,key 唯一且排序,支持按 key 索引增刪查 O (log n)
unordered_map關聯式(無序)哈希表鍵值對存儲,key 唯一,無序,查找效率高(平均)增刪查平均 O (1);最壞 O (n)

二、序列式容器詳解

1.?vector:動態數組(最常用序列容器)

核心特性
  • 底層實現:基于動態數組,內存連續(同數組),但支持自動擴容。
  • 關鍵優勢
    • 支持隨機訪問(通過[]at()),時間復雜度 O (1);
    • 尾部插入 / 刪除(push_back/pop_back)效率極高,O (1);
    • 內存局部性好,緩存命中率高(因內存連續)。
  • 局限性
    • 中間 / 頭部插入 / 刪除需移動大量元素,O (n);
    • 擴容時可能觸發內存重分配(通常擴容為原容量 2 倍),導致性能波動。
常用 API 與示例
#include <vector>
#include <iostream>
using namespace std;int main() {// 1. 初始化(三種常用方式)vector<int> vec1; // 空容器vector<int> vec2(5, 10); // 5個元素,均為10vector<int> vec3 = {1, 2, 3, 4, 5}; // 初始化列表// 2. 插入元素vec1.push_back(6); // 尾部插入(O(1))vec1.insert(vec1.begin() + 1, 8); // 在索引1處插入(O(n),需移動元素)// 3. 訪問元素(兩種方式)cout << vec3[2] << endl; // 下標訪問(無越界檢查,快)cout << vec3.at(3) << endl; // at()訪問(有越界檢查,安全)cout << "首元素:" << vec3.front() << ",尾元素:" << vec3.back() << endl;// 4. 遍歷(迭代器/范圍for)for (auto it = vec3.begin(); it != vec3.end(); ++it) {cout << *it << " ";}// 范圍for更簡潔(C++11+)for (int num : vec3) { cout << num << " "; }// 5. 修改與刪除vec3[0] = 100; // 直接修改vec1.pop_back(); // 刪除尾部元素(O(1))vec3.erase(vec3.begin() + 2); // 刪除索引2處元素(O(n))// 6. 容量管理(關鍵!)cout << "當前大小:" << vec2.size() // 元素個數<< ",容量:" << vec2.capacity() << endl; // 已分配內存可容納的元素數vec2.reserve(10); // 預分配容量(避免頻繁擴容)vec2.resize(3); // 調整大小(多余元素被截斷,新增元素為默認值)vec1.clear(); // 清空元素(size=0,但capacity不變)return 0;
}
典型場景
  • 需頻繁隨機訪問元素(如存儲數組、矩陣、日志數據);
  • 元素主要在尾部增刪(如批量數據收集、緩沖區);
  • 需與 C 語言數組兼容(因內存連續,可通過data()獲取原始指針)。

2.?list:雙向鏈表(高效增刪的序列容器)

核心特性
  • 底層實現雙向鏈表,每個節點包含數據域和前后指針,內存不連續。
  • 關鍵優勢
    • 任意位置(已知迭代器)插入 / 刪除效率極高,O (1)(無需移動元素,僅修改指針);
    • 無擴容開銷(節點動態分配),內存使用更靈活。
  • 局限性
    • 不支持隨機訪問(訪問第 n 個元素需從頭遍歷),時間復雜度 O (n);
    • 內存開銷大(每個節點額外存儲兩個指針);
    • 緩存命中率低(內存不連續)。
常用 API 與示例
#include <list>
#include <iostream>int main() {// 1. 初始化list<int> list1;list<int> list2(4, 20); // 4個元素,均為20list<int> list3 = {10, 20, 30, 40};// 2. 插入元素(頭部/尾部/中間)list1.push_back(5); // 尾部插入(O(1))list1.push_front(3); // 頭部插入(O(1))auto it = list3.begin(); ++it; // 指向第二個元素(20)list3.insert(it, 25); // 在20和30之間插入25(O(1),已知位置)// 3. 訪問元素(僅支持首尾直接訪問)cout << "首元素:" << list3.front() << ",尾元素:" << list3.back() << endl;// 訪問中間元素需遍歷it = list3.begin();advance(it, 2); // 移動迭代器到第3個元素(25)cout << "第3個元素:" << *it << endl;// 4. 遍歷(僅迭代器/范圍for)for (int num : list3) { cout << num << " "; }// 5. 特殊操作(鏈表特有)list3.reverse(); // 反轉鏈表(O(n),僅修改指針)list3.sort(); // 排序(O(n log n),鏈表自帶排序,無需轉換為vector)// 6. 刪除元素list1.pop_back(); // 尾部刪除(O(1))list3.pop_front(); // 頭部刪除(O(1))it = list3.begin(); ++it;list3.erase(it); // 刪除指定位置元素(O(1),已知位置)return 0;
}
典型場景
  • 頻繁在中間位置增刪元素(如實現鏈表、隊列、棧的變種);
  • 數據量不確定,且需避免擴容開銷(如實時數據采集,元素動態增減);
  • 需要高效拆分 / 合并鏈表(splice()方法,O (1) 實現鏈表拼接)。

三、關聯式容器詳解

1.?setunordered_set:集合(元素去重與查找)

核心特性對比
特性set(有序集合)unordered_set(無序集合)
底層實現紅黑樹(平衡二叉搜索樹)哈希表(鏈地址法解決沖突)
有序性元素自動按升序排列(可自定義)無序(按哈希值存儲)
唯一性元素不可重復(重復插入被忽略)同左
查找效率O (log n)(穩定)平均 O (1),最壞 O (n)(依賴哈希函數)
迭代器穩定性插入 / 刪除不失效(除被刪元素)插入可能觸發重哈希,迭代器失效
內存開銷較低(紅黑樹結構緊湊)較高(哈希表需預留空間)
常用 API 與示例(以set為例)
#include <set>
#include <iostream>
#include <functional> // 用于自定義排序
using namespace std;
int main() {// 1. 初始化(默認升序)set<int> set1;// 自定義排序(降序)set<int,greater<int>> set2;// 2. 插入元素(自動去重)set1.insert(3);set1.insert(1);set1.insert(2);set1.insert(2); // 重復元素,插入無效set2.insert({5, 3, 7}); // 初始化列表插入// 3. 查找元素(核心操作)auto it1 = set1.find(2); // 查找值為2的元素if (it1 != set1.end()) {cout << "找到元素:" << *it1 << endl;}// 判斷元素是否存在(count()返回0或1)if (set1.count(3)) { cout << "元素3存在" << endl; }// 4. 遍歷(有序性體現)cout << "set1(升序):";for (int num : set1) { cout << num << " "; } // 輸出:1 2 3cout << "\nset2(降序):";for (int num : set2) { cout << num << " "; } // 輸出:7 5 3// 5. 刪除元素set1.erase(1); // 按值刪除(O(log n))set2.erase(set2.begin()); // 按迭代器刪除(O(1))return 0;
}
典型場景
  • set:需去重且保持有序(如排行榜、區間統計,支持lower_bound/upper_bound范圍查詢);
  • unordered_set:僅需去重,追求極致查找效率(如緩存校驗、數據去重驗證)。

2.?mapunordered_map:鍵值對(關聯查詢)

核心特性對比
特性map(有序鍵值對)unordered_map(無序鍵值對)
底層實現紅黑樹哈希表
有序性按 key 升序排列(可自定義)無序
鍵唯一性key 不可重復(重復插入無效)同左
訪問方式通過 key 訪問 value同左
查找效率O(log n)平均 O (1),最壞 O (n)
典型用途有序關聯查詢(如字典、配置表)高效鍵值映射(如緩存、索引)
常用 API 與示例(以unordered_map為例)

cpp

運行

#include <unordered_map>
#include <iostream>int main() {// 1. 初始化(鍵為int,值為string)unordered_map<int, string> umap;// 2. 插入鍵值對(三種方式)umap.insert({1, "one"}); // 插入pair(重復key無效)umap[2] = "two"; // []運算符(重復key會覆蓋)umap.emplace(3, "three"); // 直接構造(效率更高)// 3. 訪問value(兩種方式)cout << umap[2] <<endl; // []訪問(無key則插入默認值)try {cout << umap.at(3) << endl; // at()訪問(無key拋異常,更安全)} catch (const out_of_range& e) {cout << "key不存在" << endl;}// 4. 查找key(核心操作)auto it = umap.find(1); // 查找key=1if (it != umap.end()) {cout << "key:" << it->first << ",value:" << it->second << endl;}// 5. 遍歷for (const auto& pair : umap) {cout << pair.first << " → " << pair.second << " ";}// 6. 刪除元素umap.erase(2); // 按key刪除it = umap.find(3);if (it != umap.end()) {umap.erase(it); // 按迭代器刪除}return 0;
}
典型場景
  • map:需按 key 排序的鍵值對(如按 ID 排序的用戶信息、區間查詢配置);
  • unordered_map:高頻鍵值查詢(如數據庫索引、緩存映射,優先考慮查找速度)。

四、容器選型決策指南

選擇容器時需結合操作類型(增刪查為主?隨機訪問?)、數據特性(是否有序?是否重復?)和性能需求(時間 / 內存優先),決策流程如下:

  1. 是否需要鍵值對關聯?

    • 是 → 選map(有序)或unordered_map(無序);
    • 否 → 進入下一步。
  2. 是否需要去重?

    • 是 → 選set(有序)或unordered_set(無序);
    • 否 → 進入下一步(序列容器)。
  3. 序列容器核心需求?

    • 頻繁隨機訪問 →?vector
    • 頻繁中間增刪 →?list
    • 頭尾增刪頻繁且需隨機訪問 →?deque(雙端隊列,未詳細展開)。

五、容器算法

C++ 標準庫的?<algorithm>?頭文件提供了大量實用算法,涵蓋排序、查找、修改、數值計算等場景。以下是常用算法的分類總結及例程:

5.1 排序與順序相關算法

1.?sort?- 快速排序(不穩定)

對范圍元素排序,平均復雜度 O (n log n)

#include <algorithm>
#include <vector>
#include <iostream>int main() {std::vector<int> v = {3, 1, 4, 1, 5};std::sort(v.begin(), v.end()); // 升序// 輸出:1 1 3 4 5// 自定義降序std::sort(v.begin(), v.end(), [](int a, int b) { return a > b; });// 輸出:5 4 3 1 1return 0;
}
2.?stable_sort?- 穩定排序

保持相等元素的原始相對順序

std::vector<std::pair<int, int>> v = {{2,1}, {1,2}, {2,3}};
std::stable_sort(v.begin(), v.end()); 
// 結果:{1,2}, {2,1}, {2,3}(兩個2的相對順序不變)
3.?partial_sort?- 部分排序

只保證前 k 個元素有序(最小的 k 個)

std::vector<int> v = {5, 3, 1, 4, 2};
std::partial_sort(v.begin(), v.begin()+3, v.end());
// 結果:1 2 3 5 4(前3個為最小且有序)
4.?nth_element?- 定位第 n 大元素

使第 n 個元素處于排序后的正確位置

std::vector<int> v = {5, 3, 1, 4, 2};
std::nth_element(v.begin(), v.begin()+2, v.end());
// 結果:2 1 3 5 4(3是第3小元素,左側≤3,右側≥3)

5.2? 查找算法

1.?find?- 查找元素

返回首個匹配元素的迭代器

std::vector<int> v = {1, 2, 3, 4, 5};
auto it = std::find(v.begin(), v.end(), 3);
if (it != v.end()) {std::cout << "找到元素:" << *it; // 輸出:3
}
2.?find_if?- 條件查找

通過謂詞查找元素

// 查找第一個偶數
auto it = std::find_if(v.begin(), v.end(), [](int x) { return x % 2 == 0; });
3.?binary_search?- 二分查找

已排序范圍中查找(返回 bool)

std::vector<int> v = {1, 3, 5, 7};
bool exists = std::binary_search(v.begin(), v.end(), 5); // true
4.?lower_bound?/?upper_bound
  • lower_bound:返回首個 ≥ 目標值的迭代器
  • upper_bound:返回首個 > 目標值的迭代器
std::vector<int> v = {1, 3, 3, 5};
auto lb = std::lower_bound(v.begin(), v.end(), 3); // 指向第一個3
auto ub = std::upper_bound(v.begin(), v.end(), 3); // 指向5
int count = ub - lb; // 3的個數:2

5.3 容器修改算法

1.?copy?- 復制元素
std::vector<int> src = {1, 2, 3};
std::vector<int> dest(3);
std::copy(src.begin(), src.end(), dest.begin()); // dest = {1,2,3}
2.?swap?- 交換元素
int a = 1, b = 2;
std::swap(a, b); // a=2, b=1std::vector<int> v1 = {1,2}, v2 = {3,4};
std::swap(v1, v2); // 交換整個容器
3.?reverse?- 反轉范圍
std::vector<int> v = {1, 2, 3};
std::reverse(v.begin(), v.end()); // {3,2,1}
4.?remove?- 移除元素(邏輯刪除)
std::vector<int> v = {1, 2, 3, 2, 4};
// 邏輯刪除所有2(返回新結尾迭代器)
auto last = std::remove(v.begin(), v.end(), 2);
v.erase(last, v.end()); // 物理刪除,結果:{1,3,4}
5.?unique?- 移除連續重復元素
std::vector<int> v = {1, 2, 2, 3, 3, 3};
std::sort(v.begin(), v.end()); // 先排序
auto last = std::unique(v.begin(), v.end());
v.erase(last, v.end()); // 結果:{1,2,3}

5.4 數值與集合算法

1.?accumulate?- 累加(需?<numeric>?頭文件)
#include <numeric>
std::vector<int> v = {1, 2, 3, 4};
int sum = std::accumulate(v.begin(), v.end(), 0); // 0+1+2+3+4=10// 計算乘積
int product = std::accumulate(v.begin(), v.end(), 1, std::multiplies<int>());
2.?count?/?count_if?- 計數
std::vector<int> v = {1, 2, 2, 3};
int cnt = std::count(v.begin(), v.end(), 2); // 2的個數:2// 計數偶數
int even_cnt = std::count_if(v.begin(), v.end(), [](int x) { return x%2==0; });
3.?min_element?/?max_element?- 查找最值
std::vector<int> v = {3, 1, 4};
auto min_it = std::min_element(v.begin(), v.end()); // 指向1
auto max_it = std::max_element(v.begin(), v.end()); // 指向4
4.?set_intersection?- 求交集(需已排序)
std::vector<int> a = {1, 2, 3, 4};
std::vector<int> b = {3, 4, 5, 6};
std::vector<int> res;
std::set_intersection(a.begin(), a.end(), b.begin(), b.end(), std::back_inserter(res));
// res = {3,4}

5.5? 編程練習

#include <algorithm>
#include <vector>
#include <iostream>
#include <numeric>  // 用于accumulateusing namespace std;int main() {// 一、排序與順序相關算法{// 1. sort - 快速排序(不穩定)vector<int> v1 = {3, 1, 4, 1, 5};sort(v1.begin(), v1.end());  // 升序cout << "sort升序: ";for (int num : v1) cout << num << " ";  // 1 1 3 4 5cout << endl;// 自定義降序sort(v1.begin(), v1.end(), [](int a, int b) { return a > b; });cout << "sort降序: ";for (int num : v1) cout << num << " ";  // 5 4 3 1 1cout << endl;// 2. stable_sort - 穩定排序(保留相等元素相對順序)vector<pair<int, int>> v2 = {{2,1}, {1,2}, {2,3}};stable_sort(v2.begin(), v2.end());cout << "stable_sort結果: ";for (auto p : v2) cout << "{" << p.first << "," << p.second << "} ";  // {1,2} {2,1} {2,3}cout << endl;// 3. partial_sort - 部分排序(前k個元素有序)vector<int> v3 = {5, 3, 1, 4, 2};partial_sort(v3.begin(), v3.begin()+3, v3.end());cout << "partial_sort前3個: ";for (int num : v3) cout << num << " ";  // 1 2 3 5 4cout << endl;// 4. nth_element - 定位第n個元素vector<int> v4 = {5, 3, 1, 4, 2};nth_element(v4.begin(), v4.begin()+2, v4.end());  // 第3小元素cout << "nth_element結果: ";for (int num : v4) cout << num << " ";  // 2 1 3 5 4(3在正確位置)cout << endl;}// 二、查找算法{vector<int> v = {1, 2, 3, 4, 5};// 1. find - 查找元素auto it1 = find(v.begin(), v.end(), 3);if (it1 != v.end()) cout << "find找到: " << *it1 << endl;  // 3// 2. find_if - 條件查找auto it2 = find_if(v.begin(), v.end(), [](int x) { return x % 2 == 0; });if (it2 != v.end()) cout << "find_if找到首個偶數: " << *it2 << endl;  // 2// 3. binary_search - 二分查找(需已排序)bool exists = binary_search(v.begin(), v.end(), 5);cout << "binary_search查找5: " << (exists ? "存在" : "不存在") << endl;  // 存在// 4. lower_bound/upper_boundvector<int> v_sorted = {1, 3, 3, 5};auto lb = lower_bound(v_sorted.begin(), v_sorted.end(), 3);  // 首個>=3auto ub = upper_bound(v_sorted.begin(), v_sorted.end(), 3);  // 首個>3cout << "3的個數: " << (ub - lb) << endl;  // 2}// 三、容器修改算法{// 1. copy - 復制元素vector<int> src = {1, 2, 3};vector<int> dest(3);copy(src.begin(), src.end(), dest.begin());cout << "copy結果: ";for (int num : dest) cout << num << " ";  // 1 2 3cout << endl;// 2. swap - 交換int a = 1, b = 2;swap(a, b);cout << "swap后: a=" << a << ", b=" << b << endl;  // a=2, b=1// 3. reverse - 反轉vector<int> v_rev = {1, 2, 3};reverse(v_rev.begin(), v_rev.end());cout << "reverse結果: ";for (int num : v_rev) cout << num << " ";  // 3 2 1cout << endl;// 4. remove - 移除元素(需配合erase)vector<int> v_rem = {1, 2, 3, 2, 4};auto last = remove(v_rem.begin(), v_rem.end(), 2);  // 邏輯刪除v_rem.erase(last, v_rem.end());  // 物理刪除cout << "remove后: ";for (int num : v_rem) cout << num << " ";  // 1 3 4cout << endl;// 5. unique - 去重(需先排序)vector<int> v_uni = {1, 2, 2, 3, 3, 3};sort(v_uni.begin(), v_uni.end());auto last_uni = unique(v_uni.begin(), v_uni.end());v_uni.erase(last_uni, v_uni.end());cout << "unique后: ";for (int num : v_uni) cout << num << " ";  // 1 2 3cout << endl;}// 四、數值與集合算法{vector<int> v = {1, 2, 3, 4};// 1. accumulate - 累加/累乘int sum = accumulate(v.begin(), v.end(), 0);  // 初始值0cout << "累加和: " << sum << endl;  // 10int product = accumulate(v.begin(), v.end(), 1, multiplies<int>());cout << "累乘積: " << product << endl;  // 24// 2. count/count_if - 計數vector<int> v_cnt = {1, 2, 2, 3};int cnt = count(v_cnt.begin(), v_cnt.end(), 2);cout << "數字2的個數: " << cnt << endl;  // 2int even_cnt = count_if(v_cnt.begin(), v_cnt.end(), [](int x) { return x%2 == 0; });cout << "偶數個數: " << even_cnt << endl;  // 2// 3. min_element/max_element - 最值vector<int> v_minmax = {3, 1, 4};auto min_it = min_element(v_minmax.begin(), v_minmax.end());auto max_it = max_element(v_minmax.begin(), v_minmax.end());cout << "最小值: " << *min_it << ", 最大值: " << *max_it << endl;  // 1,4// 4. set_intersection - 交集(需已排序)vector<int> a = {1, 2, 3, 4};vector<int> b = {3, 4, 5, 6};vector<int> res;set_intersection(a.begin(), a.end(), b.begin(), b.end(), back_inserter(res));cout << "交集: ";for (int num : res) cout << num << " ";  // 3 4cout << endl;}return 0;
}

六 、算法使用要點

  1. 算法通常接受迭代器范圍?[first, last)(左閉右開)
  2. 排序相關算法要求容器支持隨機訪問迭代器(如?vectorarray
  3. 二分查找類算法要求范圍已排序
  4. 自定義謂詞需滿足 "嚴格弱序" 規則,避免邏輯錯誤

這些算法大幅簡化了常見操作,合理使用可提高代碼效率和可讀性。

總結

C++ 容器的設計各有側重:vector以連續內存和隨機訪問為核心,list以高效增刪為優勢,set/map提供有序性和穩定查找,unordered_*系列則追求極致查詢效率。理解底層實現是掌握容器的關鍵 —— 紅黑樹帶來有序性和穩定性能,哈希表帶來平均 O (1) 的效率,動態數組平衡了訪問與增刪成本。實際開發中,需根據具體場景的操作頻率和性能需求,選擇最適合的容器,才能寫出高效、易維護的代碼。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/93201.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/93201.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/93201.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

MySQL ZIP安裝教程:從解壓到啟動

金金金上線&#xff01; 話不多&#xff0c;只講你能聽懂的前端知識 前言 我這里不能下載安裝程序的mysql&#xff0c;由于電腦安全限制&#xff0c;安裝時會彈出需要管理員賬號密碼權限&#xff0c;此路行不通&#xff0c;所以琢磨著免安裝版本怎么個流程&#xff0c;好&#…

p2p打洞

p2p網絡穿透庫,它的C++版本目前只支持linux,不支持win,它最新版本的穿透用的tcp,老版本支持tcp/udp: https://libp2p.io/ P2P-udp的穿透教程: https://edu.51cto.com/lesson/731596.html 目前打洞機制最好的庫是webrtc,其次是libnice,它是輕量級的專門打洞的庫。 libni…

『“無恙心寬”,梗痛不常』——愛上古中醫(12)(健康生活是coder抒寫優質代碼的前提條件——《黃帝內經》伴讀學習紀要)

養心護心氣血通&#xff0c;無痛無梗全身松。 筆記模板由python腳本于2025-08-10 15:54:46創建&#xff0c;本篇筆記適合至少通曉一門語言&#xff0c;熟悉基本編程范式的coder翻閱。 學習的細節是歡悅的歷程 博客的核心價值&#xff1a;在于輸出思考與經驗&#xff0c;而不僅僅…

Spark 運行流程核心組件(一)作業提交

1、Job啟動流程1、Client觸發 SparkContext 初始化 2、SparkContext 向 Master 注冊應用 3、Master 調度 Worker 啟動 Executor 4、Worker 進程啟動 Executor 5、DAGScheduler 將作業分解為 Stage&#xff1a; 6、TaskScheduler 分配 Task 到 Executor 2、核心組件組件職責Spar…

MySQL 臨時表與復制表

一、MySQL 臨時表臨時表是會話級別的臨時數據載體&#xff0c;其設計初衷是為了滿足短期數據處理需求&#xff0c;以下從技術細節展開說明。&#xff08;一&#xff09;核心特性拓展1.生命周期與會話綁定會話結束的判定&#xff1a;包括正常斷開連接&#xff08;exit/quit&…

從配置到調試:WinCC與S7-1200/200SMT無線Modbus TCP通訊方案

測試設備與參數l 西門子PLC型號&#xff1a;S7-1200 1臺l 西門子PLC型號&#xff1a;S7-200Smart 1臺l 上位機&#xff1a;WinCC7.4 1臺l 無線通訊終端——DTD418MB 3塊l 主從關系&#xff1a;1主2從l 通訊接口&#xff1a;RJ45接口l 供電&#xff1a;12-24VDCl 通訊協議&a…

Android沉浸式全屏顯示與隱藏導航欄的實現

1. 總體流程以下是實現沉浸式全屏顯示和隱藏導航欄的流程&#xff1a;步驟描述步驟1創建一個新的Android項目步驟2在布局文件中定義需要展示的界面步驟3在Activity中設置沉浸式全屏顯示步驟4處理系統UI的顯示與隱藏步驟5運行應用并測試效果2. 詳細步驟步驟1&#xff1a;創建一個…

EN 62368消費電子、信息技術設備和辦公設備安全要求標準

EN 62368認證標準是一項全球性的電子產品安全標準&#xff0c;用于評估和認證消費電子、信息技術設備和辦公設備的安全性。該標準由國際電工委員會(IEC)制定&#xff0c;取代了傳統的EN60065和EN 60950兩個標準&#xff0c;成為國際電子產品安全領域的新指導。IEC /EN 62368-1是…

【unity實戰】使用Splines+DOTween制作彎曲手牌和抽牌動畫效果

最終效果 文章目錄最終效果前言實戰1、Splines的使用2、繪制樣條線3、DOTween安裝和使用4、基于樣條曲線&#xff08;Spline&#xff09;的手牌管理系統4.1 代碼實現4.2 解釋&#xff1a;&#xff08;1&#xff09;計算第一張卡牌的位置&#xff08;居中排列&#xff09;&#…

Flask模板注入梳理

從模板開始介紹&#xff1a;Flask中有許多不同功能的模板&#xff0c;他們之間是相互隔離的地帶&#xff0c;可供引入和使用。Flask中的模塊&#xff1a;flask 主模塊&#xff1a;包含框架的核心類和函數&#xff0c;如 Flask&#xff08;應用實例&#xff09;、request&#x…

企業級的即時通訊平臺怎么保護敏感行業通訊安全?

聊天記錄存在第三方服務器、敏感文件被誤發至外部群組、離職員工仍能查看歷史消息.對于金融、醫療、政務等對數據安全高度敏感的行業而言&#xff0c;“溝通效率與”信息安全”的矛盾&#xff0c;從未像今天這樣尖銳。企業即時通訊怎么保護敏感行業通訊安全&#xff1f;這個問題…

Java Spring框架最新版本及發展史詳解(截至2025年8月)-優雅草卓伊凡

Java Spring框架最新版本及發展史詳解&#xff08;截至2025年8月&#xff09;-優雅草卓伊凡引言今天有個新項目 客戶問我為什么不用spring 4版本&#xff0c;卓伊凡我今天剛做完項目方案&#xff0c;我被客戶這一句問了有點愣住&#xff0c;Java Spring框架最新版本及發展史詳解…

Android實現Glide/Coil樣式圖/視頻加載框架,Kotlin

Android實現Glide/Coil樣式圖/視頻加載框架&#xff0c;Kotlin <uses-permission android:name"android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name"android.permission.READ_EXTERNAL_STORAGE" /><uses-permiss…

【k8s】pvc 配置的兩種方式volumeClaimTemplates 和 PersistentVolumeClaim

pvc配置實例 實例1在Deployment中配置 template:xxxxxxvolumeClaimTemplates:- metadata:name: dataspec:accessModes:- ReadWriteOnceresources:requests:storage: 1GistorageClassName: nfsdev-storageclass (創建好的storageClassName)實例2#先創建一個pvc 然后在 Deploym…

Logistic Loss Function|邏輯回歸代價函數

----------------------------------------------------------------------------------------------- 這是我在我的網站中截取的文章&#xff0c;有更多的文章歡迎來訪問我自己的博客網站rn.berlinlian.cn&#xff0c;這里還有很多有關計算機的知識&#xff0c;歡迎進行留言或…

計算機網絡技術-知識篇(Day.1)

一、網絡概述 1、網絡的概念 兩個不在同一地理位置的主機&#xff0c;通過傳輸介質和通信協議&#xff0c;實現通信和資源共享。 2、網絡發展史 第一階段&#xff08;20世紀60年代&#xff09; 標志性事件&#xff1a;ARPANET的誕生關鍵技術&#xff1a;分組交換技術 第二…

工業元宇宙:邁向星辰大海的“玄奘之路”

一、從認知革命到工業革命&#xff1a;文明躍遷的底層邏輯1.1 認知革命&#xff1a;人類協作的基石時間線&#xff1a;約7萬年前&#xff0c;智人通過語言和想象力構建共同虛擬現實&#xff0c;形成部落協作模式。核心突破&#xff1a;虛構能力&#xff1a;創造神、國家、法律等…

9. React組件生命周期

2. React組件生命周期 2.1. 認識生命周期 2.1.1. 很多事物都有從創建到銷毀的整個過程&#xff0c;這個過程稱之為生命周期&#xff1b;2.1.2. React組件也有自己的生命周期&#xff0c;了解生命周期可以讓我們在最合適的地方完成想要的功能2.1.3. 生命周期和生命周期函數的關系…

【單板硬件開發】關于復位電路的理解

閱讀紫光同創供應商提供的FPGA單板硬件開發手冊&#xff0c;發現復位電路他們家解釋的很通俗易懂&#xff0c;所以分享一下。如下圖&#xff0c;RST_N 是低有效的異步全芯片復位信號&#xff0c;一般外部連接電路有 3 種形式如圖 3–2&#xff0c;可根據實際需要選擇合適的電路…

《Unity Shader入門精要》學習筆記一

1、本書的源代碼 https://github.com/candycat1992/Unity_Shaders_Book 2、第1章 Shader是面向GPU的工作方式 3、第2章 渲染流水線 Shader&#xff1a;著色器 渲染流水線&#xff1a;目標是渲染一張二維紋理&#xff0c;輸入是一個虛擬攝像機、一些光源、一些Shader以及紋…