C 二維數組,以及自定義二維數組
我們通常情況下是這樣定義一個二維數組的:
int a[10][15];
我們分別查看一下 a,a[0],*a

都是一樣的值吧
我們可以這么理解: a是一個數組的數組
a是數組首元素的地址,a的首元素是一個15個元素的數組,a[0]和a[0]的首元素(a[0][0])的地址是同一個地址
所以有人可能會想int **pa 是不是 跟a同一個類型的
我們可以嘗試下面的代碼:
int a[4][2]=0x1234;
int **ppa=a;
//嘗試寫入數據
**ppa=1;

我們發現段錯誤,說明出錯了,而且ppa並不能代表a
我們把a,*a,**a,ppa,* ppa打印出來

a和ppa的值相同沒問題,因為是指向同一個地址,*a仍然是a的首地址,*ppa直接解引用了
所以**ppa相當於向0x1234寫入數據所以發生了段錯誤!
如果想理解好這個我們先看一下c語言多維數組的內存是什么樣的:

實際上,在內存中,多維數組也是像一維數組一樣是連續的,只不過我們把這個數組抽象了一下,
我們讓這個數組的首地址賦值給一個int**指針,那么這個指針會認為是一個int*數組的地址
(就是一個數組里面保存的都是指針),所以這樣解引用會發生錯誤
解決方法:
使用指向多維數組的指針:
int (*pa)[2];//注意和int *pa[2] 區別,后者是一個保存int*的數組
比如我們在函數傳參的時候
這樣會導致后面的2是固定的,編程的時候會受到一些限制
int func(int (*pa)[2],int l);
對 int (*p)[2]的理解:
int a[4][2];
int (*pa)[2]= a;
printf("%p\n",(char*)&pa[1]-(char*)pa);

自增一次多走了sizeof第二個維度的長度
如果是函數定義的話,也可以:
int func(int a[][2],int l)這樣a第一個維度可以不是固定的,第二維度是固定的,也不是很方便,我們如果定義動態二維數組的話一般不適用多維數組,適用數組的數組
數組的數組(自定義二維數組):

就是用一個int**ppa來指向一個區域,這個區域內每一個元素都是一個指針,每一個指針都指向一個數組
const int col = 5;
const int row = 5;
int **t = (int **)malloc(col*sizeof(int*));
for(int i = 0;i<col;i++)
t[i]=(int*)malloc(row*sizeof(int));
當然,我們也可以把這些不連續的小空間放在一起申請
int **t = (int **)malloc(col*sizeof(int*));
int *p = (int*)malloc(col*row*sizeof(int));
for(int i = 0;i < col;i++)
t[i]=p+col*i;
