天天看點

《C和C++代碼精粹》——2.7 指針和一維數組

本節書摘來自異步社群出版社《c和c++代碼精粹》一書中的第2章,第2.7節,作者: 【美】chuck allison,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。

c和c++代碼精粹

在程式清單2.7中,會注意到在傳遞數組 s 時并沒有使用它的位址,這是因為c和c++在大多數表達式中把數組名轉換成指向它第一個元素的指針。自1984年以來,我已經向成百上千的學生講授了c和c++,我注意到了指針和數組,特别是指針和多元數組之間的關系造成很多迷惑。

這樣說似乎很奇怪,但是c++确實不支援數組,至少c++不像支援第一類資料類型如整型或者甚至結構體那樣支援數組。考慮以下的語句:

并不是所有有關數組的操作都是合法的。我們可以進行以下操作,但是它并不是一個“真實”的指派:

除了在聲明中或者當一個數組名是sizeof運算符或&運算符的操作數之外,編譯器總是把數組名解釋成指向它的第一個元素的指針。可以将這個原則表達為:

或者等價于:

使用指針運算的規則,那麼當把一個整型變量i和一個數組名相加,結果就得到指向數組第i個元素的指針,也就是:

或者,像我喜歡的表達方式一樣:

重要的指針原則 2:*(a+i)==a[i]

程式清單2.8中的程式闡述了原則2以及準備步驟。

由于所有的數組下标是真正的指針運算,可以使用表達式i[a]代替a[i]。這些可直接從原則2中得到:

當然,任何使用了這樣極端錯誤的表達的程式都會被中斷而不被執行,而且程式員也會受到嚴厲的譴責。然而,使用相反的下标也不是完全沒有道理,如果一個指針p傳遞一個數組,就可以使用表達式p[-1]重新得到在*p之前的元素,由于:

程式清單 2.9極為全面地涵蓋了指針和數組符号的結合,它也使用了一個關于數組中元素個數的有用公式:

雖然可以在除數中使用任何一個有效的下标,但0是最安全的,這是因為每個數組都有第0個元素。當然,這一習慣隻有當原始的數組聲明是在生存期内才适用。

對于那些願意使用c風格字元串的人來說,一個遵循指針和數組符号概念之間互相作用的常用習慣是:

程式清單2.8 說明數組名是指針

程式清單2.9 使用索引和指針傳遞數組

這就把一個字元串拷貝到另一個字元串,同時確定沒有溢出并且字元串沒有被劃上界限(假設n沒有超限)—所有這些都在一個簡短的語句當中實作。

在指針和數組名之間有另一個差別需要記住:一個數組名是一個不可改變的左值。這就意味着不能改變數組名對應的位址,就像下面的示例所嘗試的那樣:

如果這樣指派,就會很輕易地丢失數組在記憶體中存儲的位置(這可不是個好主意!)。

從字面上來說字元串是一組沒有名稱的字元,可以使用sizeof得到它們的大小并且甚至可以給它們添加下标(見程式清單2.10 和2.11)。注意在清單2.10中我的編譯器把“hello”的每一次的出現都作為一個獨立的對象,每次都傳回不同的位址,有些編譯器能夠把具有相同字元的字元串“集中起來”以單個形式出現以節省空間。

程式清單2.10 說明一個字元串中的字元是一個匿名數組

程式清單2.11 将字元串中的字元進行索引

練習 2.1

已知如下聲明:

下面表達式的結果是什麼?

本文僅用于學習和交流目的,不代表異步社群觀點。非商業轉載請注明作譯者、出處,并保留本文的原始連結。

繼續閱讀