C++中的順序容器(一)

文章目錄

  • 順序容器概述
    • 所有容器類型都支持的操作
    • 迭代器
    • 容器定義與初始化
      • 將一個容器初始化為另一個容器的拷貝
      • 標準庫array具有固定大小
    • 賦值和swap
    • 關系運算符
  • 順序容器的特有操作
    • 向順序容器添加元素
    • 訪問元素
    • 刪除元素
    • 特殊的forward_list操作
    • 改變容器的大小
    • 容器操作可能是迭代器失效

順序容器概述

元素在順序容器中順序與其加入容器時的位置相對應。
在這里插入圖片描述
選擇合適的順序容器:

  • 除非有很好的理由選擇其他容器,否則使用vector;
  • 程序有很多小的元素,且空間的額外開銷很重要,則不要使用list或forward_list;
  • 要求隨機訪問,vector、deque;
  • 要求在容器的中間插入或刪除,list或forward_list;
  • 只在頭尾插入或刪除,deque;
  • 輸入時要求在中間插入元素,隨后要求隨機訪問:如果在中間插入只是為了排序的話,可以在vector尾部添加元素之后在使用sort排序;如果必須在中間插入,則可以先使用list接收數據,在將接收的數據拷貝到vector中。

如果不確定應該使用哪種容器,那么可以在程序中只是用vector或list公共的操作:使用迭代器,不使用下標操作,避免隨機訪問。

雖然我們可以在容器中保存幾乎任何類型,但某些容器操作對元素類型有自己的特殊要求。例如順序容器的一個版本的構造函數接收容器大小參數,并使用元素類型的默認構造函數。我們可以定義保存這種類型對象的容器,但在構造這種容器時不能只傳遞元素數量:

//假定noDefault是一個沒有構造函數的類型
vector<noDefault> v1(10, init); //ok
vector<noDefault> v1(10); //err,必須提供一個元素初始化器

所有容器類型都支持的操作

在這里插入圖片描述
在這里插入圖片描述

迭代器

一個迭代器范圍由一對迭代器表示,兩個迭代器分別指向同一個容器中的元素或者尾元素之后的位置。可以使用begin得到第一個元素位置,end得到尾元素之后的位置。

//顯式指定類型
list<string>::iterator it = a.begin();
list<string>::const_iterator it = a.begin();
//auto
auto it = a.begin(); //當a是const時,為const_iterator,否則為iterator
auto it = a.cbegin(); //const_iterator

當auto與begin或end結合使用時,獲得的迭代器類型依賴于容器類型。但與cbegin或cend結合時,獲得的是const_iterator。

容器定義與初始化

每個容器都定義了一個默認構造函數。除array之外,其他容器的默認構造函數都會創造一個指定類型的空容器。
在這里插入圖片描述

將一個容器初始化為另一個容器的拷貝

將一個容器初始化為另一個容器的拷貝的方法有兩種:

  • 可以直接拷貝整個容器,要求容器類型和元素類型必須匹配;
  • 拷貝由一個迭代器對指定的元素范圍(array除外),不在要求要求容器類型和元素匹配,而要求拷貝的元素能夠轉化為目標元素即可。
list<string> authors = {"Mi", "Sh", "Au"};
vector<const char*> articles = {"a", "an", "the"};list<string> li(authors); //ok
deque<string> de(authors); //err
vector<string> words(articles); //err
//const char* 可以轉換為string
forward_list<string> words(articles.begin(), articles.end()); //ok

標準庫array具有固定大小

與內置數組一樣,標準庫array的大小也是類型的一部分。當定義一個array時,除了指定元素類型,還要指定容器大小:

array<int, 42> ia1; //42個默認初始化的int
array<int, 42> ia1 = {0}; //一個0,41個默認初始化的int
array<int, 42>::size_type i;

值得注意的是,內置數組不能進行拷貝或者賦值,但是array可以:

int digs[4] = {0, 1, 2, 3};
int cpy[4] = digs; //err,內置數組不支持拷貝或賦值
array<int, 4> digits = {0, 1, 2, 3}; //初始化后,不可使用{}賦值
array<int, 4> copy = digits; //ok,要求類型(容器類型以及大小)一致

賦值和swap

在這里插入圖片描述
賦值運算符要求左右兩邊的運算對象具有相同的類型,它將右邊運算對象中的所有元素拷貝到左邊運算對象中。assign也可以實現類似的功能,但不在要求要求容器類型和元素匹配,而要求拷貝的元素能夠轉化為目標元素即可。

swap可以交換兩個相同類型容器的內容。除了array之外,swap不會對任何元素進行拷貝、刪除或插入操作,因此可以保證在常數時間完成,swap只是交換了兩個容器之間的內部結構。這意味著指向容器(string除外)的迭代器、引用或指針在swap之后不會失效。

例如,iter在swap之前指向svec[3],在swap之后就會指向svec2[3]:

vector<string> svec1(10);
vector<string> svec2(10);
swap(svec1, svec2);

與其他容器不同,swap會真正交換array中元素,雖然swap不會使得array中的指針、引用、迭代器失效,但是在swap之后解引用得到的結果是另外一個array相應位置的值。

關系運算符

每個容器都支持相等運算符(==、!=),除了無序關聯容器都支持關系運算符(>、>=、<、<=)。關系運算符左右兩邊運算對象必須是相同類型的容器,且必須保存相同類型的元素。并且只有當其元素也定義了相應的比較運算時,才可進行比較。

順序容器的特有操作

向順序容器添加元素

除array外,所有標準庫容器都提供靈活的內存管理。在運行時可以動態添加或刪除元素來改變容器的大小。
在這里插入圖片描述
當我們用一個對象來初始化容器時,或將一個對象插入(push、insert)到容器時,實際上放入到容器中的是對象值得拷貝,而不是對象本身。值得注意得是,使用emplace時,則是將參數傳遞給元素得構造函數,并在容器內直接構造元素。

//使用三個參數構造函數
c.emplace_back("789", 25, 15.99);
//err
c.push_back("789", 25, 15.99);
//ok,創建一個臨時對象傳遞給push
c.push_back(Sales_data("789", 25, 15.99));

訪問元素

在這里插入圖片描述
在容器中訪問元素的成員函數返回的都是引用:

if(c.empty())
{c.front() = 42;auto &v = c.back();v = 1024; //改變容器中的元素auto v2 c.back;v2 = 0; //無法改變容器中元素
}

刪除元素

在這里插入圖片描述

特殊的forward_list操作

在這里插入圖片描述
因為forward_list是單向列表,插入刪除等操作會影響目標節點之前的節點,因此以目標節點的前節點作為參數。

改變容器的大小

在這里插入圖片描述

容器操作可能是迭代器失效

向容器中添加元素或從容器中刪除元素的操作可能會使指向容器中元素的指針、引用、迭代器失效。

添加、刪除元素:

  • vector、string,且存儲空間被重新分配,則指向容器的迭代器、指針和引用全部失效。如果為重新分配存儲空間,則只失效指向插入后的元素的;
  • deque,插入刪除到首尾之外的位置會導致指向其中元素的迭代器、指針和引用失效。
  • list、forward_list,不會失效;

使用失效的迭代器、指針或引用是嚴重的運行時錯誤。

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

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

相關文章

Javaweb中,使用Servlet編寫簡單的接口

案例&#xff1a;網頁提交用戶名和密碼信息&#xff0c;后端校驗密碼長度需在6-12位之間 后端部分 WebServlet("/valid") public class SimpleServlet extends HttpServlet{public void service(HttpServletRequest req, HttpServletResponse resp) throws IOExcepti…

C語言實現的常見排序算法

排序是計算機科學中非常重要的基礎算法之一。無論是在數據分析、數據庫查詢還是圖形界面中&#xff0c;我們都可能會遇到排序問題。本文將介紹幾種常見的排序算法&#xff0c;并提供其C語言實現代碼。排序算法的效率和應用場景有很大關系&#xff0c;不同的算法有不同的時間復雜…

對于簡單的HTML、CSS、JavaScript前端,我們可以通過幾種方式連接后端

1. 使用Fetch API發送HTTP請求&#xff08;最簡單的方式&#xff09;&#xff1a; //home.html // 示例&#xff1a;提交表單數據到后端 const submitForm async (formData) > {try {const response await fetch(http://your-backend-url/api/submit, {method: POST,head…

[論文閱讀] SeeSR: Towards Semantics-Aware Real-World Image Super-Resolution

文章目錄 一、前言二、主要貢獻三、Introduction四、Methodology4.1 Motivation &#xff1a;4.2Framework Overview.** 一、前言 通信作者是香港理工大學 & OPPO研究所的張磊教授&#xff0c;也是圖像超分ISR的一個大牛了。 論文如下 SeeSR: Towards Semantics-Aware Rea…

案例-04.部門管理-刪除

一.功能演示 二.需求說明 三.接口文檔 四.思路 既然是通過id刪除對應的部門&#xff0c;那么必然要獲取到前端請求的要刪除部門的id。id作為請求路徑傳遞過來&#xff0c;那么要從請求路徑中獲取&#xff0c;id是一個路徑參數。因此使用注解PathVariable獲取路徑參數。 請求方…

Blazor-父子組件傳遞任意參數

在我們從父組件傳參數給子組件時&#xff0c;可以通過子組件定義的[Parameter]特性的公開屬性進行傳值&#xff0c;但是當我們需要傳遞多個值的時候&#xff0c;就需要通過[Parameter]特性定義多個屬性&#xff0c;有沒有更簡便的方式&#xff1f; 我們可以使用定義 IDictionar…

DeepSeek 的創新融合:多行業應用實踐探索

引言 在數字化轉型的浪潮中&#xff0c;技術的融合與創新成為推動各行業發展的關鍵力量。藍耘平臺作為行業內備受矚目的創新平臺&#xff0c;以其強大的資源整合能力和靈活的架構&#xff0c;為企業提供了高效的服務支持。而 DeepSeek 憑借先進的人工智能技術&#xff0c;在自然…

STM32創建靜態庫lib

創建靜態庫lib 1. 新建工程1.1 創建工程文件夾1.2 編寫用戶相關代碼1.2.1 stm32f4xx_it.h1.2.2 stm32f4xx_it.c1.2.3 標準庫配置&#xff1a;stm32f4xx_conf.h1.2.4 HAL庫的配置&#xff1a;stm32f4xx_hal_conf.h1.2.5 LL庫配置&#xff1a;stm32f4xx_ll_conf.h 1.3 移植通用文…

elabradio入門第二講——BPSK數字調制與解調(插值、升余弦濾波、速率匹配、符號同步)

數字信號可以通過數字基帶傳輸系統進行傳輸&#xff0c;而基帶傳輸系統僅僅適用于低頻信道下的數字信號傳輸。然而&#xff0c;在實際的通信系統中信道通常具有帶通特性&#xff0c;因而需要將基帶信號搬移到適合信道傳輸的高頻載波上&#xff0c;使得信號與信道相匹配&#xf…

汽車 OTA 升級:提升下載與升級速度,優化用戶體驗

摘要&#xff1a; 隨著汽車智能化的飛速發展&#xff0c;OTA&#xff08;Over - the - Air&#xff09;升級已成為汽車行業的重要技術&#xff0c;它能為車輛持續帶來功能更新與性能優化。然而&#xff0c;下載及升級速度較慢的問題常常影響用戶體驗。本文深入探討在汽車 OTA …

【Spring+MyBatis】留言墻的實現

目錄 1. 添加依賴 2. 配置數據庫 2.1 創建數據庫與數據表 2.2 創建與數據庫對應的實體類 3. 后端代碼 3.1 目錄結構 3.2 MessageController類 3.3 MessageService類 3.4 MessageMapper接口 4. 前端代碼 5. 單元測試 5.1 后端接口測試 5.2 使用前端頁面測試 在Spri…

SQLite Select 語句詳解

SQLite Select 語句詳解 SQLite 是一個輕量級的數據庫管理系統&#xff0c;以其簡潔的設計和高效的性能被廣泛應用于各種場景。在 SQLite 中&#xff0c;SELECT 語句是用于查詢數據庫中的數據的命令。本文將詳細介紹 SQLite 的 SELECT 語句&#xff0c;包括其基本語法、常用功…

深度學習05 ResNet殘差網絡

目錄 傳統卷積神經網絡存在的問題 如何解決 批量歸一化BatchNormalization, BN 殘差連接方式 ?殘差結構 ResNet網絡 ResNet 網絡是在 2015年 由微軟實驗室中的何凱明等幾位大神提出&#xff0c;斬獲當年ImageNet競賽中分類任務第一名&#xff0c;目標檢測第一名。獲得CO…

組件庫地址

react&#xff1a; https://react-vant.3lang.dev/components/dialoghttps://react-vant.3lang.dev/components/dialog vue用v2的 Vant 2 - Mobile UI Components built on Vue

docker 進階命令(基于Ubuntu)

數據卷 Volume: 目錄映射, 目錄掛載 匿名綁定: 匿名綁定的 volume 在容器刪除的時候, 數據卷也會被刪除, 匿名綁定是不能做到持久化的, 地址一般是 /var/lib/docker/volumes/xxxxx/_data 綁定卷時修改宿主機的目錄或文件, 容器內的數據也會同步修改, 反之亦然 # 查看所有 vo…

從入門到精通:Postman 實用指南

Postman 是一款超棒的 API 開發工具&#xff0c;能用來測試、調試和管理 API&#xff0c;大大提升開發效率。下面就給大家詳細講講它的安裝、使用方法&#xff0c;再分享些實用技巧。 一、安裝 Postman 你能在 Postman 官網&#xff08;https://www.postman.com &#xff09;下…

將圖片base64編碼后,數據轉成圖片

將圖片數據進行base64編碼后&#xff0c;可以在瀏覽器上查看圖片&#xff0c;只需在前端加上data:image/png;base64,即可 在線工具&#xff1a; Base64轉圖片 - 加菲工具

【動態規劃】詳解 0-1背包問題

文章目錄 1. 問題引入2. 從 dfs 到動態規劃3. 動態規劃過程分析4. 二維 dp 的遍歷順序5. 從二維數組到一維數組6. 一維數組的遍歷次序7. 背包的遍歷順序8. 代碼總結9. 總結 1. 問題引入 0-1 背包是比較經典的動態規劃問題&#xff0c;這里以代碼隨想錄里面的例子來介紹下。總的…

LeetCode每日精進:20.有效的括號

題目鏈接&#xff1a;20.有效的括號 題目描述&#xff1a; 給定一個只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判斷字符串是否有效。 有效字符串需滿足&#xff1a; 左括號必須用相同類型的右括號閉合。左括號必須以…

llama.cpp部署 DeepSeek-R1 模型

一、llama.cpp 介紹 使用純 C/C推理 Meta 的LLaMA模型&#xff08;及其他模型&#xff09;。主要目標llama.cpp是在各種硬件&#xff08;本地和云端&#xff09;上以最少的設置和最先進的性能實現 LLM 推理。純 C/C 實現&#xff0c;無任何依賴項Apple 芯片是一流的——通過 A…