CSAPP中一個有意思的小東西

回家的效率明顯下降了,但是第三章還是快要結束的節奏。今天看到定長數組這裏的時候,看到一個好玩的東西。在計算機的底層中,所有對數組的操作都是利用指針來完成的。數組其實也是一個很簡單的數據結構,就是把一些最簡單的數據類型合併在一段連續的內存區域上,這就是一個複合類型---數組。



學C語言的時候,大家都知道訪問數組元素有兩種方法,一種是利用數組名加索引的形式,另外一種就是利用指針加上偏移量的形式。在底層中,不管你用什麼方式來訪問元素,最後多會轉化成對指針的操作。

在編寫 代碼的時候,編譯器在編譯過程中會對代碼進行一定的優化。

今天碰到的一個問題就是按照一個例子,給一個把16*16的二維數組的對角線元素都設定爲val值的C語言代碼,讓你根據編譯器的優化規則寫一個份優化過的C語言代碼,具體的例子還是給大家貼一下圖吧,不然看着前後搭不上。




編譯器還是挺聰明的不是麼,看看兩種代碼的區別就知道編譯器做了什麼工作了。

我的理解就是,優化還是在於對指針還是偏移量的運算這裏。


所以,根據上面的那個任務,我寫了一個版本如下。

在貼代碼之前我要說的是,每一層的對角線的元素都和他臨近的對角線元素差n+1個元素,這個n是二維數組的列數。

int *p = &A[0][0]
for(int i = 0; i < n*(n + 1); i = i + n+1)
          p[i] = val

這個代碼模仿起來寫很容易,但是之後你仔細一想,還是挺有意思的。編譯器是把原來對二維數組的操作,變爲對一維數組進行操作,因爲我一開始把p指針指向的是一個一維數組裏面的一個元素。也就是說,現在整個二維數組都看成了一個一維數組,只不過這個一維數組在我們看來是拐着彎排列的。其實在內存中,二維數組中的每一個元素都是一個地址,這個地址就是二維數組內一維數組的首地址。大家在物理上都是相鄰的。

所以這樣這份代碼就很好解釋了。利用指針和便宜量的運算,把整個二維數組內的所有元素看成是一個一維數組,這樣一來,只要找到增量的規律就可以完成了。

另外還要說的就是這個循環條件,因爲我是從0開始進行循環的,所以說數組的維度是n,所以最多隻能到(n-1)(n+1)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章