严格来说C++语言中没有多维数组,通常所说的多维数组其实就是数组的数组。谨记这一点对后面的理解大有益处。
当一个数组的元素还是数组的时候,通常使用两个维度来定义它:第一个维度是表示数组本身的大小,另外一个维度表示其元素的数组的大小。
比如:
int ia[3][4];//1
int ib[10][10][10]=0//2
- 大小为3的数组,存储的元素是大小为4的整型数组。
- 大小为10的数组,它的每个元素都是大小为10的数组,而这些数组的元素每个也都是含有10个整数的数组,最后的赋值,就是将所有元素初始化为0.
紧接着理解一下下面这段代码,相信会有所想法
#include<iostream>
using namespace std;
int main()
{
int a[3][4] = { {1},{2},{3} };
for (auto i : a)
cout << *i<<" "<<*(i+1)<<" "<<*(i+2)<<endl;
return 0;
}
多维数组的初始化
允许使用花括号括起来的一组值初始化多维数组,这一点和普通的数组一样。例如
int ia[3][4]={
(1,2,3,4),
(2,3,4,5),
(3,4,5,6),
(4,5,6,7)};
其中内层嵌套着的花括号并非必须的,例如:
int ia[3][4]={1,2,3,4,2,3,4,5,3,4,5,6,4,5,6,7};
类似于一维数组,在初始化多维数组时也并非所有元素的值都必须包含在初始化列表内。如果仅仅想要初始化每一行的第一个元素,可以通过这么来写:
int ia[3][4]={(1),(2),(3)};
int ia[3][4]={{1},{2},{3}};
上面两种写法是不一样的。原因就在于()会被当成一个元素,只有{}才是被当成一组。所以仅有后者是对的。
而如果省略掉括号话,情况就是完全不一样了,数组会按顺序进行赋值,然后剩下的值全为0
多维数组的下标引用
这里的多层引用十分简单,就跟我们正常所理解的一样
我们这里定义一个ia数组int ia[3][4],那么他就是一个三行四列的值
//ia数组
1 2 3 4
2 3 4 5
3 4 5 6
4 5 6 7
上述就是该数组长的样子
如果此时说我们要将第三行第四个元素赋值给一个名为num的数我们就这么写:int num = ia[2][3],为什么是,2 3呢?
原因就在于对于数组来说它的第一行往往是第0行的。理解这一段你将对下标引用也有所理解。
使用范围for语句处理多维数组
由于在C++11中新增了范围for语句,所以,我们带着疑问看一下这个代码
#include<iostream>
using namespace std;
int main()
{
int ia[3][4];
size_t cnt=0;
for (auto &row : ia)
for(auto &col : row) //记住用的是row
col=cnt++;
return 0;
}
这一段赋值相当于把ia中数组的元素按照第几个就赋值为几,而使用引用便是方便修改值。
事实上最开始就是将ia中按ia的元素的地址枚举给row,所以row掌握的值也还是内部数组的地址,也就是ia[0],ia[1],ia[2],而再次放到下一个范围for里面进行枚举col,就相当于取内部的数据了。
PS:要使用范围for语句处理多组数据,除了最内层的循环以外,其他所有的循环的控制变量都应该是引用类型的,但是为了方便,也可以直接全部命名成引用。
指针和多维数组
当程序使用多维数组的名字的时候,也会自动将其转化为指向数组首元素的地址。
PS:定义指向多维数组的指针时,千万别忘记这个多维数组实际上时数组的数组。
int ia[3][4]; //1
int (*p)[4]=ia;//2
p=&ia[2];//3
- 大小为3的数组,每个元素都是包含4个整数的数组
- p指向含有4个整数的数组
- p指向ia的尾元素
由之前的学习可知道:
int *ip[4];//整型指针的数组
int (*ip)[4];//指向含有4个整数的数组
所以介绍到这里,这一串代码也能理解了吧:
```cpp
#include<iostream>
using namespace std;
int main()
{
int a[3][4] = { {1},{2},{3} };
for (auto i : a)
cout << *i<<" "<<*(i+1)<<" "<<*(i+2)<<endl;
return 0;
}
最后再提一嘴,就是说如果使用auto 和decltype函数进行赋值,所返回的数据类型将是指针类型,不过是一层一层的指针类型,或者可以这么想,auto p = ia,那么p就是比ia更小一层的指针,但如果是p此时变成最小的一层了,那他就是对应的数字了,就不是指针了,大家好好理解理解。
类型别名简化多维数组的指针
我们由两种方法进行简化:
第一种:
using int_array = int[4];
第二种:
typedef int int[4];
那此时进行打印就会方便很多,我也打出来方便大家理解:
for(int_array *p = ia;p!= ia+3;p++){
for(int *q = *p;q!=*p+4;q++)
cout<<*q<<' ';
cout<<endl;
}