二维数组
int a[3][4] = { {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11} };
概念上,a是3行4列的矩阵;二维数组是按行排列的,按照a[0],a[1],a[2]排列;
在内存中,a 的分布是一维线性的,整个数组占用一块连续的内存;
二维数组在内存中的存储
a[0],a[1],a[2]分别表示3个一维数组,地址次第相差4*sizeof(int);
二维数组指针
int (*p)[4] = a; //二维数组指针
数组的类型为 int [4],这正是 a 所包含的每个一维数组的类型;
p 指向的数据类型是 int [4],那么 p+1 就前进 4×4 = 16 个字节(a相同);
p 指向数组 a 的开头,也即第 0 行;p+1 前进一行,指向第 1 行;
*(p+1) 表示取地址上的数据,也就是整个第 1 行数据,是多个数据,不是第 1 行中的第 0 个元素;
sizeof(*(p+1)); //结果为16
*(p+1)+1 表示第 2 行第 2 个元素的地址;
等价关系:
a+i == p+i
a[i] == p[i] == *(a+i) == *(p+i)
a[i][j] == p[i][j] == *(a[i]+j) == *(p[i]+j) == *(*(a+i)+j) == *(*(p+i)+j)
指针数组
int *p[4]; //表示的是4个指针形成的数组
[]结合性大于;
指向指针的指针
int **p; //指向指针(数组)的指针
int数组——》数组的地址形成的地址数组——》地址数组的指针;
自由度过高,不能用来表示2维数组;(编译器会报类型匹配错误)
Example
1.二维数组指针作为入参
#include
//等价于int summary(int i, int j, int arr[5][2]) //最后一个元素未定义,会取栈上的脏数据
//(int i, int j, int arr[2][2])与下面函数结果相同,主要是i,j均为2
//(int i, int j, int **arr)会无法编译,因为类型不匹配!!!
int summary(int i, int j, int (*arr)[2])
{
int result = 0;
for(int a =0; a < i;a++)
for(int b = 0; b
printf("%d ",arr[a][b]);
printf("\n");
for(int a =0; a < i;a++){
for(int b = 0; b
result+=arr[a][b];
};
return result;
}
int main()
{
/* 我的第一个 C 程序 */
int c[3][3]={{1,2,3},{5,6,7},{4,8,9}};
int r = summary(2,2,c);
printf("%d \n",r);
return 0;
}
2.指针的指针表示成二维数组
#include
#include
int main(int argc, char **argv) {
int gridArr[6][5] = {
{1, 2, 3, 4, 5},
{6, 7, 8, 9, 10},
{11, 12, 13, 14, 15},
{16, 17, 18, 19, 20},
{21, 22, 23, 24, 25},
{26, 27, 28, 29, 30}
};
int i, j;
//grid是6个(int *)指针组成的数组
int **grid = (int **) malloc(6 * sizeof(int *)); // 注意:是两个**
for (i = 0; i < 6; i++) {
//grid是6个(5个参数的一维数组)组成的数组
grid[i] = (int *) malloc(5 * sizeof(int)); // 注意:是一个*
for (j = 0; j < 5; j++) {
// 方式一:下标引用
grid[i][j] = gridArr[i][j];
// 方式二:指针计算
// *(*(grid + i) + j) = gridArr[i][j];
}
}
for (i = 0; i < 6; i++) {
for (j = 0; j < 5; j++) {
// 方式一:下标引用
printf("%d\t", grid[i][j]);
// 方式二:指针计算
// printf("%d\t", *(*(grid + i) + j));
}
printf("\n");
}
return 0;
}
reference