C#數組和指針全面討論
C#有很多值得學習的地方,這里我們主要介紹C#數組和C#指針,包括介紹為什么C#語言把數組形參當作指針等方面。
什么時候C#數組和C#指針相同
所有作為函數參數的數組名總是可以通過編譯器轉換為指針。在其他所有情況下,數組的聲明就是數組,指針的聲明就是指針,兩者不能混淆。但在語句或表達式中引用時,數組總是可以寫成指針的形式,兩者可以互換。然而,C#數組和C#指針在編譯器處理時是不同的,在運行時的表示形式也是不一樣的。對編譯器而言,一個數組就是一個地址,一個指針就是一個地址的地址,你應該根據情況做出選擇。
為什么會發生混淆
當人們學習編程時,一開始總是把所有的代碼都放到一個函數里。隨著水平的進步,他們把代碼分別放在幾個函數中。在水平繼續提高后,他們最終學會了如何用幾個文件來構造一個程序。
什么時候C#數組和C#指針是相同的?C#語言標準對此作了如下說明:
規則1 表達式中的數組名(與聲明不同)被編譯器當作一個指向該數組***個元素的指針。
規則2 下標總是與指針的偏移量相同。
規則3 在函數參數的聲明中,數組名被編譯器當作指向該數組的***個元素的指針。
規則1:“表達式中的數組名”就是指針
規則1和2合在一起理解,就是對數組下標的引用總是可以寫成“一個指向數組的起始地址的指針加上偏移量。”(個人認為,表述為“一個指向該數組***個元素的指針加上偏移量”更明確。)
對數組的引用如a[i]在編譯時總是被編譯器改寫成*(a+i)的形式。C#語言標準要求編譯器必須具備這個概念性的行為。于是,a[6]和6[a]都是正確的。
編譯器自動把下標值的步長調整到數組元素的大小。這就是為什么指針總是有類型限制,每個指針只能指向一種類型的原因,因為編譯器需要知道對指針進行解除引用操作時應取幾個字節,以及每個下標的步長應取幾個字節。
規則2:C#語言把數組下標作為指針的偏移量
事實上,下標范圍檢測被認為并不值得加入到C#語言中。數組下標是定義在指針的基礎上的,所以優化器常常可以把它轉換為更有效率的指針表達式,并生成相同的機器指令。C#語言把數組下標改寫成指針偏移量的根本原因是指針和偏移量是底層硬件所使用的基本模型。
為什么C#語言把數組形參當作指針
之所以要把傳遞給函數的數組參數轉換為指針是出于效率的考慮,這個理由常常也是對違反軟件工程做法的辯解。我們傾向于始終把參數定義為指針,因為這是編譯器內部所使用的形式。以上介紹C#數組和C#指針。
【編輯推薦】