進一步理解指針:一維數組和二維數組轉換


先看下列代碼的輸出是什么?
int main()
{
    int m[5] = { 0,1,2,3,4 };
    int* p = (int*)(&m+1);
    printf("%d,%d\n", *(m+1), *(p-1));
    return 0;
}

要知道這個輸出,最關鍵的是要理解指針操作的“加”和“減”,假設有一指針ptr,則“ptr”中的“1”是指ptr所指類型的大小。因此上述代碼中的“&m+1”中的“1”實質是“sizeof(m)”,而后一個“1”則“sizeof(m[0])”。

為什么“&m+1”中的“1”是“sizeof(m)”?根本原因在於“&a”實際是一個二維數組“int (*)[5]”的首地址,而不是一維數組“int [5]”的首地址,看下面這段代碼就容易理解:
int main()
{
    int m[5] = { 0,1,2,3,4 };
    int* p = (int*)(&m+1);
    printf("%d,%d\n", *(m+1), *(p-1));


    int (*pp)[5] = (&m+1);
    --pp;
    printf("%d\n", pp[0][4]);
    return 0;
}

而要注意:上面的“p”仍然是一個一維數組的首地址!下面演示把一個一維數組變成真正的二維數組使用:
int main()
{
    int m[5] = { 0,1,2,3,4 };

    int** ppm = (int**)m; // 這里也可以寫成:int** ppm = (int**)&m;,&m、m和&m[0]的區別是什么?
    int (*pm)[3] = (int (*)[3])ppm;
    printf("%d\n", pm[1][1]);

    return 0;
}

下列代碼的輸出又是什么了?或者代碼有問題?
int main()
{
    int m[5] = { 0,1,2,3,4 };


    int** ppm = (int**)m;
    int (*pm1)[3] = (int (*)[3])&m;
    int (*pm2)[3] = (int (*)[3])ppm;
    int (*pm3)[3] = (int (*)[3])&ppm;
    printf("%d,%d,%d\n", pm1[1][1], pm2[1][1], pm3[1][1]);


    return 0;
}

指針加減,要看它指向的類型,移動大小是指向類型的大小。實際上,內存中的pm[0]和pm[1]是連續在一起的,並沒有分成兩行,只是為了理解二維數組經常被畫成二維表格形式。
關聯貼:常見指針定義解讀http://blog.chinaunix.net/uid-20682147-id-4344901.html)。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM