C++多维数组的遍历以及初始化
多维数组初始化
int arr[2][3]
,一般在函数体中使用,所以是在栈中分配内存的局部变量,未初始化时内存上存的是0xCCCCCCCC,它的补码数即为-858993460。int arr[2][3] = {0}
,为第一个元素赋值为0,其余元素由于没给值,所以也赋值为0.int arr[2][3] = {1}
,为第一个元素赋值为1,其余元素由于没给值,所以赋值为0.int arr[2][3] = {1,2,3,4}
,为前4个元素依次赋值为这些。(相当于把所有元素展开来数前4个)其余为0.int arr[2][3] = { {1}, {2} }
,为每一行的首元素赋值。注意里面大括号的个数不能大于第一维度的大小。其余为0.int arr[2][3] = { {1,2,3}, {4,5,6} }
,这是最完整的赋值。
使用下标 遍历
int ia[3][4] = {1,2,3,4,5,6,7,8};
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
cout << ia[i][j] << endl;
}
}
很常用的方式,既可以打印,也可以赋值。
使用范围for + auto遍历
for (auto &p : ia)
{
for (auto q : p)
{
cout << q << endl;
}
}
只可以打印。上面的q
是个局部变量,修改值不会影响到数组中的元素。
for (auto &p : ia)
{
for (auto &q : p)
{
cout << q << endl;
}
}
既可以打印,也可以赋值。上面的q
是个引用,绑定在数组的各个元素上的,修改值自然会影响到数组中的元素。
for (auto p : ia)//此处有错,p被转换为指针
{
for (auto q : p)
{
cout << q << endl;
}
}
上面代码有错,p被转换为指针(其类型为int(*)[4]
),而在内循环中一个指针自然是不可以范围for的,所以会报错。所以要使用范围for + auto,至少最里循环以外的所有循环都用的引用,才能正常遍历。如果还想对元素赋值,则最里循环也得使用引用。
for (int (&p)[4] : ia)
{
for (int q : p)
{
cout << q << endl;
}
}
这是第一段代码它原来的样子。
总结:使用范围for + auto是一种比较方便的方法来遍历多维数组,只需要知道有多少个维度,再建立多少个循环即可。关键是不容易写错。
使用指针 + auto遍历
int ia[3][4] = {1,2,3,4,5,6,7,8};
for (auto p = ia; p != ia + 3; p++)
{
for (auto q = *p; q != *p + 4; q++)
{
cout << *q << endl;
}
}
既可以打印,也可以赋值。上面的q
是个int型指针,对指针解引用自然可以赋值。
int ia[3][4][5] = { 1,2,3,4,5,6 };
for (auto p = ia; p != ia + 3; p++)
{
for (auto q = *p; q != *p + 4; q++)
{
for (auto t = *q; t != *q + 5; t++) {
cout << *t << endl;
*t = 10;
}
}
}
注意多维数组如果是2维以上,写法应该是这样的。除最外层循环外,其余循环都得对指针解引用。
- 第二个循环里,
p
是个int (*)[4][5]
指针(因为这个多维数组的每个元素是int [4][5]
数组,执行auto p = ia
后,数组名ia
转换为指向其首元素的指针) - 对
p
解引用后,*p
是个数组名,其每个元素为int [5]
数组,执行auto q = *p
后,q
则为int (*)[5]
指针。
可见即使使用了auto关键字,这段代码也很容易写错,比如for循环的循环条件那里。
for (auto p = begin(ia); p != end(ia); p++)
{
for (auto q = begin(*p); q != end(*p); q++)
{
cout << *q << endl;
}
}
使用begin和end就可以避免循环条件那里写错了。注意参数需是数组名哈。
for (int(*p)[4] = ia; p != ia + 3; p++)
{
for (int* q = *p; q != *p + 4; q++)
{
cout << *q << endl;
}
}
这是第一段代码它原来的样子。
使用类型别名替换auto遍历
typedef int int_array[4];
using int_array = int[4];//两种方式
//在指针 + auto中,将auto进行替换
for (int_array* p = ia; p != ia + 3; p++)
{
for (int* q = *p; q != *p + 4; q++)
{
cout << *q << endl;
}
}
//在范围for + auto中,将auto进行替换
for (int_array &p : ia)
{
for (int q : p)
{
cout << q << endl;
}
}
将循环变量的类型指定为类型别名,很花哨,但不实用。