授權轉載,作者:判若兩人丶 (Github)
iOS 筆試題
前言:
這個筆試題想必很多小伙伴都很面熟把,差不多10個人有7個人不會做這道筆試題,或許有知道答案的,但是僅僅知道答案,心裡還是一頭霧水。如果你真的不會那就請認真看完本文章學習一下吧!
錯誤想法:
有的人認為
NSLog(@"%d", *(&arrayName + 1 - 1));
加1減1不就是抵消了麼,那肯定是訪問數組首地址,那打印的值肯定是 10,
看起來是通的(引用宋小寶小品海參炒面一句話:湯面沒給錢,湯面用炒面換得給什麼錢?炒面也沒給錢啊,炒面沒吃給什麼錢?)但是含義是不一樣的。
指針是如何加減運算:
int *p 的解釋:將來的指針是指向int類型
指針p + 1 說明內存地址會加上4個字節(因為是int占4個字節)
如果是 double *p 指針p + 1內存地址會加上8個字節(因為是double占8個字節)
通過上述解釋我們得出一個公式:
指針p + n = p當前的地址值 + n *指向類型所占用的字節數
指針p - n = p當前的地址值 - n * 指向類型所占用的字節數
數組與指針:
int arrayName[4] = {10, 20, 30, 40};
上面的數組占16個字節(原因:每個int類型占4個字節,這個數組有4個int類型,所以占16個字節)
arrayName就是數組名
數組名 :表示數組首元素的地址,相當於一個指向數組首元素的指針
相信你已經有點蒙圈了,我們在進一步解釋一下:
NSLog(@"%p %p", arrayName, arrayName + 1); NSLog(@"%p %p", &arrayName, &arrayName + 1);
打印值
1. arrayName 與 &arrayName
arrayName 是數組名,所以打印出來是數組首元素的地址
&arrayName 含義就是數組的地址(等價於指向arrayName數組的指針),因為沒增加1,所以數組的地址就是數組首元素的地址所以 arrayName <->&arrayName 打印出的地址是一樣的
2.(arrayName + 1) 與 (&arrayName + 1)
(arrayName + 1)通過上述解釋我們知道(arrayName + 1)指針是指向int類型,所以內存地址會加上4個字節
(&arrayName + 1)我們知道&arrayName是數組的地址(等價於指向arrayName數組的指針) 因為增加1,這個數組總共占16個字節,所以內存地址會加上16個字節
最後答案解析
int arrayName[4] = {10, 20, 30, 40}; /** 1.(&arrayName + 1):&arrayName是數組的地址(等價於指向arrayName數組的指針) 2.增加 1 會往後移動16個字節,開始是4個字節的位置,移動後就是16個字節後面的位置(也就是目前位置是20個字節) 3.最後又賦值給,int類型的指針p(int類型占4個字節) 4.所以(p - 1)就是減去4個字節,變成為16個字節的位置,輸出的*(p - 1)值為40 */ int *p = (int *)(&arrayName + 1); NSLog(@"%d", *(p - 1));//輸出結果為 40