從一道面試題談談數(shù)組與指針的差別

如果遇到的面試多了,大抵會被問到這樣一個問題:數(shù)組和指針有什么區(qū)別?這也是一道非?;A但不乏精華的題目,所能得到的答案也可謂是五花八門,但不外乎如下幾類:概念復述,具體使用,能否改變。

概念復述:數(shù)組是內存中長度確定的連續(xù)單元排列,而指針則是包含了單個單元地址的特殊單元。

簡單而又直接,直接列出概念,前者是一群單元,而后者是一個單元。但這顯然不是一個完整的答案。

具體使用:在全局下,數(shù)組與指針的長度不同,而對于函數(shù)而言,數(shù)組不能被傳入函數(shù),會被替換成一個指針。

類似的答案還有很多,無非在強調數(shù)組和指針在使用(引用元素)上的種種差別。然而本質上可以歸納為下列一句話:

數(shù)組在應用元素時直接對數(shù)組地址符號的值作偏移,而指針在引用元素時則先讀取指針單元中的地址的值,再按該值進行尋址。

這里我為了突出兩個值的差別,敘述的比較拗口,其實這個答案的要素在于數(shù)組和指針的符號對于編譯器而言是兩個不同的東西,如果寫成代碼,事情其實很明了:


       int a[10];

       int* b = a;

       cout << "a = " << a<< "   &a = "<< &a << "  sizeof(a) = " << sizeof(a) << endl;

       cout << "b = " << b<< "   &b = "<< &b << "  sizeof(b) = " << sizeof(b) << endl;

數(shù)組和指針

上述的代碼昭示了幾個信息 數(shù)組的(首地址)值等于其取地址的結果,而指針不然;數(shù)組與指針長度是不一樣的,前者是所聲明數(shù)組的長度,后者則僅僅是一個指針的大小。

回到剛才的討論:所有的符號都會被編譯器放在一張符號表中,這張表也會標注其相關的類別,對于數(shù)組,編譯器直接在出現(xiàn)這個符號的地方用那個地址去作替換,并完成相關的尋址和偏移工作,因此會有a == &a。而對于指針,則會先讀取存放在指針這個地址的單元的“值”,并把該值作為一個待尋地址,對其進行尋址。簡而言之,數(shù)組是地址符號,指針是存值單元,指針多了一次讀取的步驟。而這樣的差異,則造成了數(shù)組與指針在所有使用細節(jié)上的不同。

能否改變:數(shù)組不能改變,指針可以改變。

這個切入點在我看來可以說有些刁鉆了,因為一般而言,不會有人會覺得數(shù)組本身(地址)有什么修改的意義,因而這樣的角度有些刻意為之。然而要較真地去剖析,不得不承認事實確實如此。從這個角度切入的人一般會認同一種觀點,即數(shù)組與指針在本質上沒有差別——均為指針,不過數(shù)組多了一個const限定。因此如下的代碼是不合法的:


Int a[10];

++ a;

編譯器給出的解釋為:表達式必須是能修改的左值。這恰也符合試圖修改const的情況。

由此來看,上述的觀點完全成立,但是考慮到第二個角度,這個觀點又明顯相悖,這里我不打算深究數(shù)組的本質,畢竟要不要把數(shù)組理解為指針確實是個因人而異的話題,這里我選擇文字上做一個妥協(xié),在最終的敘述上作一點修正:數(shù)組是一個const地址符號,而指針則是一個非const的存址單元。

抽象觀念:數(shù)組是一個元素內在關聯(lián)的線性表,而指針是一個獨立的迭代器

一般而言,如果能系統(tǒng)地從上述角度去表述這些差異,再畫上一兩張好看的圖示,可以說是非常完整了,然而我在閱讀Andrew Koenig / Barbara Moo的《C++沉思錄》時,作者提出了這樣一種觀點——數(shù)組(或者索引)本身提供了特殊的抽象含義,那些偏移本身就具有其意義,即使數(shù)組消失了也是如此。而指針的價值在于通過指針,便提供了額外的對象信息,能夠用來構造出更通用的程序。

上述的區(qū)別可以說相當?shù)奶亓ⅹ毿辛?,我認為作者在此處不是從語法或實現(xiàn)上,而是更多地從算法或抽象觀念的角度上來理解問題,看起來有些抽象,其實這個觀念是很直觀的,要說明這個問題,請直接讀一讀如下的代碼吧:


a[2] = 3;

*(a + 2) = 3;

兩句代碼實現(xiàn)了一樣的功能,但卻給了人不一樣的感覺。對于第一句,我們會說:給a的第二個元素賦值3;而對于第二句,除非我們明白地知道a是一個數(shù)組,否則我們往往會說:給a后面的第二個單元賦值3。這個表述上的差異正如作者所言,索引本身具有含義,它表征了各元素的內在聯(lián)系,數(shù)組的長度情況,以及數(shù)組作為一個整體而存在等諸多概念。而指針則更加獨立,即使它被放入一個指針,也往往被割裂而存在。

至于說指針提供了對象信息,我認為有些晦澀了。對此我的理解是提供索引來進行元素訪問時解引用過程默認發(fā)生了,而指針則需要手動解引用,顯然解引用后的對象便被限定了類型,而指針則可以通過多態(tài)等手段有著更多發(fā)揮空間。這個解釋也有些刻意為之了,希望日后能悟到新的見解吧。

總而言之,數(shù)組與指針的差異:可以從概念復述,具體使用,能否改變和抽象觀念四個方面來思考。有的觀點有些過于刁鉆,但這也表明了C++的魅力所在——多去思考,便能窺見新天地。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容