C語言的指針,是C語言里最為靈活最有力量也最容易產(chǎn)生問題的強力武器。數(shù)組相對來講花樣少一些,但也有些比較容易出問題的知識點。
如果你想系統(tǒng)深入了解指針,我推薦你完整系統(tǒng)的閱讀這幾本書《C Programming language》也就是(K&R圣書),第二本是《C專家編程》,里面關(guān)于數(shù)組與指針的闡述盡管已經(jīng)過去十多年依然是熠熠生輝,沒有其它書籍能趕上,另外還可以看看《C與指針》這本書,其實也是一本C語言系統(tǒng)教材,把指針單獨提出了,也體現(xiàn)了指針的強大威力,還有一本是《C陷阱與缺陷》,也是非常值得一讀。
如果看完這些書,可以看看幾個專門闡述C指針或者包含相關(guān)內(nèi)容的文檔,比如:
http://home.netcom.com/~tjensen/ptr/pointers.htm A TUTORIAL ON POINTERS AND ARRAYS IN C
http://publications.gbdirect.co.uk/c_book/ 這本書在線免費閱讀
http://boredzo.org/pointers/ Everything you need to know about pointers in C
http://www.cs.cf.ac.uk/Dave/C/node10.html Common Pointer Pitfalls 這是從wiki的pointer頁面上發(fā)現(xiàn)的
http://www.knosof.co.uk/cbook/cbook.html New C Standard, 云風(fēng)在他的blog推薦過。
http://learn.akae.cn/media/index.html Linux C編程一站式學(xué)習(xí)
———————————
C語言中的指針是什么,數(shù)組是什么,該如何定義初始化,我在這里不多講,任何一本C語言的教材或者我前面推薦的K&R都有很詳細的解釋。
關(guān)于指針與數(shù)組最經(jīng)常提到的問題就是在定義為functionA(int * p),然后可以直接把int numArray[5]這樣的數(shù)組直接作為參數(shù)傳入,或者聲明declaration與定義definition不匹配,如extern定義為char* 但是實際上是char[]。
其實我們只要記住指針與數(shù)組的幾個不同點,到時候類似問題就很容易搞掂了。在《C專家編程》里面列出一些,我這里簡述一下:
第一點也是最關(guān)鍵一點,指針訪問是間接的,也就是指針存放的是一個地址的值,存放的是被指內(nèi)容的地址,其實類似一個中轉(zhuǎn)站或者114的功能,如果想取得指針?biāo)赶虻膬?nèi)容,必須做提領(lǐng)(deference)操作,實際上類似于兩個步驟(先取得指針的內(nèi)容也就是p存放的地址值,然后取得存放地址里面內(nèi)容)。而數(shù)組里存放的就是數(shù)組的值,不是什么間接引用的地址,比如我們要取arr[5]的值,只要從arr開始數(shù)5個位置,里面就是a[5]的內(nèi)容。
另外一點不同是,假如我們有個數(shù)組int array[5],數(shù)組的地址&array與數(shù)組名字array本身代表的地址是不一樣的。&array實際上是一個int (*p1)[5]類型的指針,p1每一步遞增遞減都是sizeof(array),也就是5個int長度。而array相當(dāng)于&array[0],也就是第一個元素(element)的地址,類型是int *p2,p2每一步遞增都是sizeof(int)。這個區(qū)別在指向二維數(shù)組或者多維數(shù)組指針里非常需要注意。
再有一點不同是,一般指針類型(除了int *const p這種)都是沒有名字的,可以隨意的指來指去的,另外指針可以有加減計算,加上減去一定的值。而數(shù)組相當(dāng)于,定義以后就不可以修改數(shù)組地址了,這也是前面一條我都會說有一個p1或者p2指針,而不是數(shù)組array本身。盡管數(shù)組array有類似指針的行為,也是某種地址,但是它不可以進行加減操作,我們可以認為數(shù)組array本身是一個常量。
還有一點不同是,指針可以初始化為NULL,另外可以聲明為void指針,還可以聲明非常復(fù)雜的函數(shù)指針、指針的指針、字符串指針等等,但是數(shù)組沒法定義為函數(shù)數(shù)組。
什么情況下指針與數(shù)組的概念可交換?《C專家編程》總結(jié)的以及相當(dāng)全面,我在這里簡單列兩條,深入的內(nèi)容請看書。1)使用a[i]這種形式對數(shù)組訪問,編譯器改寫為*(a + i)形式,這也是為何i[a]這樣寫也編譯運行通過的原因。2)作為函數(shù)參數(shù)時,數(shù)組會被修改為指向數(shù)組第一個元素的指針。
關(guān)于指針還有很多高階內(nèi)容,比如復(fù)雜的指針聲明該如何解讀?int const * p1與int * const p2的不同之處?sizeof *ptr 與 sizeof ptr結(jié)果?這里就不一一講述了,畢竟這篇文字是給我自己做一個知識備份。如果大家有指針相關(guān)問題,歡迎留言,我會盡量解答。