關(guān)于指針數(shù)組與數(shù)組指針的理解

上一篇介紹了指針和數(shù)組的區(qū)別和聯(lián)系哀蘑,相信很多同學(xué)都已經(jīng)明白了指針和數(shù)組的用法顿苇,那么如果指針和數(shù)組混合起來撩满,你還會(huì)用嗎蜒程?

指針數(shù)組

指針數(shù)組是一個(gè)數(shù)組,它里面存儲(chǔ)的是指針變量伺帘。比如說 int *p[5]昭躺,數(shù)組里面有五個(gè)元素,里面存儲(chǔ)的是指針伪嫁。由于[]*的優(yōu)先級(jí)要高领炫,故 p 先與[]結(jié)合,也就是說 p 是一個(gè)數(shù)組张咳。

數(shù)組指針

數(shù)組指針是一個(gè)指針帝洪,它在32位機(jī)器下占四個(gè)字節(jié)大小似舵,64位機(jī)器下占據(jù)八個(gè)字節(jié)。比如int (*p)[5]碟狞,表示指向擁有5個(gè)元素的數(shù)組啄枕,示例:

int main()
{
    int a[3][5] = {0};
    int (*p)[5] = a;
}

需要注意的是,數(shù)組指針后面括號(hào)里面的數(shù)字必須與二維數(shù)組的列數(shù)相同才可以族沃。

地址偏移量

地址偏移量的概念不太好理解频祝,為了便于理解,我們引入房間地址樓層地址這兩個(gè)概念脆淹。

在一維數(shù)組中常空,比如int a[5]; a 代表的是一個(gè)房間地址,那么 a+1 就會(huì)偏移一個(gè)房間地址的距離(以數(shù)組中的一個(gè)元素所占內(nèi)存字節(jié)為單位進(jìn)行地址偏移)盖溺,也就是偏移到 a[1] 的地方漓糙。

&a 代表的是一個(gè)樓層地址&a+1 會(huì)偏移整個(gè)數(shù)組的長度(以整個(gè)數(shù)組所占內(nèi)存字節(jié)為單位進(jìn)行偏移)烘嘱,也就是偏移到了整個(gè)數(shù)組后面的地方昆禽。

指針數(shù)組操作二維數(shù)組

int main()
{
    //指針數(shù)組操作二維數(shù)組
    int a[4][5]; //定義一個(gè)二維數(shù)組
    int i, j;
    int *p[4]; //定義一個(gè)指針數(shù)組(是個(gè)數(shù)組),和二維數(shù)組的行數(shù)相同。

    //初始化二維數(shù)組
    for(i = 0; i < 4; i++) 
    {
        for(j = 0; j < 5; j++)
        {
            a[i][j] = 10 * i + j;
        }
    }

    //輸出二維數(shù)組內(nèi)容
    for(i = 0; i < 4; i++) 
    {
        for(j = 0; j < 5; j++)
        {
            printf("a[%d][%d]= %d\t", i, j, a[i][j]);
        }
    }
    printf("\n\n");

    p[0] = *a; //指針數(shù)組(數(shù)組),存儲(chǔ)的是"房間"的地址,而不是"樓層"的地址,如果這樣寫p[0] = a;這樣在c++中編譯不通過的
    p[1] = *(a + 1); //給第二個(gè)元素賦值
    p[2] = *(a + 2); //給第三個(gè)元素賦值
    p[3] = *(a + 3); //給第四個(gè)元素賦值

    //第一種方式輸出二維數(shù)組內(nèi)容
    for(i = 0; i < 4; i++) 
    {
        for(j = 0; j < 5; j++)
        {
            printf("p[%d][%d]= %d\t", i, j, p[i][j]);
        }
    }
    printf("\n\n");


    //第二種方式輸出二維數(shù)組內(nèi)容
    for(i = 0; i < 4; i++) 
    {
        for(j = 0; j < 5; j++)
        {
            printf("*(*(p+%d)+%d)= %d\t",i ,j, *(*(p + i) + j));
         }
    }
    printf("\n\n");

    //第三種方式輸出二維數(shù)組內(nèi)容
    for(i = 0; i < 4; i++) 
    {
        for(j = 0; j < 5; j++)
        {
            printf("*(p[%d]+%d)= %d\t", i, j, *(p[i] + j));
        }
    }
    return 0;
}

輸出結(jié)果:


指針數(shù)組運(yùn)行結(jié)果

解釋:
p 數(shù)組里面存放的是一級(jí)指針蝇庭,p[0] 保存的是二維數(shù)組第一層樓第一個(gè)房間地址醉鳖,p[1] 保存的是二維數(shù)組第二層樓的第一個(gè)房間地址,p[2] 保存的是第三層樓的第一個(gè)房間地址哮内,p[3] 保存的是二維數(shù)組第四層樓的第一個(gè)房間地址盗棵;之后,p[0][0] 表示:(p[0])[0] == (p 數(shù)組的第一個(gè)元素)[0] == (*a)[0] == (a[0])[0] == a[0][0]北发,其他的以此類推纹因,得出結(jié)果。

數(shù)組指針操作二維數(shù)組

int main()
{
    //數(shù)組指針操作二維數(shù)組
    int a[4][5]; //定義一個(gè)二維數(shù)組
    int i, j;
    int (*p)[5]; //定義一個(gè)數(shù)組指針(是個(gè)指針)琳拨,和二維數(shù)組的行數(shù)相同

    //初始化二維數(shù)組
    for(i = 0; i < 4; i++) 
    {
        for(j = 0; j < 5; j++)
        {
            a[i][j] = 10 * i + j;
         }
    }

    //輸出二維數(shù)組內(nèi)容
    for(i = 0; i < 4; i++) 
    {
        for(j = 0; j < 5; j++)
        {
            printf("a[%d][%d]= %d\t", i, j, a[i][j]);
        }
    }
    printf("\n\n");

    p = a; //讓指針指向二維數(shù)組

    // p = *a; //雖然a和*a的值都是一樣的瞭恰,但是這樣無法賦值(a是"樓層地址",*a是"房間地址")

    //第一種方式輸出二維數(shù)組內(nèi)容
    for(i = 0; i < 4; i++) 
    {
        for(j = 0; j < 5; j++)
        {
            printf("p[%d][%d]= %d\t", i, j, p[i][j]);
        }
    }
    printf("\n\n");


    //第二種方式輸出二維數(shù)組內(nèi)容
    for(i = 0; i < 4; i++) 
    {
        for(j = 0; j < 5; j++)
        {
            printf("*(*(p+%d)+%d)= %d\t",i, j, *(*(p + i) + j));
        }
    }
    printf("\n\n");

    //第三種方式輸出二維數(shù)組內(nèi)容
    for(i = 0; i < 4; i++) 
    {
        for(j = 0; j < 5; j++)
        {
            printf("*(p[%d]+%d)= %d\t",i, j, *(p[i] + j));
        }
    }
    return 0;
}

輸出結(jié)果:


數(shù)組指針運(yùn)行結(jié)果

解釋:
p 里面存放的是一維數(shù)組的地址(注意不是數(shù)組首元素的地址,是整個(gè)數(shù)組的地址)狱庇,在程序中 a 表示的就是第一層樓的地址寄疏,也就是 &a[0] 。由于 p 指向的是樓層地址僵井,則 p+1 則表示第二層樓的地址陕截,p+2 表示第三層樓的地址...當(dāng)我們用 p[0][0] 的時(shí)候,其實(shí)表示的就是第一層樓的第一個(gè)房間內(nèi)容(p 表示的第一層樓的地址批什,p[0] 表示的第一層樓的第一個(gè)房間的地址农曲,p[0][0] 表示的第一層樓的第一個(gè)房間的內(nèi)容),其他的以此類推。

總結(jié)

  1. 指針數(shù)組是數(shù)組乳规,數(shù)組指針是指針形葬;它們符合各自數(shù)組或指針的特性;
  2. 數(shù)組和指針都是操作地址的運(yùn)算暮的;
  3. 地址也是有級(jí)別的笙以,例如上面所說的樓層地址房間地址(本質(zhì)是地址操作時(shí)候的偏移單位不同);
  4. 很重要的一點(diǎn)冻辩,數(shù)組的地址是連續(xù)的2蟆!上面的操作都是基于這點(diǎn)才可以實(shí)現(xiàn)的恨闪,如果換成鏈表倘感,則上面程序的輸出結(jié)果將無法判斷;
  5. 上面提到的指針數(shù)組和數(shù)組指針都屬于二級(jí)指針范疇咙咽,如果是int ****p[5]老玛,你還能操作二維數(shù)組嗎?換成三維數(shù)組呢钧敞?抓住本質(zhì)蜡豹,無論多少級(jí)都一樣操作。

補(bǔ)充

與指針數(shù)組和數(shù)組指針類似的還有一個(gè):二級(jí)指針溉苛,示例:

int main() 
{
    int a[4][5]; 
    int i, j;
    int *q[4]; 
    int **p;

    for(i = 0; i < 4; i++) 
    {
        for(j = 0; j < 5; j++)
        {
            a[i][j] = 10 * i + j;
        }
    }

    for(i = 0; i < 4; i++) 
    {
        for(j = 0; j < 5; j++)
        {
            printf("a[%d][%d]= %d\t", i, j, a[i][j]);
        }
    }
    printf("\n\n");

    q[0] = *a; 
    q[1] = *(a + 1); 
    q[2] = *(a + 2); 
    q[3] = *(a + 3); 
    p = q;

    for(i = 0; i < 4; i++) 
    {
        for(j = 0; j < 5; j++)
        {
            printf("p[%d][%d]= %d\t", i, j, p[i][j]);
        }
    }
    printf("\n\n");


    for(i = 0; i < 4; i++) 
    {
        for(j = 0; j < 5; j++)
        {
            printf("*(*(p+%d)+%d)= %d\t",i ,j, *(*(p + i) + j));
        }
    }
    printf("\n\n");

    for(i = 0; i < 4; i++) 
    {
        for(j = 0; j < 5; j++)
        {
            printf("*(p[%d]+%d)= %d\t", i, j, *(p[i] + j));
        }
    }
    return 0;
}

自己輸出一下結(jié)果余素,嘗試?yán)斫庖幌轮羔樀墓ぷ髟恚嘈拍憧梢哉鞣炊昆。。?/p>

練習(xí)

int a[] = {0, 2,4,6,8};
int *p[5]={a, a+1, a+2, a+3, a+4};
int ** pp = p;
int main()
{
    printf("%d\n",*pp++);
    printf("%d\n", *pp-a);
    printf("%d\n", ** ++ pp);
    printf("%d\n", pp - p);
    return 0;
}

輸出結(jié)果是什么呢威根?

#include <stdio.h>

int main()
{
    int a[5] = {1, 2, 3, 4, 5};
    int *ptr = (int *)(&a + 1);
    printf("%d %d\n", *(a+1), *(ptr-1));
    return 0;
}

輸出結(jié)果是什么呢凤巨?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市洛搀,隨后出現(xiàn)的幾起案子敢茁,更是在濱河造成了極大的恐慌,老刑警劉巖留美,帶你破解...
    沈念sama閱讀 222,590評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件彰檬,死亡現(xiàn)場離奇詭異,居然都是意外死亡谎砾,警方通過查閱死者的電腦和手機(jī)逢倍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來景图,“玉大人较雕,你說我怎么就攤上這事。” “怎么了亮蒋?”我有些...
    開封第一講書人閱讀 169,301評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵扣典,是天一觀的道長。 經(jīng)常有香客問我慎玖,道長贮尖,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,078評(píng)論 1 300
  • 正文 為了忘掉前任趁怔,我火速辦了婚禮湿硝,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘痕钢。我一直安慰自己图柏,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,082評(píng)論 6 398
  • 文/花漫 我一把揭開白布任连。 她就那樣靜靜地躺著蚤吹,像睡著了一般。 火紅的嫁衣襯著肌膚如雪随抠。 梳的紋絲不亂的頭發(fā)上裁着,一...
    開封第一講書人閱讀 52,682評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音拱她,去河邊找鬼二驰。 笑死,一個(gè)胖子當(dāng)著我的面吹牛秉沼,可吹牛的內(nèi)容都是我干的桶雀。 我是一名探鬼主播,決...
    沈念sama閱讀 41,155評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼唬复,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼矗积!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起敞咧,我...
    開封第一講書人閱讀 40,098評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤棘捣,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后休建,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體乍恐,經(jīng)...
    沈念sama閱讀 46,638評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,701評(píng)論 3 342
  • 正文 我和宋清朗相戀三年测砂,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了茵烈。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,852評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡砌些,死狀恐怖瞧毙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤宙彪,帶...
    沈念sama閱讀 36,520評(píng)論 5 351
  • 正文 年R本政府宣布矩动,位于F島的核電站,受9級(jí)特大地震影響释漆,放射性物質(zhì)發(fā)生泄漏悲没。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,181評(píng)論 3 335
  • 文/蒙蒙 一男图、第九天 我趴在偏房一處隱蔽的房頂上張望示姿。 院中可真熱鬧,春花似錦逊笆、人聲如沸栈戳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽子檀。三九已至,卻和暖如春乃戈,著一層夾襖步出監(jiān)牢的瞬間褂痰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評(píng)論 1 274
  • 我被黑心中介騙來泰國打工症虑, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留缩歪,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,279評(píng)論 3 379
  • 正文 我出身青樓谍憔,卻偏偏與公主長得像匪蝙,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子习贫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,851評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • 指針是C語言中廣泛使用的一種數(shù)據(jù)類型逛球。 運(yùn)用指針編程是C語言最主要的風(fēng)格之一。利用指針變量可以表示各種數(shù)據(jù)結(jié)構(gòu)沈条; ...
    朱森閱讀 3,451評(píng)論 3 44
  • 變量的聲明和定義變量聲明(declaration) 可以declaration很多次父款,不占內(nèi)存空間,例如 exte...
    FlyingReganMian閱讀 1,042評(píng)論 0 1
  • 前言 最近真的是忙的不可開交,公司一直給安排任務(wù)憨攒,連學(xué)習(xí)和寫筆記的時(shí)間都沒有了世杀,落下好幾次課的筆記都沒有寫,所以我...
    Xiho丶閱讀 1,530評(píng)論 1 12
  • 文/阿霞 忙 早上7點(diǎn)肝集,園區(qū)的飯?zhí)靡呀?jīng)熱鬧起...
    深圳阿霞閱讀 521評(píng)論 2 5
  • 從昨天回了家以后瞻坝,接倆個(gè)電話,錄了一個(gè)電臺(tái)杏瞻。我都沒有說過一句話所刀。這算我活了這么多年第一次感到絕望吧。夜很漫長捞挥,我睡...
    Joey冰閱讀 392評(píng)論 2 5