僅供參考,歡迎交流和指正 power by Qi
練習
3.6 多維數組
1.多維數組其實就是數組中嵌套數組,數組的元素還是數組,這樣嵌套起來就沒有限制,
一般稱二維數組的第一維叫做行,第二位叫做列。
int a[3][4];
int a[3][4][2];
int a[2][2][2][2];
俄羅斯套娃,可以嵌套很多層,
2.使用初始化列表對多維數組進行初始化,如果初始化列表不全則後面的元素使用默認值初始化
//調用默認初始化
int a[3][4]={};
//統一初始化爲1
int a[3][4] = {1};
//爲每一行初始化
int a[3][4] = {{1},{2},{3}}
//順序初始化
int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12}
//按照維度進行初始化
int a[3][4] = { {1,2,3,4},{5,6,7,8},{9,10,11,12}
}
//初始化列表的長度小於數組中元素的個數
int a[3][4] = {1,3,4,5,6};
3.和一維數組一眼,使用下標運算符可以訪問數組中的元素,如果下標運算符的個數等於數組的維度,則返回定義的類型元素,如果小於數組的維度,則返回的是數組。
4.基於範圍的for同樣適用於多維數組,但是使用auto遍歷的時候要使用引用類型,因爲不使用引用類型的話,會被auto推斷爲指針類型,從而導致範圍for遍歷不了
for(const auto &item:a){
}
使用多維數組,除了在最內層可以不加引用,其餘的層都要加引用
5.多維數組和一維數組一樣,編譯器會將其轉化爲指針,多維數組的指針指向其首元素,其實也沒有什麼特別的,只是首元素爲數組時,定義的指針類型稍稍有點複雜
a的指針類型爲
int (*P)[4]=a;
6.使用類型別名可以使得多維數組的指針稍微沒有那麼複雜
複習
using int_array = int[4];
typedef int[4] int_array;
練習
3.43
int ia[3][4] = {
1,2,3,4,5,6,7,8,9,10,11,12
};
首先是3個錯誤的例子,爲了加深印象寫出來了。
//這種是錯誤的,因爲數組不允許拷貝和賦值
for (int item[4]:ia) {
}
//這也是錯誤的,因爲ia返回的是大小爲四的整數數組,而不是大小爲4的整數數據的地址
for ( int(*item)[4]:ia) {
}
//這一種編譯正確,因爲大小爲4的整型數組在編譯的過程中會被替換爲int*類型,但是int*類型是無法進行範圍for遍歷的
//至於爲什麼int a[4];可以使用返回for我的理解是,雖然a會在編譯時被替換爲int*,
//但是在範圍for中,他的維度信息得到了保留,所以可以遍歷
for (int* item :ia) {
}
1.基於返回for的遍歷
//返回的是大小爲4的整數數組,定義大小爲4的整數數組引用
for (int (&item)[4]:ia) {
for (int item1:item) {
cout<<item1<<endl;
}
}
2.基於下標運算符
for (int i = 0; i < 3;++i) {
for (int j = 0; j < 4;++j) {
cout << ia[i][j] << endl;
}
}
3.基於指針
//多維數組的名字在編譯時也會變成指向首元素的指針
//在這裏ia內部的元素是大小爲4的數組,所以指針類型爲int (*item)[4]
for (int(*item)[4] = begin(ia); item != end(ia);++item) {
for (int* i = begin(*item); i != end(*item);++i) {
cout<<*i<<endl;
}
}
3.44
using int_array = int[4];
for (int_array* item = begin(ia); item != end(ia);++item) {
for (int value:*item) {
cout<<value<<endl;
}
for (int* item1 = begin(*item); item1 != end(*item);++item1) {
cout << *item1 << endl;
}
for (int i = 0; i < 4;i++) {
//要打括號,不然會先調用下標運算符
cout << (*item)[i] << endl;
}
}
3.45
for (const auto & item : ia) {
for (auto value:item) {
cout<<value<<endl;
}
}