先放結論:
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。
這就是文章的全部內容了,感謝閱讀,希望對你有所幫助,如有錯誤歡迎評論。