c语言指针概述,C语言指针概述.doc
首先,我們來看一看指針有什么用?
講道理的話,如果你到目前沒有發(fā)現(xiàn)指針有什么用,那就不用,挺好的。
你看C++程序員做個(gè)軟件也基本不會(huì)把C++的語言特性都用上是吧。你有數(shù)組,有結(jié)構(gòu)體,有函數(shù),什么事情做不成呢?
是吧。直到有一天,你遇見了這樣一個(gè)問題:試編寫一個(gè)函數(shù)swap(x, y)使得其能夠交換x和y兩個(gè)變量的值這個(gè)……
很簡單嘛。我開始寫:
void swap(int x, int y)
{
int tmp = x;
x = y;
y = tmp;
}
然后你調(diào)用一下,發(fā)現(xiàn)……咦,怎么沒用。
啊啊啊啊啊!好難過好難過,怎么回事?
你上網(wǎng)求助,發(fā)現(xiàn)大神們告訴你要用指針寫,像這樣:
void swap(int * x, int * y)
{
int tmp = *x;
*x = *y;
*y = tmp;
}
然后調(diào)用的時(shí)候swap(&a, &b);就行了。
哇啊啊啊好神奇!
于是,指針的第一個(gè)用處出來了:它能使得函數(shù)有能力交換兩個(gè)變量的值。
怎么做到的呢?我們來看看。
我相信你已經(jīng)知道了,每一個(gè)變量都有屬于自己的一塊空間,那這塊空間在哪里呢?
答案是:內(nèi)存,哦不!準(zhǔn)確一點(diǎn)說是虛擬內(nèi)存 (Virtual Memory) 里。
那計(jì)算機(jī)怎么知道我要找的是變量b的空間而不是a的空間呢?
是因?yàn)槊恳粋€(gè)變量所屬的空間都有一個(gè)惟一的地址,計(jì)算機(jī)只要通過這個(gè)“地址”,就可以找到里面的值了。
這種根據(jù)一個(gè)地址就能直接訪問到一塊內(nèi)存空間的方式,我們叫做隨機(jī)讀取。
具體它是如何做到的,可以去看看Charles Petzold的《編碼》一書,里面甚至從最基本的電路一步一步講起,構(gòu)造一臺最基本的計(jì)算設(shè)備。
還有一個(gè)問題是,如果我的變量占有多個(gè)空間(字節(jié)),但是一個(gè)地址只能對應(yīng)一個(gè)空間,那我們又有兩個(gè)問題:如果我們要用一個(gè)地址代表整個(gè)變量所占的內(nèi)存空間(假設(shè)4個(gè)字節(jié)),我這四個(gè)空間是從前向后排還是從后向前排?比方說我變量的值是AE 01 08 82,那我在內(nèi)存里從前向后的排序到底是82 08 01 AE還是AE 01 08 82?我怎么知道我叫這個(gè)名字的變量占幾個(gè)空間?第一個(gè)問題顯然又是信仰之爭。所謂從前向后的,我們叫做大端序 (big-endian);另一種,我們叫做小端序 (little-endian),大端序與小端序的轉(zhuǎn)換在網(wǎng)絡(luò)傳輸?shù)臅r(shí)候會(huì)用到,Intel的CPU大多采用的都是小端序。
而第二個(gè)問題,由于C里每個(gè)變量都有自己的類型,所以編譯器會(huì)根據(jù)不同類型的各自尺寸生成相應(yīng)的代碼。說這么多干什么呢?
只是為了讓你更好地明白,你在程序里定義的變量乃至函數(shù)代碼,全都是存儲(chǔ)在隨機(jī)存儲(chǔ)器(內(nèi)存)里的。
每個(gè)變量都有自己的起始地址,即屬于自己的一塊位置。那指針是什么呢?指針當(dāng)然也是變量咯,指針也跟其他類型的變量一樣,有自己的一塊空間,空間里的二進(jìn)制位構(gòu)成了一個(gè)值。
這個(gè)值可以是任意的,你甚至可以把它當(dāng)作整數(shù)來用。(沒記錯(cuò)的話,指針的本質(zhì)類型應(yīng)該是unsigned long。即無符號的長整形數(shù)據(jù))
而指針跟其它變量類型的根本性不同在于,它有一個(gè)取值的運(yùn)算符,即*符號。
因?yàn)樗梢匀≈?#xff0c;所以指針類型的變量就不僅可以有自己的值,也可以“操縱”其它變量的值了。
無論是多么復(fù)雜的指針,本質(zhì)上它們的存在都跟這個(gè)*操作有關(guān)。回到我們開始說的那個(gè)swap函數(shù)。
為什么第一種寫法無法達(dá)成交換兩個(gè)變量值的效果?
原因跟指針無關(guān),跟函數(shù)參數(shù)的傳遞方式相關(guān)。原因可以用一句話來解釋:你的swap函數(shù)里出現(xiàn)的x和y,跟你傳參數(shù)進(jìn)去時(shí)候的a和b,根本沒有指向同樣的內(nèi)存地址。
當(dāng)函數(shù)調(diào)用的時(shí)候,a和b被復(fù)制了一份給了x和y變量。
你在swap函數(shù)里對x和y進(jìn)行的所有操作,都是對這兩塊新的內(nèi)存地址里的值進(jìn)行操作,影響不到a和b的內(nèi)容。你不是沒有交換東西,只是被交換了的x和y在swap函數(shù)調(diào)用結(jié)束之后空間就被回收了而已。(回收的概念如果不懂得會(huì)可以理解為銷毀)
這種“把傳進(jìn)去的參數(shù)復(fù)制一份”的方式叫做值傳遞。
而在其他一些語言比如C++或者Visual Basic里面,還存在一種傳參數(shù)的方式叫引用傳遞,即函數(shù)里面的參數(shù)和傳進(jìn)去的參數(shù),指向同樣的內(nèi)存地址。(引用的傳遞是在C++;里面有的,純C語言沒有)
在純C里面,我們不存在引用傳遞,因此要模擬引用傳遞的效果,只能用指針來實(shí)現(xiàn)。
第二個(gè)函數(shù)調(diào)用的方法有點(diǎn)不太一樣,是swap(&a, &b),比起上一個(gè)版本多了&符號。這個(gè)符號的意思是“取地址”,函數(shù)的形式參數(shù)是兩個(gè)指針,在調(diào)用的時(shí)候本質(zhì)上也是值傳遞,只不過這次復(fù)制的不是a和b的值,而是a和b的地址。
在函數(shù)內(nèi)部,我的x和y兩個(gè)指針也是兩塊獨(dú)立的空間,有各自的內(nèi)存地址。
只是它們的值對應(yīng)了a和b兩個(gè)變量的地址,所以我用*操作,就可以完成“操控
總結(jié)
以上是生活随笔為你收集整理的c语言指针概述,C语言指针概述.doc的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 印度语中的lata是什么?
- 下一篇: c语言程序的多文件组织,C代码多文件的组