您好,登錄后才能下訂單哦!
本篇內容介紹了“C++之array數組如何使用”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
數組是一個復合類型,可以通過類似a[d]的形式定義,其中a是數組名,d是數組的容量,d必須要大于0,數組的容量是數組類型的一部分,其導致數組容量必須要在編譯時就已知,這要求數組容量必須是常量表達式,以下提供了數組聲明的幾種形式:
unsigned cnt = 42; //不是一個常量表達式 constexpr unsigned sz = 42; //是常量表達式 int arr[10]; //聲明一個容量為10的整型數組 int *parr[sz]; //42個指向整形指針的數組 string bad[cnt]; //這是個錯誤聲明,因為cnt不是常量表達式
默認情況下,數組里面的元素都會被默認初始化。
我們可以通過列表初始化一個數組,通過這種方式我們在定義時可以忽略數組的容量,如果我們指定了數組容量,那么在列表初始化時初始化的元素數量不能超過設置的容量值,如果少于設置的數組的數量,沒有指定值的元素會使用默認初始化的值,例子如下:
const unsigned sz = 3; int a1[sz] = {0, 1, 2}; int a2[] = {0, 1, 2}; //可以忽略數組的容量 int a3[5] = {0, 1, 2}; //等價于{0, 1, 2, 0, 0} string a4[3] = {"hi", "bye"}; //等價于{"hi", "bye", ""} int a5[2] = {0, 1, 2}; //錯誤
字符數組有一個額外的初始化方式,就是可以通過一個字符還去初始化字符數組,但是需要注意的是string是以null字符結尾的,所以在定義數組容量時要考慮null字符:
char a1[] = "C++"; //其等價于{'C', '+', '+', '\0'} char a2[6] = "Daniel" //錯誤,其未考慮到null字符
?需要注意的是一些編譯器是不支持數組的拷貝,如果直接通過一個數組去初始化另一個數組可能會報錯?
正如vector,array也可以容納所有的類型,例如指針的數組,由于數組是一個對象,所以可以定義指向數組的指針和引用,,定義指向數組的指針或者引用可以通過以下方式:
int *ptre[10]; //ptre是一個數組,其中的元素是10個指向整型的指針 int (*parray)[10] = &arr; //parray是一個指針,其指向的對象是一個容量為10的整型數組 int (&arrRef)[10] = arr; //arrRef是一個引用,其指向的是一個容量為10的整型數組
?在理解聲明時可以按照從左到右,從內到外的順序。?
在C++中指針和數組關系是很近的,一般來說,當我們使用一個數組,編譯器會自動將其轉化為一個指針,一般來說我們是通過地址操作符來獲取一個對象的指針的,但是對于數組而言,當我們使用數組時,編譯器將會自動獲取一個指針指向數組的第一個元素:
string nums = {"one", "two", three}; string *p = &nums[0]; //p指向nums的第一個元素 string *p2 = nums //等價于string *p = &nums[0];
?在大多數表達式中,我們使用數組對象,我們其實是獲取一個指針指向數組的第一個元素?
由于這個影響,我們對于數組的操作其實絕大多數都是對于指針的操作,其中一個比較明顯的是當我們使用auto和數組去初始化一個變量時,其實是聲明了一個指針而不是數組:
int ia[] = {0, 1, 2, 3, 4}; auto ia2(ia); //ia2是一個整形指針,指向ia的第一個元素 ia2 = 43 //錯誤,不可以將int賦值給一個指針 auto ia3(&ia[0]) //這樣看起來更清楚,ia3是整型指針
需要注意的是當我們使用之前提到的decltype時不會發生這種轉化, decltype(ia)返回的類型是10個整型的數組:
decltype(ia) ia3 = {0, 1, 2, 3, 4}; ia3 = p; // 錯誤,不可以將一個整型指針賦值給一個數組 ia3[4] = i; //正確,可以對數組的元素賦值
指針也是迭代器,指向數組元素的指針同樣支持我們之前提到的vector和string中迭代器的操作,例如可以通過自增操作實現從一個元素移動到下一個元素:
int arr[] = [0, 1, 2, 3, 4, 5]; int *p = arr; //現在p指向arr[0] ++p; //現在p指向arr[1]
正如我們可以使用迭代器遍歷vector中的元素,我們也可以使用指針去遍歷數組中的元素,我們可以通過上面的方式獲取數組的第一個元素的指針,那么我們又該如何獲取數組最后一個元素之后的不存在的元素呢,我們可以通過以下方式:
int *e = &arr[6];
我們只可以獲取最后一個元素的下一個元素的地址
for (int *b = arr; b != e; ++b) cout<< *b<<endl
雖然我們可以通過上述方式獲取數組的第一個元素的地址和最后一個元素的下一個地址,但是這并不是一個好的方法,在新的規范中已經提供了新的函數begin和end可以獲取數組的第一個元素的地址和最后一個元素的下一個地址:
int ia[] = {0, 1, 2, 3, 4}; int *beg = begin(ia); int *last = end(ia);
指向數組元素的指針可以使用我們之前在迭代器的文章中提到的所有的迭代器的操作,當我們使用指針加上或者減去一個整型的值時我們將會獲得一個新的指針,這個指針指向原來數組元素前或者后幾個位置的元素,具體的位置取決于加或者減的值:
constexpr size_t sz = 5; int arr[sz] = {1, 2, 3, 4, 5}; int *p1 = arr; //等價于*p1 = &arr[0] int *p2 = p1 + 4; //p2指向arr[4]
當我們用數組加上sz時,編譯器會把arr轉化為指向數組第一個元素的指針,所以如下p就是指向數組最后一個元素的下一個元素,如果相加結果超出數組的范圍則會發生錯誤:
int *p = arr + sz; //小心使用,沒有解引用 int *p3 = arr + 10; //錯誤,數組只有5個元素,雖然編譯器可能無法檢測到這個錯誤
和迭代器一樣,兩個指針相減其結果是兩個指針之間的距離,其前提是這兩個指針式同一個數組中的元素:
auto n = end(arr) - begin(arr);
通過上面的介紹我們已經知道了指針也有算數運算,那么如何判斷是指針的算術運算還是元素的算術運算呢,可以和之前復雜的指針對應,都是先從括號內部開始:
int ia = {0, 2, 4, 6, 8}; int last = *(ia + 4); //先看括號內,所以這是指針的元素暗,last = ia[4] = 8 int last2 = *ia + 4; //ia指向ia[0], 所以last2 = ia[0] + 4 = 4
我們可以看到數組其實就是一個指向數組第一個元素的指針,所以對于數組的下標操作其實就是對于指針的算數元運算,ia[2]等價于*(ia + 2):
int ia = {0, 2, 4, 6, 8}; int *p = &ia[2]; //p指向ia[2]的指針 int j = p[-2]; p[-2]等價于*(p - 2), 所以j = ia[0]
“C++之array數組如何使用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。