新聞中心

創(chuàng)新互聯(lián)公司-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比隴川網(wǎng)站開(kāi)發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫(kù),直接使用。一站式隴川網(wǎng)站制作公司更省心,省錢(qián),快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋隴川地區(qū)。費(fèi)用合理售后完善,十載實(shí)體公司更值得信賴。
指針
相信大家對(duì)下面的代碼不陌生:
- int i=2;
- int *p;
- p=&i;
這是最簡(jiǎn)單的指針應(yīng)用,也是最基本的用法。再來(lái)熟悉一下什么是指針:首先指針是一個(gè)變量,它保存的并不是平常的數(shù)據(jù),而是變量的地址。如上代碼,指針p中保存的是整型變量i的地址信息。
接下來(lái)看如何定義一個(gè)指針,既然指針也是一個(gè)變量,那么它的定義也和其它變量一樣定義:如:int p;是間接尋址或間接引用運(yùn)算符。上例中我們還看到了一個(gè)特別的運(yùn)算符&,它是一個(gè)取地址運(yùn)算符(在其他合適場(chǎng)合&也是按位運(yùn)算運(yùn)算符,&&為取交集運(yùn)算符)。
在上面的指針定義中,我們看到了定義的是一個(gè)整型指針,難道指針還有類型嗎?答案是肯定的,指針只能指向某種特定類型的對(duì)象,也就是說(shuō),每個(gè)指針都必須指向某種特定的數(shù)據(jù)類型(***的例外:指向void類型的指針可以存放指向任何類型的指針,但它不能間接引用其自身。)。比如,int 類型的指針絕對(duì)不能指向char 類型的變量。
下面我們給出一個(gè)完整的例子來(lái)說(shuō)明指針的簡(jiǎn)單應(yīng)用:
- #include
- void main()
- {
- int a,b,c,*p;
- a=1;
- b=3;
- p=&a;
- b=*p+1;
- c=*(p+1);
- printf("%d %d %d %d /n",a,b,c,*p+3);
- }
運(yùn)行結(jié)果為: 1 2 -858993460 4
這是個(gè)完整的例子,可以自己在機(jī)器上調(diào)試一下,現(xiàn)在很多人用的都是微軟的Visual Studio 開(kāi)發(fā)環(huán)境,有人就不知道在該開(kāi)發(fā)環(huán)境中怎么寫(xiě)C程序以及調(diào)試C程序,具體境況可以參考附錄。
在上面例子中,看到了這樣兩個(gè)表達(dá)式b=p+1;和c=(p+1);前者的意思是p所指的地址里的內(nèi)容加1再賦給b,相當(dāng)于b=a+1;,后者是p所指的地址加1再把(p+1)所指的地址賦給c,當(dāng)然我們不知道p的下一個(gè)地址里放的是什么,所以輸出了一個(gè)隨機(jī)值(這樣的操作時(shí)很危險(xiǎn)的,切記不要使用不確定的內(nèi)存地址)。
數(shù)組
數(shù)組大家應(yīng)該都很熟悉了,用途非常廣泛。
- int a[4]={2,4,5,9};
此語(yǔ)句定義一個(gè)4個(gè)空間大小的整型數(shù)組a并為它進(jìn)行了初始化。
數(shù)組的基礎(chǔ)知識(shí)可以參考其他相應(yīng)的教材,我們?cè)谶@主要討論指針和數(shù)組的結(jié)合應(yīng)用。
我們?cè)賮?lái)看個(gè)完整的例子:
- #include
- void main()
- {
- int a[4]={2,4,5,9};
- int *p;
- p=a;
- *p=*p++;
- printf("%d %d %d/n",*p,*p+6,*(p+1));
- }
運(yùn)行結(jié)果:4 10 5
分析:語(yǔ)句p=a;表示把數(shù)組a的第0個(gè)元素的地址賦給指針p,數(shù)組名a代表的是數(shù)組a的第0個(gè)元素的地址。
a[i]表示數(shù)組a的第i個(gè)元素,如果定義一個(gè)指針p,那么語(yǔ)句p=&a[0];表示可以將指針p指向數(shù)組a的第0個(gè)元素,也就是說(shuō)p的值為數(shù)組元素a[0]的地址。那么(p+1)引用的是數(shù)組元素a[1]的內(nèi)容,p+i是數(shù)組元素a[i]的地址,(p+i)引用的是數(shù)組元素a[i]的內(nèi)容。對(duì)數(shù)組元素a[i]的引用也可以寫(xiě)成(a+i)??梢缘贸鼋Y(jié)論:&a[i]與a+i的含義相同,p[i]與(p+i)也是等價(jià)的。
雖然數(shù)組和指針有這么多通用的地方,但我們必須記住,數(shù)組名和指針之間有一個(gè)不同之處。指針是一個(gè)變量,因此語(yǔ)句p=a和p++都是合法的。但數(shù)組名不是變量,因此,類似于a=p和a++形式的語(yǔ)句是非法的。
下面來(lái)看一個(gè)我們常用的函數(shù)strlen(char *s):
- int strlen(char *s)
- {
- int n;
- for(n=0;*s!='/0';s++)
- n++;
- return n;
- }
因?yàn)閟是一個(gè)指針,所以對(duì)其執(zhí)行自增運(yùn)算是合法的。執(zhí)行s++運(yùn)算不會(huì)影響到strlen函數(shù)的調(diào)用者中的字符串,它僅對(duì)該指針在strlen函數(shù)中的私有副本進(jìn)行自增運(yùn)算。在函數(shù)定義中,形式參數(shù)char s[]和char *s是等價(jià)的。
我們?cè)賮?lái)看一下地址算術(shù)運(yùn)算:如果p是一個(gè)指向數(shù)組中某個(gè)元素的指針,那么p++將對(duì)p進(jìn)行自增運(yùn)算并指向下一個(gè)元素,而p+=i將對(duì)p進(jìn)行加i的增量運(yùn)算,使其指向指針p當(dāng)前所指向元素之后的第i個(gè)元素。同其他類型的變量一樣,指針也可以進(jìn)行初始化。通常,對(duì)指針有意義的初始化值只能是0或者是表示地址的表達(dá)式,對(duì)后者來(lái)說(shuō),表達(dá)式所表達(dá)的地址必須是在此之前已定義的具有適當(dāng)類型的數(shù)據(jù)的地址。任何指針與0進(jìn)行相等或者不相等的比較運(yùn)算都有意義。但是指向不同數(shù)組的元素的指針之間的算術(shù)或比較運(yùn)算沒(méi)有意義。指針還可以和整數(shù)進(jìn)行相加或相減運(yùn)算。如p+n表示指針p當(dāng)前指向的對(duì)象之后第n個(gè)對(duì)象的地址。無(wú)論指針p指向的對(duì)象是何種類型,上述結(jié)論都成立。在計(jì)算p+n時(shí),n將根據(jù)p指向的對(duì)象的長(zhǎng)度按比例縮放,而p指向的對(duì)象的長(zhǎng)度則取決于p的聲明。例如,如果int類型占4個(gè)字節(jié)的存儲(chǔ)空間,那么在int類型的計(jì)算中對(duì)應(yīng)的n將按4的倍數(shù)來(lái)計(jì)算。
指針的減法運(yùn)算也是有意義的,如果p和q指向相同數(shù)組中的元素,且p 程序中,p被初始化為指向s,即指向該字符串的***個(gè)字符,while循環(huán)語(yǔ)句將依次檢查字符串中的每個(gè)字符,直到遇到標(biāo)識(shí)字符數(shù)組結(jié)尾的字符’/0’為止。由于p是指向字符的指針,所以每執(zhí)行以此p++,p就將指向下一個(gè)字符的地址,p-s則表示已經(jīng)檢查過(guò)的字符數(shù),即字符串長(zhǎng)度。 總結(jié):有效的指針運(yùn)算包括相同類型指針之間的賦值運(yùn)算;指針和整數(shù)之間的加減運(yùn)算;指向相同數(shù)組中元素的兩個(gè)指針間的減法或比較運(yùn)算;將指針賦值為0或指針與0之間的比較運(yùn)算。其他所有形式的指針運(yùn)算都是非法的。 再來(lái)看兩條語(yǔ)句: char a[]=”I am a boy”; char *p=”I am a boy”; a是一個(gè)僅僅足以存放初始化字符串以及空字符’/0’的一維數(shù)組。數(shù)組中的單個(gè)字符可以進(jìn)行修改,但a始終指向同一個(gè)存儲(chǔ)位置。而p是一個(gè)指針,其初值指向一個(gè)字符串常量,之后它可以被修改以指向其他地址,但如果試圖修改字符串的內(nèi)容,結(jié)果是沒(méi)有定義的。 為了更容易理解數(shù)組和指針的關(guān)系,我們?cè)賮?lái)看一個(gè)函數(shù): 因?yàn)閰?shù)是通過(guò)值傳遞的,所以在strcpy函數(shù)中可以以任何方式使用參數(shù)s和t。 下面是指針實(shí)現(xiàn)的幾個(gè)版本: 最簡(jiǎn)版本: 這里,s和t的自增運(yùn)算放到了循環(huán)的測(cè)試部分中。表達(dá)式*t++的值是執(zhí)行自增運(yùn)算之前t所指向的字符。后綴運(yùn)算符++表示在讀取該字符之后才改變t的值。同樣,在s執(zhí)行自增運(yùn)算之前,字符就被存儲(chǔ)到了指針s指向的舊位置。上面的版本中表達(dá)式同’/0’的比較是多余的,因?yàn)橹恍枰袛啾磉_(dá)式的值是否為0即可。 指針數(shù)組和指向指針的指針 這兩個(gè)詞次聽(tīng)起來(lái)挺新穎的,到底是什么意思呢? 由于指針本身也是變量,所以它們也可以像其他變量一樣存儲(chǔ)在數(shù)組中。這一點(diǎn)很容易理解。 運(yùn)行結(jié)果:wustrive_2008 這里庫(kù)函數(shù)strlen,strlen為string類的標(biāo)準(zhǔn)庫(kù)函數(shù),所以要包含#include。 下面我們來(lái)自己寫(xiě)一個(gè)strlen函數(shù),我們把上面的例子該成這樣: 這個(gè)運(yùn)行結(jié)果和上個(gè)例子一樣,不一樣的只是我們自己實(shí)現(xiàn)了strlen函數(shù),我們?cè)倬幊虝r(shí)使用的庫(kù)函數(shù),都是語(yǔ)言的開(kāi)發(fā)者或者系統(tǒng)為我們寫(xiě)好了的函數(shù),其實(shí)我們也可以自己寫(xiě)。 這個(gè)例子很好的演示了指針數(shù)組的用法,指針數(shù)組a的值a[1]是一個(gè)指針,指向字符數(shù)組***個(gè)字符。 指針的指針也很好理解,就是一個(gè)指針里放的是另一個(gè)指針的地址,而另一個(gè)指針可能指向一個(gè)變量的地址,還可能指向另一個(gè)指針。 指針和多維數(shù)組 看兩個(gè)定義語(yǔ)句:int a[5][10]; int *b[5]; 從語(yǔ)法角度講,a[3][4]和b[3][4]都是對(duì)一個(gè)int對(duì)象的合法引用。但a是一個(gè)真正的二維數(shù)組,它分配了50個(gè)int類型長(zhǎng)度的存儲(chǔ)空間。但b定義僅僅分配了5個(gè)指針,并且沒(méi)有初始化,它們必須進(jìn)行顯示的初始化,假設(shè)b的每個(gè)元素都指向一個(gè)有10個(gè)元素的數(shù)組,那么編譯器就要為它分配50個(gè)int類型長(zhǎng)度的存儲(chǔ)空間以及5個(gè)指針存儲(chǔ)空間。指針數(shù)組的一個(gè)重要優(yōu)點(diǎn)在于,數(shù)組的每一行長(zhǎng)度可以不同,也就是說(shuō),b的每個(gè)元素不必都指向一個(gè)有10個(gè)元素的向量。 指向函數(shù)的指針: 在C語(yǔ)言中,函數(shù)雖然不是變量,但可以定義指向函數(shù)的指針。這種類型的指針可以被賦值,存放在數(shù)組中,傳遞給函數(shù)以及作為函數(shù)的返回值等。 如果下面的語(yǔ)句為一個(gè)函數(shù)的參數(shù),表示什么意思: 它表明p是一個(gè)指向函數(shù)的指針,該函數(shù)具有兩個(gè)void類型的參數(shù),其返回值類型為int。語(yǔ)句if((p)(v[i],v[left])<0)中,p的使用和其聲明是一致的,p是一個(gè)指向函數(shù)的指針,p代表一個(gè)函數(shù)。如果寫(xiě)成這樣:int p(void ,void )則表明p是一個(gè)函數(shù),該函數(shù)返回一個(gè)int類型的指針。 下面來(lái)看兩個(gè)聲明: int *f(); //f是一個(gè)函數(shù),它返回一個(gè)指向int類型的指針
int (*pf)(); //pf是一個(gè)指向函數(shù)的指針,該函數(shù)返回一個(gè)int類型的對(duì)象。
本文名稱:C語(yǔ)言核心之?dāng)?shù)組和指針詳解
網(wǎng)站路徑:http://www.dlmjj.cn/article/cohiddg.html


咨詢
建站咨詢
