跟我學C 中級篇 STL的容器Array

2021-10-19 14:07:38 字數 2504 閱讀 6624

stl中的array陣列型別是在c++ tr1中才提出的,在之前只有vector這個類似於陣列的型別。但在實際應用中發現,vector和實際應用陣列還是有非常大的區別,包括迭代器訪問的控制,記憶體大小的控制等。用過vector的很容易發現它和實際使用中的陣列的諸多不同之處。

換句話說,實際開發過程中,還是需要乙個和陣列高度類似的資料型別,這也是std::array的出現的乙個原因,正如軍事上的火力配比一樣,不能出現火力空白區。那麼這二者最關鍵的不同在哪兒呢?有兩個主要方面,第一是array的記憶體是在棧上,而vector是在堆上。它的直接結果就是理論上講,array的大小有上限(預設win是1m,linux是10m,不過可以動態調整),而vector理論上講可以認為上限非常大(x64平台上,但實際仍受限於物理記憶體和os系統)。同時棧和堆又導致了記憶體生命週期的不同,應用範圍的不同等等。而棧的有限性又顯示標註了array的固定大小性。第二個就是為了保持與c陣列的最大的類似,其建構函式、析構函式和賦值操作符等都是隱式宣告的,這也是乙個從設計原理上與vector不同的地方。

其原始碼定義為:

template class array 

#endif // _has_tr1_namespace

void fill(const _ty& _value) 

_swap_ranges_unchecked(_elems, _elems + _size, _other._elems);

}_nodiscard _constexpr17 iterator begin() noexcept 

_nodiscard _constexpr17 const_iterator begin() const noexcept 

_nodiscard _constexpr17 iterator end() noexcept 

......

}

array的原始碼定義不複雜,就是乙個帶有非模板型別引數的模組類。非模板型別用於指定整個模板陣列的大小,使用size_t來定義。類的開始使用using重定義了一大批的型別,供後面相關**使用。在這個模板類中過載發運算子並實現了at函式,這兩個函式返回的是乙個當前元素的引用。

另外乙個需要說明的是,在這個類模板中,使用的是隱式宣告的建構函式和析構函式,它的定義符合聚合初始化的規則來初始化陣列。

在array中,經歷了版本的不斷的迭代,從c++11到c++17再到最新的c++20,反正都是讓人越來越好用的方法。這會在下面的例程中進行體現。

看幾個例子:

1、宣告定義和使用

void testarray()

;  //標準用法

std::array arr17 = ;  //c++17自動推導

auto arr20 = ;

}

2、生成乙個array,std::to_array

在實際開發中,c陣列在應用中經常退化為指標來使用,這也是初學者在實際開發中,對指標比較恐懼的乙個原因之一,指標為啥莫名其妙又變成了陣列,特別是涉及到高維陣列,老程式設計師也會出現短暫的理解認知時間。

目前在cppreference上定義的介紹為:

namespace detail  };}}

template constexpr std::array, n> to_array(t (&a)[n])

);}

它的應用方法如下:

void testarray()

);  //這行,會服乙個警告,最好在to_array中給出大小,即注釋那行

//std::arraya20 = std::to_array();

std::arraya20 = std::to_array();

for (int num = 0; num 

}

這裡需要說明的是,一定要顯示的使用型別,保證資料安全,這也是c/c++安全開發的乙個要求。

3、做為返回值返回

在實際開發中,如果在棧區上有乙個陣列,一般是嚴格禁止做為返回值的形式酆的。在函式中返回乙個棧上的值,是非常危險的,但是std::array的出現則實現了這種操作的安全性。

std::arraygetarray()

;    return arr;

}int* getcarr()

;    return buf;

}void tgetarray()

}

比較主要的三種用法,可以自己試試。具體的操作函式操作,非常簡單,這裡就不再一一舉例了。

其實對於標準制定者來說,是非常左右為難的,既要兼顧易用性,又要兼顧容易理解性,還得照顧各種歷史的傳承,所以同學們應該明白為啥新語言一出來,就很容易被高手們一下子看到其開發的本質就在於此。因為沒有歷史的包袱,所以新語言能創造性的使用一些新技術新技巧,從而在某個方面迅速展露頭角,(當然,也有搞不好的)但是隨著時間的推進,版本的迭代,同樣會變得越來越臃腫,這也是沒辦法的辦法。

跟我學C 中級篇 STL的容器vector

std vector的原始碼很容易找到,其實你看它 也不複雜,之所以看上去眼花繚亂的原因不是因為他複雜,而是為了相容和安全性搞了好多新功能和方法,再加上一些模板本身的技巧。這些都可以暫時忽略過去,重點看重點的相關的函式方法的實現。向量的建構函式其實就是兩部分模板型別名稱和分配器,而分配器一般使用預設...

跟我學C 中級篇 STL的學習

c 的標準庫主要包含兩大類,首先是包含c的標準庫的,當然,為了適應c 對一些c庫進行了少許的修改和增加。最重要的當然是物件導向的c 庫 而c 庫又可以分成兩大類,即物件導向的c 庫和標準模板庫,也就是題目中的stl。另外在此基礎上,還要提醒同學們的是,除了上面的庫,在各個平台的開發廠商中,還會針對實...

跟我學c 中級篇 pimpl

private implementation,私有化實現。在c 中,由於語言本身的限制,沒有純粹的介面定義。這就導致了在介面的使用上很多c 的人員都是隨心而動。有用抽象類的純虛函式的,有直接用c型別的介面的。有乾脆提供介面類的 不一而足吧。根據實際情況,實事求是的選擇才是乙個好的標準。在c 中,大量...