iOS 數(shù)組與指針的詳細(xì)解析

前言:

- (void)viewDidLoad {

[super viewDidLoad];

int arrayName[4] = {10,20,30,40};

int *p = (int *)(&arrayName + 1);

NSLog(@"%d", *(p - 1));

}

很多小伙伴都很面熟吧,差不多10個(gè)人有7個(gè)人都不知道這個(gè)輸出的結(jié)果是什么吧,或許有知道答案的,但是僅僅知道答案,心里還是一頭霧水。如果你真的不會(huì)那就請認(rèn)真看完本文學(xué)習(xí)一下吧!

錯(cuò)誤想法:

有的人認(rèn)為

NSLog(@"%d", *(&arrayName + 1 - 1));

加1減1不就是抵消了么,那肯定是訪問數(shù)組首地址,那打印的值肯定是 10,看起來是通的(引用宋小寶小品海參炒面一句話:湯面沒給錢,湯面用炒面換得給什么錢?炒面也沒給錢啊,炒面沒吃給什么錢?)但是含義是不一樣的。

指針是如何加減運(yùn)算:

- int *p 的解釋:將來的指針是指向int類型

指針p + 1 說明內(nèi)存地址會(huì)加上4個(gè)字節(jié)(因?yàn)槭莍nt占4個(gè)字節(jié))

如果是 double *p 指針p + 1內(nèi)存地址會(huì)加上8個(gè)字節(jié)(因?yàn)槭莇ouble占8個(gè)字節(jié))

- 通過上述解釋我們得出一個(gè)公式:

指針p + n = p當(dāng)前的地址值 + n *指向類型所占用的字節(jié)數(shù)

指針p - n = p當(dāng)前的地址值 - n * 指向類型所占用的字節(jié)數(shù)

數(shù)組與指針:

int arrayName[4] = {10, 20, 30, 40};

上面的數(shù)組占16個(gè)字節(jié)(原因:每個(gè)int類型占4個(gè)字節(jié),這個(gè)數(shù)組有4個(gè)int類型,所以占16個(gè)字節(jié))

arrayName就是數(shù)組名

數(shù)組名 :表示數(shù)組首元素的地址,相當(dāng)于一個(gè)指向數(shù)組首元素的指針

相信你已經(jīng)有點(diǎn)蒙圈了,我們在進(jìn)一步解釋一下:

NSLog(@"%p %p", arrayName, arrayName + 1);

NSLog(@"%p %p", &arrayName, &arrayName + 1);

看看下面的輸出結(jié)果:

2016-07-17 21:46:00.845 數(shù)組與指針筆試題[1861:196315] 0x7fff53a7ca30 0x7fff53a7ca34

2016-07-17 21:46:00.846 數(shù)組與指針筆試題[1861:196315] 0x7fff53a7ca30 0x7fff53a7ca40

我們從輸出的結(jié)果可以知道arrayName 與 &arrayName的地址是相同的,而(arrayName + 1) 與 (&arrayName + 1)輸出的結(jié)果不一樣.

下面就來解釋為什么是這樣的結(jié)果:

1. arrayName 與 &arrayName

arrayName 是數(shù)組名,所以打印出來是數(shù)組首元素的地址

&arrayName 含義就是數(shù)組的地址(等價(jià)于指向arrayName數(shù)組的指針),因?yàn)闆]增加1,所以數(shù)組的地址就是數(shù)組首元素的地址所以 arrayName <->&arrayName 打印出的地址是一樣的

2.(arrayName + 1) 與 (&arrayName + 1)

(arrayName + 1)通過上述解釋我們知道(arrayName + 1)指針是指向int類型,所以內(nèi)存地址會(huì)加上4個(gè)字節(jié)

(&arrayName + 1)我們知道&arrayName是數(shù)組的地址(等價(jià)于指向arrayName數(shù)組的指針) 因?yàn)樵黾?,這個(gè)數(shù)組總共占16個(gè)字節(jié),所以內(nèi)存地址會(huì)加上16個(gè)字節(jié)

最后答案解析

int arrayName[4] = {10, 20, 30, 40};

/**

1.(&arrayName + 1):&arrayName是數(shù)組的地址(等價(jià)于指向arrayName數(shù)組的指針)

2.增加 1 會(huì)往后移動(dòng)16個(gè)字節(jié),開始是4個(gè)字節(jié)的位置,移動(dòng)后就是16個(gè)字節(jié)后面的位置(也就是目前位置是20個(gè)字節(jié))

3.最后又賦值給,int類型的指針p(int類型占4個(gè)字節(jié))

4.所以(p - 1)就是減去4個(gè)字節(jié),變成為16個(gè)字節(jié)的位置,輸出的*(p - 1)值為40

*/

int *p = (int *)(&arrayName + 1);

NSLog(@"%d", *(p - 1));//輸出結(jié)果為 40

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 指針是C語言中廣泛使用的一種數(shù)據(jù)類型。 運(yùn)用指針編程是C語言最主要的風(fēng)格之一。利用指針變量可以表示各種數(shù)據(jù)結(jié)構(gòu); ...
    朱森閱讀 3,624評論 3 44
  • void* 類型指針:通用變體類型指針;可以不經(jīng)轉(zhuǎn)換,賦給其他指針,函數(shù)指針除外;malloc返回的就是void*...
    冰吉凌閱讀 3,537評論 0 18
  • __block和__weak修飾符的區(qū)別其實(shí)是挺明顯的:1.__block不管是ARC還是MRC模式下都可以使用,...
    LZM輪回閱讀 3,609評論 0 6
  • 1. 昨晚和朋友K喝茶,他談起最近去南寧會(huì)見一些大學(xué)同學(xué)的經(jīng)歷。 因?yàn)橐ツ蠈庌k事,算是短途出差,晚上抽空約了幾位...
    我的創(chuàng)業(yè)故事采訪閱讀 2,097評論 16 71
  • 少年自幼迷戀捉鬼拿妖之事,立志要成為一代捉妖大俠。春分及冠之后,便告別故鄉(xiāng),前往蜀山習(xí)捉妖之術(shù)。 蜀山路途遙遠(yuǎn),少...
    浮云歸晚閱讀 368評論 0 0

友情鏈接更多精彩內(nèi)容