一道90%都会做错的指针题
今天,在我們的一個小群里,一個同學發了一道題目給我看,這道題目應該是C語言面試的一股清流了,各種招聘筆試上都可以看到,我試著發到我的大群里去,發現有人對這個理解不是很深刻,所以再發出來,知識總是在不斷的碰撞中提高的,同理,球技也是一樣。
大家可以先猜測一下這兩個程序的輸出是什么?
什么是指針?
書籍看得比較多了,這個指針那個指針,但是我認為如果說到指針,不說變量,就有點耍流氓,所以我認為理解指針的基礎就要理解它是一個變量,所以指針,可以理解為指針變量,再延伸出來,就是地址變量,可以存地址的一個變量,而且存的這個地址指向的類型也是有要求的。
#include "stdio.h" int main() { int i = 12; int *p = &i; printf("%d\n",sizeof(int *)); printf("%d\n",sizeof(p)); printf("%p\n",&p); }看上面的代碼,p是一個指針變量,p存的是一個地址,p存的這個地址存的類型是 int 類型。有點拗口,我們畫個圖。
上圖中 我們定義了一個變量 p ,所以編譯器就必須要給這個p分配內存,如上圖所示,這個p的內存是 0x1000,p是什么類型呢?從定義可以看,p的類型是 int *,所以說p只可以存 int * 類型的值,也就是一級指針,就是一級地址,也就是 i 的地址。
i 也是一個變量,這個變量的地址是 0x1001, 這個地址上存的值是 12。
地址本來是沒有名字的,因為定義了變量,所以地址就對應有了一個別名,這個名字就代表了這個內存地址。
弱弱問一句,聲明有沒有分配內存呢?
什么是數組?
我覺得指針和數組是不用比較的,我們比較的是指針變量和數組名,這兩個東西才有比較的意義,數組是一類數據的集合,指針變量只能是一個地址變量,沒必要折騰自己的大腦了。
#include "stdio.h" int main() { int array[5] = {1,2,3,4,5}; return (0); }我們定義了一個 array的數組,這個數組是個什么鬼東西,我們知道,內存可以起一個別名,數組是連續幾個同類型內存塊的別名。
好了,我們再說下一個問題 ,array 是數組的名字,&array 獲取的是這個數組的地址,而且這個地址的值等于 &array[0] 「首元素的地址」。
雖然數值相等,但是他們的含義是不一樣的。
如果 &array +1 這個時候,地址偏移的是 &array + sizeof(array)
如果 &array[0] +1 這個地址偏移是 &array[0] + sizeof(array[0]) ,也就是偏移到地址 &array[1]上。
再看看上面的兩個題目
我們再看看上面的題目
int *p = (int*)(&a +1);這句代碼執行后,p的值應該是 &a +sizeof(a)了。
但是下面這句代碼就不一樣了。
#include "stdio.h" int main() { int a[5] = {1,2,3,4,5}; int *p = &a; int *q = a; printf("%d %d\n",*(q+1),*(p+1)); return (0); }&a 賦值給 p 后,這個意義就不一樣了,這時候,它的類型是 int* ,p+1 就是 p + sizeof(int *) 。只能偏移到數組的下一個位置。
所以這樣說之后,大家都知道上面的輸出結果了嗎?
2,5
2,2
掃碼或長按關注
回復「?加群?」進入技術群聊
總結
以上是生活随笔為你收集整理的一道90%都会做错的指针题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电脑常用快捷键和操作你值得拥有!
- 下一篇: rk3188开机失败(ump_file_