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;
    }
}

将循环变量的类型指定为类型别名,很花哨,但不实用。

posted @ 2019-05-25 20:42  allMayMight  阅读(339)  评论(0编辑  收藏  举报