二维数组逻辑上是二维,物理存储实质是一维。逻辑上的二维数组,是指一个数组的数组,如int arr[R][C]; int i, j;
数组arr的元素是数组arr[i],arr[i][j]。
arr在与运算符&和sizeof的上下文中表示整个数组,其类型是int[R][C]。
arr在其它的上下文中表示数组的元素,其类型是int[C],是一个一维数组指针int(*)[C]。
如此规定有其合理性存在,因为操作数组的绝大部分时间是操作数组的元素,如arr[i][j],是*(*(arr i) j)的语法糖。arr i是按元素的长度sizeof(int[C])*i的字节数进行移动而形成对元素的访问。所以,二维数组自然可以通过一个一维数组指针来访问。
二维数组逻辑上是一个数组的数组,可以用一个一维指针数组的元素来引用一个二维数组的元素(一维数组)。也就是可以用一个一维指针数组来操作一个二维数组。
二维数组的物理存储还是线性的顺序存储,自然,也可以使用一个一级指针来操作二维数组。
对于返回动态二维数组,通常可以先建立一个一维的动态指针数组,再由数组元素(指针)指向一个一维动态数组。逻辑便构建了一个动态二维数组。
#include <stdio.h>
#include <malloc.h>
#define ROW 3
#define COL 5
void arr2D()
{
int arr[ROW][COL] = {0};
int i,j;
for(i=0;i<ROW;i )
for(j=0;j<COL;j )
arr[i][j] = (i 1)*(j 1);
int (*ap)[COL] = arr; // 使用一维数组指针(行指针)引用二维数组元素
for(i=0;i<ROW;i )
{
for(j=0;j<COL;j )
printf("- ",*(*(ap i) j)); // ap i移动的字节数是sizeof int[COL]*i
printf("\n");
}
printf("\n");
int *pa[COL] = {0}; // 使用一维指针数组引用二维数组元素
for(i=0;i<ROW;i )
pa[i] = arr[i];
for(i=0;i<ROW;i )
{
for(j=0;j<COL;j )
printf("- ",*(*(pa i) j)); // pa i移动的字节数是sizeof (int*) *j,由指针指向数组
printf("\n");
}
printf("\n");
int *p =(int*)arr; // 使用一级指针引用二维数组元素
for(i=0;i<ROW;i )
for(j=0;j<COL;j )
*(p i*COL j) = (i 1)*(j 1);
for(i=0;i<ROW;i )
{
for(j=0;j<COL;j )
printf("- ",*(p i*COL j));
printf("\n");
}
printf("\n");
}
int **darr2d(int row,int col,int(**ap)[COL],int(**pd)[ROW][COL])
{
int i;
// 1 通过一维数组指针建立动态二维数组(行、列皆为变量)
int **dp = (int**)malloc(sizeof(int*)*row);
for(i=0;i<row;i )
dp[i] = (int*)malloc(sizeof(int)*col); // 由指针指向数组
// 2 通过一维数组指针(行指针)建立动态二维数组(列数为常量)
*ap = (int(*)[COL])malloc(sizeof(int[COL])*row);
// 3 通过二维数组指针建立动态二维数组(行、列皆为常量)
*pd = (int(*)[ROW][COL])malloc(sizeof(int[ROW][COL]));
return dp;
}
void darr2dTest()
{
int(*ap)[COL];
int (*pd)[ROW][COL];
int row = 4;
int col = 6;
int i,j;
int **dp = darr2d(row,col,&ap,&pd);
for(i=0;i<row;i ) // 测试一维数组指针动态分配的内存
for(j=0;j<COL;j )
ap[i][j] = (i 1)*(j 1);
for(i=0;i<row;i )
{
for(j=0;j<COL;j )
printf("- ",*(*(ap i) j));
printf("\n");
}
printf("\n");
free(ap);
for(i=0;i<ROW;i ) // 测试二维数组指针动态分配的内存
for(j=0;j<COL;j )
(*pd)[i][j] = (i 1)*(j 1);
for(i=0;i<ROW;i )
{
for(j=0;j<COL;j )
printf("- ",*(*(*pd i) j));
printf("\n");
}
printf("\n");
free(pd);
for(i=0;i<row;i ) // 测试二维数组动态分配的内存
for(j=0;j<col;j )
dp[i][j] = (i 1)*(j 1);
for(i=0;i<row;i )
{
for(j=0;j<col;j )
printf("- ",*(*(dp i) j));
printf("\n");
}
printf("\n");
for(i=0;i<row;i )
free(dp[i]);
free(dp);
}
int main()
{
arr2D();
darr2dTest();
getchar();
return 0;
}
/*
1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
4 8 12 16 20
1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
1 2 3 4 5 6
2 4 6 8 10 12
3 6 9 12 15 18
4 8 12 16 20 24
*/
图示:
-End-
,