本质:数组的数组。
int iarr[3][4]; -----[3]表示数组iarr本身的大小,[4]表示iarr所容纳的数组的大小。
多维数组的初始化
//每一行分别用花括号括起来
int ia[3][4] = {
{0, 1, 2, 3},
{4, 5, 6, 7},
{8, 9, 10, 11}
};
//不对每一行进行标识,那么将会依次填充,没有填充上的就执行默认初始化
int ia[3][4] = {1, 2, 3, 4, 5, 6, 7};
//只初始化每行的一部分
int ia[3][4] = {{1}, {2}, {3}};
多维数组的范围for循环
除最内层的循环外,其余所有循环的控制变量都应该是应用类型。否则,编译器将会把其自动转换为指向该层数组首元素的指针,内层循环就无法进行下去了。
for(auto &row: ia)
for(auto &colum: row)
声明中的圆括号
//一个数组,其存储对象是整型指针
int *p[4];
//一个指针,其指向一个容纳4个整数的数组
int (*p)[4];
//错误的,因为数组不能存储引用
int &p[4];
//一个引用,引用对象是一个能容纳4个整数的数组
int (&p)[4];
练习题
1. 编写3个不同版本的程序,令其均能输出ia的元素。版本1使用范围for语句管理迭代过程;版本2和版本3都使用普通的for语句,其中版本2要求用下标运算符,版本3要求用指针。此外,在所有3个版本的程序中都要直接写出数据类型,而不能使用类型别名、auto关键字或decltype 关键字。
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
int main() {
int ia[3][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
cout << "version1_rangeFor" << endl;
for(int (&row)[4]: ia){
for(int colum: row){
cout << colum << " ";
}
}
cout << endl << "version2_index"<< endl;
for(size_t i = 0; i < 3; ++i){
for(size_t j = 0; j < 4; ++j){
cout << ia[i][j] << " ";
}
}
cout << endl << "version3_ptr"<< endl;
for(int (*row)[4] = ia; row != (ia + 3); ++row){
for(int *colum = *row; colum != (*row + 4); ++colum){
cout << *colum << " ";
}
}
cout << endl << "version4_beginAndEnd"<< endl;
for(int (*row)[4] = std::begin(ia); row != std::end(ia); ++row){
for(int *colum = std::begin(*row); colum != std::end(*row); ++colum){
cout << *colum << " ";
}
}
}
2. 改写上一题,使用类型别名来代替循环控制变量的类型。
类型别名简化数组的指针:using int_array = int[4];
typedef int int_array[4];
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
int main() {
int ia[3][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
cout << "version1_rangeFor" << endl;
using int_array = int[4];
for(int_array (&row): ia){
for(int colum: row){
cout << colum << " ";
}
}
cout << endl << "version2_index"<< endl;
for(size_t i = 0; i < 3; ++i){
for(size_t j = 0; j < 4; ++j){
cout << ia[i][j] << " ";
}
}
cout << endl << "version3_ptr"<< endl;
for(int_array (*row) = ia; row != (ia + 3); ++row){
for(int *colum = *row; colum != (*row + 4); ++colum){
cout << *colum << " ";
}
}
cout << endl << "version4_beginAndEnd"<< endl;
for(int_array (*row) = std::begin(ia); row != std::end(ia); ++row){
for(int *colum = std::begin(*row); colum != std::end(*row); ++colum){
cout << *colum << " ";
}
}
}
3. 再次改写,使用auto关键字
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
int main() {
int ia[3][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
cout << "version1_rangeFor" << endl;
for(auto &row: ia){
for(auto colum: row){
cout << colum << " ";
}
}
cout << endl << "version2_index"<< endl;
for(size_t i = 0; i < 3; ++i){
for(size_t j = 0; j < 4; ++j){
cout << ia[i][j] << " ";
}
}
cout << endl << "version3_ptr"<< endl;
for(auto row = ia; row != (ia + 3); ++row){
for(auto colum = *row; colum != (*row + 4); ++colum){
cout << *colum << " ";
}
}
cout << endl << "version4_beginAndEnd"<< endl;
for(auto row = std::begin(ia); row != std::end(ia); ++row){
for(auto colum = std::begin(*row); colum != std::end(*row); ++colum){
cout << *colum << " ";
}
}
}