[英]Declaring arrays in C++
我是C ++的新手,目前正在自己學習一本書。 這本書似乎說有幾種數組取決於你如何聲明它。 我想動態數組和靜態數組之間的區別對我來說很清楚。 但我不明白STL std::array
類和靜態數組之間的區別。
STL std::array
變量聲明為:
std::array < int, arraySize > array1;
而靜態數組變量聲明為:
int array1[arraySize];
這兩者之間有根本的區別嗎? 或者它只是語法而兩者基本相同?
std::array<>
只是C風格數組的一個輕量級包裝器,帶有一些額外的好的接口成員函數(如begin
, end
等)和typedef
s,大致定義為
template<typename T, size_t N>
class array
{
public:
T _arr[N];
T& operator[](size_t);
const T& operator[](size_t) const;
// other member functions and typedefs
}
但是一個基本的區別是前者可以通過值傳遞,而后者只能傳遞指向第一個元素的指針,或者你可以通過引用傳遞它,但是你不能將它復制到函數中(除了通過std::copy
或手動)。
一個常見的錯誤是假設每次將C樣式數組傳遞給函數時,由於數組衰減為指針而導致其大小丟失。 這並非總是如此。 如果您通過引用傳遞它,則可以恢復其大小,因為在這種情況下沒有衰減:
#include <iostream>
template<typename T, size_t N>
void f(T (&arr)[N]) // the type of arr is T(&)[N], not T*
{
std::cout << "I'm an array of size " << N;
}
int main()
{
int arr[10];
f(arr); // outputs its size, there is no decay happening
}
這兩者之間的主要區別是重要的。
除了STL給你的好方法,在將std::array
傳遞給函數時,沒有衰減。 意思是,當你在函數中收到std::array
時,它仍然是一個std::array
,但是當你將一個int[]
數組傳遞給一個函數時,它會有效地衰減到一個int*
指針和數組的大小迷路了。
這種差異是一個重要的差異。 一旦丟失了數組大小,代碼現在容易出現很多錯誤,因為您必須手動跟蹤數組大小。 sizeof()
返回指針類型的大小,而不是數組中元素的數量。 這會強制您使用process(int *array, int size)
等接口手動跟蹤數組大小。 這是一個很好的解決方案,但容易出錯。
請參閱Bjarne Stroustroup的指南:
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Rp-run-time
使用更好的數據類型可以避免這種情況, std::array
是為許多其他STL類設計的。
作為旁注,除非有充分的理由使用固定大小的數組,否則std::vector
可能是一個更好的選擇作為連續的內存數據結構。
std::array
和C風格的數組類似:
std::array
一個重要優點是它可以通過值傳遞,並且不會像C風格的數組那樣隱式衰減到指針。
在這兩種情況下,都會在堆棧上創建數組。
但是,STL的std::array
類模板比第二種情況的“原始”C類數組語法提供了一些優勢:
int array1[arraySize];
例如,對於std::array
您有一個典型的STL接口,使用size
(可用於查詢數組的元素計數), front
, back
, at
等方法。
你可以在這里找到更多細節。
這兩者之間有根本的區別嗎? 或者它只是語法而兩者基本相同?
原始c風格數組( 內置數組 )與std::array
。
從參考文檔中可以看出,有許多可用的操作沒有原始數組:
例如:元素訪問
at()
front()
back()
data()
std::array
的底層數據類型仍然是一個原始數組,但是帶有“語法糖” (如果這應該是您關注的話)。
std::array<>
和C風格數組的主要區別在於前者是一個包裹后者的類。 該類有begin()
和end()
方法,允許std::array
對象作為參數輕松傳入期望迭代器的STL算法(注意C樣式數組也可以通過非成員std::begin
/ std::end
方法)。 第一個指向數組的開頭,第二個指向超出其結束的一個元素。 您可以使用其他STL容器看到此模式,例如std::vector
, std::map
, std::set
等。
STL std::array
另一個std::array
是它有一個size()
方法,可以讓你獲得元素數。 要獲得C風格數組的元素數,您必須編寫sizeof(cArray)/sizeof(cArray[0])
,所以stlArray.size()
看起來不那么可讀嗎?
你可以在這里得到完整的參考:
通常你應該更喜歡std::array<T, size> array1;
超過T array2[size];
但是,底層結構是相同的。
主要原因是std::array
總是知道它的大小。 您可以調用其size()方法來獲取大小。 而當你使用C風格的數組(即你所謂的“內置數組”)時,你總是必須將大小傳遞給使用該數組的函數。 如果你以某種方式弄錯了,你可能會導致緩沖區溢出,並且該函數會嘗試讀取/寫入不再屬於該數組的內存。 std::array
不會發生這種情況,因為大小始終是清晰的。
IMO,
優點:它的效率很高,因為它不會使用比內置固定陣列更多的內存。
缺點:內置固定數組上的std::array
是一種稍微笨拙的語法,你必須明確指定數組長度(編譯器不會從初始化程序中為你計算它)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.