先放结论:
1. 二维数组数组名指向的类型是 int [x] 类型,int** 指针指向类型是 int* ,如果用二级指针接收会导致访问错误,因为 int [x] 类型和 int* 类型不同。
2. 指向什么类型的指针+1就按照该类型的字节数+1移动。
最近在学图的创建,关于二维数组传参的部分有了很大混淆,因i为二级指针也可以用来模拟二维数组。当然不知道图的创建也没问题,下面先来看代码:
在下面的代码中,G->vexsNum等于6,arcs是一个二级指针,它开辟了6个int*的内存用于存放一级指针,然后每个一级指针也就是for循环中的G->arcs[i]又开辟了6个int的内存用于存放int整形,最后的结果可以看成是创建了一个 6*6 的 int 正方形。
G->arcs = (int**)malloc(sizeof(int*)*G->vexsNum);
for (int i = 0; i < VexsNum; i++) {
G->arcs[i] = (int*)malloc(sizeof(int)*G->vexsNum);
}
这是我们创建的二维数组,当我们有一个外部的二维数组要给 arcs[i] [j] 里的每个成员赋值的时候我们应该如何传参呢?
先来看第一段代码,因为我们刚才创建二维数组时使用的是二级指针,现在用二级指针来接收二维数组好像没有什么问题,但是一调试就会报错出现问题,这是怎么回事?
int array[6][6] = {
0,6,1,5,1,2,
6,0,5,4.3,2,
1,5,0,5,6,4,
5,3,5,0,0,2,
2,3,6,1,0,6,
};
MyGraphCreat(G, array);//main函数中的调用
void MyGraphCreat( Graph* G, int** data) {
for (int a = 0; a < G->vexsNum; a++) {
for (int b = 0; b < G->vexsNum; b++) {
G->arcs[a][b] = data[a][b];
}
}
}
仔细回想一下 data[a][b]的含义,data[a][b] 就是*(*(data+a)+b),data是 int** 指针代表指向类型是 int* 类型,+a就是跳过 a 个int* 类型,再+b跳过b个int类型,找到数。
但是咱们的二维数组的数组名是什么,是第一行的地址, 也就是说 array 是 array[0] 的地址,&array[0],也就是一维数组的指针,指向的是 int [6] 类型的数据。这时data[a][b]就是 *(data+a),就是data跳过a个 int [6] 类型的数据,解引用先找到一维数组 data[a],然后再*(*(data+a)+b),在一维数组中跳过b个int类型的数据,解引用找到最后的数。
也就是说,int* 类型和 int [6] 类型不是一样的,所以不能这样传参,代码的错误就在于指针类型的改变。本来 int** 和二维数组都可以各自 G->arcs[a][b], data[a][b],都可以这样访问,int** 类型指针+1是跳过一个int*,二维数组+1是跳过一个int [6] 数组,这时你把二维数组强行变为 int** 类型来传参,二维数组中没有跳过一个 int* 的操作,就导致错误了。
所以如何传参呢,下面就是一个最帮助理解的例子:
void MyGraphCreat( Graph* G, int(*data)[6]) {
for (int a = 0; a < G->vexsNum; a++) {
for (int b = 0; b < G->vexsNum; b++) {
G->arcs[a][b] = data[a][b];
}
}
}
传过来的是指向 int [6] 类型的指针,所以就用一个数组指针来接收,一次跳过一个 int [6] 类型找到数组,再 [b] 找到数。
或者也可以直接这样传参:
void MyGraphCreat( Graph* G, int data[6][6]) {
for (int a = 0; a < G->vexsNum; a++) {
for (int b = 0; b < G->vexsNum; b++) {
G->arcs[a][b] = data[a][b];
}
}
}
这样就直接可以看出来传的是一个二维数组。
但是如果不是 6*6 的数组呢?我们要更改 6,这样比较麻烦,直接用一级指针(int*)来接收二维数组,这样,每次指针+1就会只跳过1个int类型。代码如下:
void MyGraphCreat( Graph* G, int* data {
for (int a = 0; a < G->vexsNum; a++) {
for (int b = 0; b < G->vexsNum; b++) {
G->arcs[a][b] = *(data+a*G->vexsNum+b);
}
}
}
a
因为二维数组的存储是连续的,如果想找array[6][6]中,第2行第4个元素 (array[1][3]) ,相当于第10个数,只需要让指针+1*6+3,此时a是1,b是3,也就是+9。
这就是文章的全部内容了,感谢阅读,希望对你有所帮助,如有错误欢迎评论。