1+1 ≠ 2?來看這道奇怪的C語言題目!

對於很多C語言初學者來說,指針是一大難題!但是指針也是C語言的靈魂,離開指針,可能C語言就只能處理小學數學題了。

但是指針雖然難,但並沒有難到大多數人學不會的程度。C語言面向的使用群體是普通人,而不是智商超群的大佬們。只要用心學習,肯定是可以掌握的。

今天小編又給大家帶來一道關於指針的c語言面試題,話不多說上代碼:

#include<stdio.h>

int main()

{

int vector[2][10] = {

{1,2,3,4,5,6,7,8,9,10},

{11,12,13,14,15,16,17,18,19,20}

};

int(*a)[10] = vector;

printf("%d %d %d %d %d\\n",

**a, **(a + 1), *(*a + 1), *(a[0] + 1), *(a[1]));

return 0;

}

程序首先定義了一個二維數組vector,並使用初始化的方式賦予了1-20的初值,接著又定義了一個指針a,並令其指向vector。

接下來程序通過指針依次輸出5個值,那麼,這個c語言程序的輸出是什麼呢?


✎ 初步分析

顯然這題的關鍵點在於指針a

首先我們要明確一點:在理解指針的時候,要像int char short一樣,將它當做一種數據類型。

分析a的定義語句:int(*a)[10] = vector,可以發現a其實是一個 int[10] 類型的數組指針。

那麼這個c語言的程序輸出結果是什麼呢,得到答案最簡單粗暴的方式就是直接運行代碼:

1+1 ≠ 2?來看這道奇怪的C語言題目!


✎ C語言中的指針移動

不僅僅是C語言,語言中的數據類型其實就是告訴處理器應該如何訪問它,這句話是什麼意思呢?請看下圖:

1+1 ≠ 2?來看這道奇怪的C語言題目!

大家都知道數據在內存中的最小粒度是一個字節,上圖假設截取內存中的10個字節,在我的電腦上,c語言類型佔用了4個字節,因此int類型指針是逐4個字節訪問內存的。

同理,short類型的指針是逐2個字節移動的。char類型的指針是逐字節的移動的。到這裡相信大家都發現了,指針的加減法並不像數學概念中的加減一樣嚴格遵循 1+1 =2。

對於int型指針來說,+1 居然移動了4個字節,對於short型指針來說 +1又只移動了兩個字節。其實分析指針加減法的時候不應該從只從數學角度考慮,比如 1千克 + 1克也不等於2對吧!

這提醒了我們應該不僅僅考慮數字,還需要考慮單位。

指針的單位就是數據類型。int型指針的單位就是sizeof(int),short型指針的單位就是sizeof(short),這樣考慮是不是覺得合理多了。


✎ 程序輸出分析

明確了指針的加減法處理方式,再來分析程序輸出就簡單多了。

**a, **(a + 1), *(*a + 1), *(a[0] + 1), *(a[1]))

1 11 2 2 11

我們首先查看一下指針的數據類型(下圖截取自vs2019)。

1+1 ≠ 2?來看這道奇怪的C語言題目!

從上圖中我們可以清楚地看到a的數據類型就是一個int[10]的數組指針。

那麼*a的數據類型就是一個int[10]的數組,顯然**a就等價於*(*a+0)

那不就是數組的第0個元素1了嗎。

**(a+1)不就相當於指針指向位置的第0個元素嗎,也就是11。

再來看第三個,*a的數據類型就是一個int[10]的數組,那麼*a+1就相當於移動到這個數組的第1個元素(下標從0開始),也就是2。

第四個數字分析和第三個是類似的,因為 *a等價於a[0],所以此處輸出也是2。

第五個數字的分析和第四個是類似的,因為 *(a+1)和a[1]是等價的,輸出為11。

大家有什麼看法呢?歡迎評論區留言!

對於熱愛編程的人來說,有群一起學習的小夥伴很重要!如果你感興趣或者有需求的話,筆者有一個編程零基礎入門學習交流俱樂部,私信我【編程學習】自動進入學編程!還有學習文件視頻,歡迎初學者和正在進階中的小夥伴們!


分享到:


相關文章: