1. 程式人生 > >例項分析用指標訪問二維陣列的幾種方法

例項分析用指標訪問二維陣列的幾種方法

之前對陣列的概念一直沒有理解透徹,只覺得陣列名就是個常量指標而已,用法和基本的指標差不多。所以當我嘗試用二級指標去訪問二維陣列時,就經常會出錯。下面就是剛開始寫的一個錯誤的程式:

copycode.gif

#include <stdio.h>

int main()

{

    int iArray[2][3] =        {{1,2,3},{4,5,6}};

    int **pArray = NULL;

    pArray = iArray;

printf("pArray[0] = %d\n",*pArray);           (1)

printf("array[0][0] = %d\n", pArray[

0][0]);   (2)

printf("array[1][2] = %d\n", pArray[1][2]);   (3)

    return 0;

}

copycode.gif

    (1)當執行第一步的時候列印的結果為: pArray[0] = 1,即為array[0][0]的值,而**pArray則是去訪問地址為1的地址空間中的資料,自然會出段錯誤。

(2) 當執行第二步和第三步時系統會報錯:其實這裡錯誤的原因是訪問了不該訪問的地址空間.(pArray[0][0]其實就是 *(*(pArray + 0)+0)).

指向陣列的指標和指向指標的指標也大不一樣。它們倆最明顯的不同就是表現在指標步進的時候。我們知道指標在進行

++運算的時候,跨越的實際地址取決於指標指向的資料型別:對於一般的32位機來說,假如指向的是int型資料,跨越的實際地址就是4,指向的是指標型資料,跨越的實際地址也是4,當指向的是陣列型別的時候,跨越的實際地址就是陣列的長度了。

其實用指標訪問二維陣列可以直接用一級指標就可以了。比如下面這個程式:

copycode.gif

int main()

{

    int iArray[2][3] =        {{1,2,3},{4,5,6}};

    int *pArray = NULL;

    pArray = iArray;

printf("array[0][0] = %d\n", *pArray);

    printf("array[1][2] = %d\n", *(pArray + 1 * 3 + 2));

    return 0;

}

copycode.gif

因為陣列本身在地址空間中就是連續排列的,根據行數和列數,我們自己計算出訪問單元的地址偏移量就可以用一級指標輕鬆遍歷二維陣列中的所有資料了。

我們還可以嘗試用指向陣列的指標來訪問二維陣列的成員。下面就是事例程式:

copycode.gif

int main()

{

    int iArray[2][3] =        {{1,2,3},{4,5,6}};

    int (*pArray)[3] = NULL;

    pArray = iArray;

printf("array[0][0] = %d\n", pArray[0][0]);

printf("array[1][2] = %d\n", pArray[1][2]);

    return 0;

}

copycode.gif

     簡單分析一下這個程式:我們知道[]運算子的結合方向是由左向右,pArray[1][2]就等價於(* (pArray + 1))[2],而由於pArray是陣列指標,而且陣列的長度為3,所以* (pArray + 1)就表示iArray[1]這個陣列,則pArray[1][2]則就完全等價於iArray[1][2]

如果非得想用二級指標來訪問二維陣列的話,我們還得借用指標陣列(陣列記憶體儲的都是指標型別的資料),下面是事例程式:

copycode.gif

int main()

{

    int iArray[2][3] =        {{1,2,3},{4,5,6}};

    int *ipArray[2] = {iArray[0], iArray[1]};

    int **pArray = NULL;

    pArray = ipArray;

printf("array[0][0] = %d\n", pArray[0][0]);

printf("array[1][2] = %d\n", pArray[1][2]);

    return 0;

}

copycode.gif

由於二級指標要跳兩次,所以中間還需要額外的儲存一級指標的空間。所以一般不建議用二級指標去訪問二維陣列。