在C語言中,指針和數(shù)組是兩個密不可分的概念,所以在我們正確區(qū)分它們的恩怨糾葛之前,先要正確理解一下“指針”和“數(shù)組”的概念。
摘要:在C語言中指針是教學中最大的難點,在學習初,尤其對數(shù)組和指針的相關(guān)語法感到非常“糾結(jié)”,常常一頭霧水。那么,指針和數(shù)組到底有什么關(guān)系呢?在我們還不了解的時候,我們不防先這樣告訴自己:“它們之間沒有任何關(guān)系。”該文將幫助您辨明指針與數(shù)組之間的“思思怨怨”。
關(guān)鍵詞:指針,數(shù)組,指向,常量,變量
1什么是指針
關(guān)于“指針”一詞,在K&R中是這樣描述的:指針是一種保存變量地址的變量。所以一量說到“指針”,我們就很自然的想起“指針變量”,就要把它當作變量的意思。比如:char*p1;int*p2;float*p3;double*p4,這最基本的寫法。但是,這只表示該指針指向某類型的數(shù)據(jù),而不表示該指針的類型。說白了,指針都是一個類型:四字節(jié)無符號整數(shù)。
以C語言標準中最初出現(xiàn)“指針”一詞的部分,有這樣的一段描述:
指針類型(pointertype)可由函數(shù)類型、對象類型或不完全的類型派生,派生指針類型的類型稱為引用類型。指針類型描述一個對象,該類對象的值提供對該引用類型實體的引用。由引用類型T派生的指針類型有時稱為“指向T的指針”。從引用類型構(gòu)造指針類型的過程稱為“指針類型的派生”。這些構(gòu)造派生類型的方法可以遞歸地應用。
解釋一下上面的話,也就是說,指針類型不是單獨存在的,而是依附于派生出它的基類型,也就是上面那段話中最關(guān)鍵的一句:“由引用類型T派生的指針類型有時稱為‘指向T的指針’”,即可以有“指向int的指針類型”、“指向float的指針類型”等等。
既然“指針類型”也是類型,那么就該和基本數(shù)據(jù)類型中的int、float、double一也存在該類型的變量,以及該類型變量所對應的值,即“指針類型變量”和“指針類型的值”。
2C語言中數(shù)組值得注意的地方
什么是數(shù)組?大多數(shù)的教科書上是這樣描述的:“數(shù)組是一組有固定數(shù)目的、有序的、相同數(shù)據(jù)類型的元素的集合。”但我想說兩點,我所理解的數(shù)組。
1)C語方中只有一維數(shù)組,而且數(shù)組的大小在編譯期就必須是一個明確的常量確定了下來。那你一定會問,那多維數(shù)組呢?其實,多維數(shù)據(jù)只是由一維數(shù)組“仿真”出來的。也就是說,數(shù)組的元素可以是任何類型對象,那么我們只要把一維數(shù)組中的每一個元素都定為另一個一維數(shù)組,那多維數(shù)組就被仿真出來了。
2)要想操控一個數(shù)組,我們只要確定兩件事,一是確定該數(shù)組的大小,二是獲得指向該數(shù)組下標為0的元素的指針。有的時候,對數(shù)組的操作是靠下標運算來控制的,但這只是一個表面現(xiàn)象,實際都是通過指針進行的。也就是說,數(shù)組的下標運算等同于一個對應的指針運算,所以我們完全可以依據(jù)指針行為定義數(shù)組的下標行為?磥砦覀儾荒苷f“指針”和“數(shù)組”之間沒有任何關(guān)系。但是,我依然要強調(diào),指針就是指針,數(shù)據(jù)依就是數(shù)組。
3指針和數(shù)組并不是相等的
是的,指針就是指針,數(shù)據(jù)依就是數(shù)組。它們并不是相等的。為了說明這個概念,請看下面的聲明:
Intx[5];
Int*y;
x和y能互換使用嗎?可以嗎?它們都具有指針值,也就是說他們的值都是個地址,它們都可以進行間接訪問和下標引用操作,盡管這樣,答案仍然是,它們不能互換使用,它們存在著相當大的區(qū)別。
在這里,x的值是一個常量,指向存放數(shù)組x這段空間的起始位置。而聲明指針變量時,編譯器只為指針本身保留內(nèi)存空間(32位系統(tǒng)下,永遠占4個字節(jié),其值為某一個內(nèi)存的地址。)它并不為任何整型值分配內(nèi)存空間,而且,在沒有對其初始化之間,該變量并未被安排指向任何現(xiàn)有的內(nèi)存空間。當然,如果它再是一個auto,它甚至于根本不會被初始化。
有了上面的定義,讓我們來看看這幾個表達式,看看它們是不是合法的:
*x它是完全合法的;
*y它是非法的,因為這是將訪問內(nèi)存中某個不確定的位置,計算機可沒那么聰明;
y++它也可以通過編譯;
x++它不能通過編譯,因為x是數(shù)組名,數(shù)組名是一個常量,是不能進行自增自減運算的。
4以指針的形式訪問指針和以下標的形式訪問指針
讓我們舉個小例子:Char*p=”abcdef”;對于這個定義,如果現(xiàn)在我想讀取字符‘e’我們要怎么處理呢?有兩種方法:
1)*(p+4):這是以指針形式來讀取的,先取出p里存放的地址(假定地址是Ox1111ff00),加四個字符的偏移量,新地址應該是Ox1111ff04,然后取出Ox1111ff04這個地址里取放的值,這個值就是我們要讀取的’e’。
2)p[4]:這是以下標的形式讀取的,先取出p里存儲的地址值;再加上中括號中四個元素的偏移量,計算出新地址,然后從新地址中取出值來。我們可以看到,這兩種方法并沒有本質(zhì)的區(qū)別,只是表現(xiàn)形式即寫法的不同而已。
5)以指針的形式訪問數(shù)組和以下標的形式訪問數(shù)組
再來看下面這個例子:Charx[]=”123456”;對于這個定義,如果現(xiàn)在想讀取字符‘5’我們要怎么處理呢?也有兩種方法:
1)*(x+4):這是以指針形式來讀取的,x這里代表的是數(shù)組元素的首地址(假定地址是Ox1111ff00),再加上四個字符的偏移量,得到新地址Ox1111ff04,然后取出Ox1111ff04這個地址里取放的值,這個值就是我們要讀取的’5’。
2)x[4]:這是以下標的形式讀取的,x作為數(shù)組首地址,再加上中括號內(nèi)四個元素的偏移量,計算出新地址,然后從新的地址中取出值’5’。
還有一件事請大家注意,這里所說的偏移量帶表的是元素個數(shù),而不是字節(jié)數(shù),比如上面例子中偏移量為4,是指4個元素,而不是4個字符,只是因為一個字符本來大小就是1個字節(jié),所以地址從Ox1111ff00,偏移后變成Ox1111ff04,如果是整型或其它類型就要重新計算了。
通過上面的分析,我們對指針和數(shù)組又了更深層次、更清晰的了解,指針和數(shù)組真真的、的的確確的是兩回事,在應用過程中一定不能把它們混淆,但是我們可以以指針的形式訪問指針、以下標的形式訪問指針,當然也可以,以指針的形式訪問數(shù)組、或以下標的形式訪問數(shù)組。當然僅僅是理解還是不夠的,我們必須通過大量的實踐才能做到真正的運用自如。
參考文獻:
[1]譚浩強.C語言程序設計[M].北京:清華大學出版社,2010.
[2]楊智明.C語言指針使用分析[J].保山學院學報,2012(2).
[3]趙忠孝,楊亞蕾.對C語言指針教學問題的探究[J].計算機教育,2009(19).
[4]徐輝,王安民.關(guān)于C語言中使用指針作為函數(shù)參數(shù)的問題[J].電腦編程技巧與維護,2009(18).
[5]AndrewKoenig.C陷阱與缺陷[M].北京:人民郵電出版,2011.
[6]前橋和彌.征服C指針[M].北京:人民郵電出版,2011.
[7]KennethA.Reek.C和指針[M].北京:人民郵電出版,2010.
轉(zhuǎn)載請注明來自:http://www.jinnzone.com/dianzijishulw/28952.html