二维数组逻辑上是二维,物理存储实质是一维。逻辑上的二维数组,是指一个数组的数组,如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 */

图示:

c语言中的指针引用二维数组元素(指针数组或数组指针引用二维数组或二维动态数组)(1)

-End-

,