指向數組的指針

1.指針數組和數組指針的概念

指針數組:指針數組是一個數組,是指由指針構成的數組,在這個數組中的所有元素都是指針,每個指針佔用相同的字節。

數組指針:數組指針是一個指針,是指一個數組的指針,數組兩字表示這個指針指向一個數組的首地址,並且這個指針加1時移動的位置是整個數組的長度。

2.指針數組

一個可行的指針數組定義如下:

char *arr[4] = {"hello", "world", "xiang", "qian"};

這裏的寫法是*arr[4],則表示指針數組,如果是(*arr)[4],則表示數組指針。上面的代碼中arr是一個有4個元素的數組,每個元素都是指針,因此arr佔據的空間是14個字節,而後面的字符串呢?他們被分配在另一個內存區域,由arr指向他們,因此可以試着向字符串中多寫入幾個字母,再用sizeof(arr)輸出觀察,結果依然是16個字節。所以指針數組,相當於是把好幾個指針放在了一個數組裏,僅此而已。

3.指向數組的指針

對於一維數組,實際上數組的名字就是數組的首地址,數組的名字也可以當做指針使用。假設一個數組arr[5]存放了5個整型數字,在定義一個指針int *p = arr;那麼arr[2]和p[2]的值是一樣的。

而如果定義了一個數組指針指向了一個一維數組呢?如int (*p1)[5] = arr這時候相當於是一個指針,注意是一個!一個指針指向了一塊內存區域,這塊區域是個一維數組的首地址,而對這個指針進行加一操作的時候,這個指針實際上移動了整個數組長度的距離。這個可以類比來理解,指針之所以需要聲明類型,是爲了說明清楚指針它指向什麼類型的數據,這樣加一操作是才能知道移動多少距離,指向char的指針加一時移動1個字節,指向double的指針加一時移動8個字節。同樣的道理,指向數組的數組指針如果寫成int[5]  (*p1)這樣會比較好理解,這就告訴我們p1這個指針加一時一次要移動5個int的距離。實際中不能這麼寫,這只是爲了好理解。

對於一維數組的訪問,使用普通指針就夠了,如果使用數組指針反而會比較麻煩。

#include <iostream>
using namespace std;
int main() {

    int arr1[5] = {1, 2, 3, 4, 5};
    int *p1;
    int (*p2)[5] = &arr1;
    //p1 = &arr1[0];
    p1 = arr1;
    cout << sizeof(arr1) << endl;
    cout << &arr1 << '\t' << p1 << endl;
    cout << &arr1 + 1 << '\t' << p1 + 1 << endl;
    cout << endl;
    cout << &arr1 << '\t' << p2 << endl;
    cout << &arr1 + 1 << '\t' << p2 + 1 << endl;
    cout << p1[2] << '\t' << *(*(p2+0)+2)<< endl;    } 

代碼輸出爲:

20

0x28fef4        0x28fef4

0x28ff08        0x28fef8


0x28fef4        0x28fef4

0x28ff08        0x28ff08

3       3


對於二維數組的訪問,也可以使用普通指針或者數組指針。假設一個數組arr2[3][3],定義一個普通指針獲取arr2[0][0]的地址後,就可以操作其所有的元素,本質上這個數組在內存中的位置是連續的,因此我們當然知道對指針增加幾個單位後會指向哪個位置。而使用數組指針時,int (*p2)[3] = arr2;一定要記住p2後面的方括號裏的數字要和數組的列數相同,因爲這樣對這個指針進行加一操作時,移動的單位就是數組的列數,相當於移動了一整行的距離。

#include <iostream>

using namespace std;

int main() {
    int arr2[3][3] = {{1, 2, 3},
                      {4, 5, 6},
                      {7, 8, 9}};
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++)
            cout << arr2[i][j] << ' ';
        cout << endl;
    }
    int *p3 = &arr2[0][0];
    cout << p3[0] << ' ' << p3[7] << endl;
    int (*p4)[3] = arr2;
    cout << arr2 << '\t' << p4 << endl;
    cout << arr2 + 1 << '\t' << p4 + 1 << endl;
    cout << 0x28fee8 - 0x28fedc << endl;
    cout << *(*(p4+0)+1) << '\t' << *(*(p4+2)+0) << endl;

    return 0;
}

輸出爲:

1 2 3

4 5 6

7 8 9

1 8

0x28fedc        0x28fedc

0x28fee8        0x28fee8

12

2       7

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章