日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++ STL容器——序列式容器(array、vector、deque、list)

發布時間:2025/3/21 c/c++ 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++ STL容器——序列式容器(array、vector、deque、list) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

概述

1.C++ STL的容器分為三種,序列式容器,關聯式容器,無序式容器,這里先說說常用的序列式容器。
2.array,vector,deque,list,forward_list這幾種都是序列式容器,序列容器是以線性序列的方式存儲元素,也就是說,在內存,是連續分配一塊內存來存放元素的,是可以經過下標迭代的方式遍歷元素。
3.C++的容器是不能用來裝引用和函數的,容器的設計原則是以效率為先,安全為次的,所以容器本身并不帶有異常處理。

一.基本用法

所有的序列式容器都有一些共同的屬性和用法,這里我拿最學常用的std::vecot來舉例子,這些屬性array,vector,deque,list,forward_lis的使用方法是一樣的。

  • 構造:
using T = std::vector<float>;T a;T b(a);//拷貝構造T d = a;//拷貝構造,調用了operator =T e(std::move(b));//右值引用,執行完之后b里面為空值,但b所占的內存不變T c{ a };//C++ 11之后支持的拷貝方法T g(a.begin(), a.end());//區間拷貝
  • 屬性:
T t;int i = t.size();//返回容器大小,為了空間上的極致效率,forward_list沒有這個屬性bool tf = t.empty();//容器是否為空,等價于 t.size() != 0,但效率上要高一些auto max = t.max_size();//當前環境下最多還存放多少個該元素t.swap(a);//交換兩個容器,但類型必須相同,實現是交換兩個容器的指針(array除外)swap(t, a);//等價于上面t.begin();//返回容器頭部迭代器位置t.end();//返回容器末尾部的迭代器合法位置的下一個位置,如果要解引用 *(t.end()-1)t.cbegin();//跟上面兩不一樣的是,這個返回的是const迭代器t.cend();t.rbegin();//反過來的迭代器t.rend();t.front();//返回頭部元素的引用t.back();//返回尾部元素的引用t.clear();//清空容器,調用類的析構函數

二.std::array

1.概念
1.1 std::array是在C++11中才引入的容器,其實就是C++11對內置數組的重新封裝,array對象在實例化的時候大小是固定的,并不支持動態添加或者刪除元素,所以array默認是構造一個非空的實例。array的內存是分配在棧上的,對應的拷貝和賦值都要花掉一定的空間,絕不會重新分配內存。
1.2 在知道容器的大小情況,或者要與C進行交互時可以考慮使用std::array,畢竟array比內置的數組增加了一些常用的接口和可以對下標進行檢查。
2. std::array的構造:

std::array<float, 100> a;//類型是float,有100個元素 std::array<float, 100> b = {};//全部按float的默認值初始化 std::array<float, 5> d = { 1.0f,33.0f,2.1f,4.3f,7.0f };//具體值初始化 std::array<float, 5> c = {2.0f};//第一個元素初始化為2.0,其余按類型默認值初始化

3.std::array的元素訪問
遍歷方法:

//傳統方法遍歷for (size_t i = 0; i < d.size(); ++ i){std::cout << d[i] << std::endl;//中括號是不檢查下標是否合法std::cout << d.at(i) << std::endl;//.at()會檢查下標,如果不合法則拋出異常}//迭代器遍歷for (auto iter = d.begin(); iter != d.end(); ++iter){std::cout << *iter << std::endl;//解引用}//auto 方式遍歷for (auto v : d){std::cout << v << std::endl;}
  • 與C接口互用
  • std::array<char, 10> c_str;strcpy(c_str.data(), "array char\n");//在vs中頭文件要加#include <cstring>,項目屬性/C++/預處理器加入:_CRT_SECURE_NO_WARNINGSprintf("%s", c_str.data());

    5.交換函數:

    t.swap(a);//交換兩個容器,array是交換兩個容器里面的值,而不是容器指針,這樣容器一大效率就會降低swap(t, a);//等價于上面

    三.std::vector

  • 概念
    1.1 std::vector 是C++ 98就引入的動態數組,vector會在需要自動調整所占內存的大小,vector的這個特性讓它比起靜態數組所占用的內 存更多一些,因為它還分配了額外的內存以應對將來可能的內存擴張,在使用過程中,不用因為每次插入新的元素而重新分配內存,除非預留分配的那塊內存用完,這樣有效率會有很大的提升。
    1.2 std::vector的特點是能隨機訪問容器內的元素,在容器末端添加或者刪除元素效率比較高,前端和中間則效率相對會低一些。
  • 構造
  • std::vector<float> d(10);//創建容器里面全部初始化為類型默認值(0.0)std::vector<float> e(10, 1.0f);// 創建容器里面全部初始化為1.0std::vector<float> c(e.begin(), e.end());//迭代器方式拷貝//C++ 11 std::vector<float> h({ 1.01, 1.1, 4.0, 3.0, 5.5 });std::vector<float> d{ 1.2, 3.7, 0.2, 10.4, 3.6 };
  • 屬性
  • auto mun = h.capacity(); //返回容器當前能夠容納的元素數量h.reserve(10); //為容器預先分配內存,避免重新分配內存。h.assign(8, 1.1f);//壓縮或者放大內存并指定默認值h.assign(e.begin(), e.end());//等價于 h = eh.assign({2.0,1.5,3.9});//壓縮并指定初始化h.pop_back();//刪掉最后一個元素,這里要確定容器不能為空h.push_back(11.12);//在容器尾部插入一個元素auto iterAfter = h.erase(h.begin());//刪掉指定元素,刪掉后后面的元素要向前填補,//返回要刪除元素的下一個元素的引用,如果全部//刪完,則返回end(),使用該方法之后,迭代器有//可能會失效(pop_back(),push_back()也有這個現象)//因為vector有可能重新分配內存h.erase(h.begin(), h.end());//區間刪掉元素,要確定區間值是閉合的auto iter = h.insert(h.end(),12.7f);//在指定位置插入一個新的元素,返回迭代器位置iter = h.insert(h.end(),10,12.1f);//在指定位置插入10元素,并初始化為指定值h.insert(h.end(), e.begin(), e.end());//在指定位置插入另一個容器區間h.resize(10);//縮小或者放大容器h.resize(20, 1.2f);//放大容器,如果之前不滿20個,則插入的元素初始化為1.2,//如果原本的容器大于20個,則忽略掉。h.clear();//清空掉容器里面所有的值,但容器的所占的內存不會變小h.shrink_to_fit();//請求容器降低其容量與當前所要存的元素匹配,//但主動權在編譯器,它決定是否真正釋放多余的內存,//這個方法只是提出請求,是否要實現由編譯器說了算//目前大部分的實現是內存能降下來t.swap(a);//交換兩個容器,vector是交換兩個容器的指針swap(t, a);//等價于上面
  • 元素訪問與容器遍歷與array一樣
  • //傳統方法遍歷for (size_t i = 0; i < h.size(); ++i){std::cout << h[i] << std::endl;//中括號是不檢查下標是否合法std::cout << h.at(i) << std::endl;//.at()會檢查下標,如果不合法則拋出異常}//迭代器遍歷for (auto iter = h.begin(); iter != h.end(); ++iter){std::cout << *iter << std::endl;//解引用}//auto 方式遍歷for (auto v : h){std::cout << v << std::endl;}
  • 與C接口互用
  • std::vector<char> c_str(20;strcpy(c_str.data(), "vector char\n");//在vs中頭文件要加#include <cstring>,項目屬性/C++/預處理器加入:_CRT_SECURE_NO_WARNINGSprintf("%s", c_str.data());

    四.std::deque

    1.概念
    1.1 std::deque是雙端隊列,頭尾兩端插入和刪除元素比較高效,中間刪除和添加元素效率低,在std::deque兩端插入和刪除并不會使其它元素的指針或引用失效。
    1.2 元素的訪問和迭代比vector慢,因為迭代器是智能指針而不是普通指針,內存分配不連續。
    1.3 std::deque的存儲空間會自動按需擴大和縮小,擴大std::deque比擴大std::vector的效率和開銷會低很多,因為它不涉及到現有元素復制到新的內存位置。
    2.定義方法和定義vecot的方法一樣,沒有不一樣的地方。
    3.屬性
    std::deque不提供 capacity(),reserve()這兩個方法,因為deque分配的內存是一塊一塊的,不需要知道預分配多少內存。

    std::deque<float> d{ 1.2,3.7,0.2,10.4,3.6 };d.pop_back();//刪除最后一個元素d.pop_front();//刪除頭元素;//在頭部添加元素d.push_front(2.9f);d.emplace_front(3.7f);//在尾部添加元素d.push_back(3.3f);d.emplace_back(1.1f);d.emplace(d.end(),10.0f);//插入元素,指定初始化

    4.元素訪問與容器遍歷與vector一樣。
    5.deque不能和C接口交互。
    6.交換兩個容器方法和效率跟vector一樣。

    五.std::list

    1.概述
    1.1 list是一個雙向鏈表,不支持隨機訪問元素,訪問頭部和尾部元素速度快。
    1.2 在list中任何位置進行插入/刪除操作速度都很快,常量時間內完成,插入和刪除不會造成迭代器失效。
    1.3 對異常支持較好,出現異常對list而言,要么成功,要么什么影響都沒有。
    1.4 list在空間的成本上要比vector,deque高很多,因為list是一個雙向列表,每個元素要有一個往前指針和往后的指針,list本身內部的元素是通過new的方式來生成的,比如用list存一個char元素時,在64位系統下,要開支33個字節左右(往前指針8個字節 + 往后指針8個字+new的16個字節 + char本身的一個字節)。

    2.構造方法與vector一樣。

    3.屬性。
    list是一個個分配內存的,所以不提供capacity(),reserve(),shrink_to_fit() 這三個方法。

    std::list<float> d{ 1.2, 3.7, 0.2, 10.4, 3.6 };d.pop_back();//刪除最后一個元素d.pop_front();//刪除頭元素//在頭部添加元素d.push_front(2.9f);d.emplace_front(3.7f);//在尾部添加元素d.push_back(3.3f);d.emplace_back(1.1f);d.emplace(d.end(), 10.0f);//插入元素,指定初始化

    4.元素訪問與遍歷
    list不支持[]和at訪問元素。

    //訪問遍歷元素auto iter_begin = d.begin();for (int i = 0; i < d.size()-1; ++i){std::cout << *(++iter_begin) << std::endl;}auto iter = std::next(iter_begin,2);//訪問第三個元素,返回迭代器引用std::cout << *iter << std::endl;//auto遍歷元素for (auto v : d){std::cout << v << std::endl;}

    5.算法

    d.remove(1.2);//刪除掉容器里面所有等于1.2的值d.remove_if([](auto v) {return v > 5.0f; });//條件刪除d.reverse();//翻轉整個容器d.sort();//排序,默認是從小到大//std::sort(d.begin(), d.end());//不能這么用h.sort();d.merge(h);//把兩個排好序的容器合并成一個容器,之后h里面沒有元素d.unique();//把兩個排好序的容器里面重復的元素刪掉d.splice(d.begin(),c);//把C容器安插到d的指定位置

    5.list不能和C接口交互。

    總結

    以上是生活随笔為你收集整理的C++ STL容器——序列式容器(array、vector、deque、list)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。