1. 程式人生 > 實用技巧 >C/C++陣列取值的真實實現——一個初學者的常見疑惑

C/C++陣列取值的真實實現——一個初學者的常見疑惑

頭條稽核了兩個小時都沒稽核完,先發到這裡了。

第一部分

剛剛看到西芬探測資深軟體工程師@快樂的老碼農 分享了一個微頭條:

相信這位作者是肯定清楚箇中原因的,只是丟擲來讓大家討論。評論區裡有許多朋友顯然是不瞭解的:

還有很多,就不一一截圖了。

毛主席說“沒有調查就沒有發言權”,我們還能看到有信口開河的朋友:

終於有一位朋友給出了正確答案,但是可惜的是,這個和彙編沒關係。

下面我們來說一說這到底是怎麼回事。

第二部分

我們直接看Stack Overflow上面這個2008年提出的問題:

然後看看大神的解答:

這下大家該明白了吧?

對的,C/C++中對陣列取值a[i]的實現,是*(a+i)。你寫i[a],得到是*(i+a),結果是一模一樣的。

第三部分

關於原因,就像這位網友說的一樣,在C語言誕生的年代,計算資源並不像我們現在這樣豐富,64KB的記憶體就已經算是很大了。在這種情況下,C語言編譯器不會去做很多的語法檢查,而是簡單的把x[y]給翻譯成*(x+y).

第四部分

再簡單說一下評論區裡關於組合語言是不是這樣寫的爭論:

沒錯,通常在彙編中,你需要自己指定“真正”的地址偏移量。不過組合語言有非常非常多種,所以我也不知道會不會有一種組合語言不用這樣做,不過我估計是沒有的。

第五部分

這部分是給對C語言指標不熟悉的朋友準備的。看如下程式碼:

int a[5];

我們取a[2],編譯器翻譯成*(a+2)。有人會說,這怎麼能行呢?

這就是在第四部分說的C語言區別於彙編的特性。a是一個數組,在這裡被看成一個int型別的指標,對它進行+操作,實際上a的偏移量不是2,而是2*sizeof(int),在一般的32位機器上是2*4=8。

這就是說,如果一個int的指標p指向0x1230,那做p+2,得到的不是0x1232而是0x1238.