linuxC中指針的使用.ppt_第1頁(yè)
linuxC中指針的使用.ppt_第2頁(yè)
linuxC中指針的使用.ppt_第3頁(yè)
linuxC中指針的使用.ppt_第4頁(yè)
linuxC中指針的使用.ppt_第5頁(yè)
已閱讀5頁(yè),還剩21頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

linux C中指針的使用,學(xué)號(hào): 姓名:,1、指針的概念 指針是一個(gè)特殊的變量,它里面存儲(chǔ)的數(shù)值被解釋成為內(nèi)存里的一個(gè)地址。 把一個(gè)變量所在的內(nèi)存單元的地址保存在另外一個(gè)內(nèi)存單元中,保存地址的這個(gè)內(nèi)存單元稱為指針。 重點(diǎn):指針的四方面的內(nèi)容:指針的類(lèi)型、指針?biāo)赶虻念?lèi)型、指針的值(或者叫指針?biāo)赶虻膬?nèi)存區(qū))、指針本身所占據(jù)的內(nèi)存區(qū)。,(1)指針的類(lèi)型 判斷指針類(lèi)型的方法:把指針聲明語(yǔ)句里的指針名字去掉,剩下的部分就是這個(gè)指針的類(lèi)型。 如:int*ptr;/指針的類(lèi)型是int* char*ptr;/指針的類(lèi)型是char* int*ptr;/指針的類(lèi)型是int* int(*ptr)3;/指針的類(lèi)型是int(*)3 int*(*ptr)4;/指針的類(lèi)型是int*(*)4,.(3)指針的值-或者叫指針?biāo)赶虻膬?nèi)存區(qū)或地址 指針的值是指針本身存儲(chǔ)的數(shù)值,這個(gè)值將被編譯器當(dāng)作一個(gè)地址,而不是一個(gè)一般的數(shù)值。 在32位程序里,所有類(lèi)型的指針的值都是一個(gè)32位整數(shù),因?yàn)?2位程序里內(nèi)存地址全都是32位長(zhǎng)。 指針?biāo)赶虻膬?nèi)存區(qū)就是從指針的值所代表的那個(gè)內(nèi)存地址開(kāi)始,長(zhǎng)度為sizeof(指針?biāo)赶虻念?lèi)型)的一片內(nèi)存區(qū)。,(4)指針本身所占據(jù)的內(nèi)存區(qū) 只要用函數(shù)sizeof(指針的類(lèi)型)測(cè)一下就可以知道。在32位平臺(tái)里,指針本身占據(jù)了4個(gè)字節(jié)的長(zhǎng)度。在64位平臺(tái)上指針變量都占8個(gè)字節(jié)。 注意: sizeof(指針的名稱)測(cè)到的是指針自身類(lèi)型的大小。,2、指針中&和* &是取地址運(yùn)算符,*號(hào)是指針間接尋址運(yùn)算符。&i表示取變量 i 的地址。*pi表示取指針pi 所指向的變量的值。 &運(yùn)算符的操作數(shù)必須是左值,因?yàn)橹挥凶笾挡疟硎疽粋€(gè)內(nèi)存單元,才會(huì)有地址, 運(yùn)算結(jié)果是指針類(lèi)型。 *運(yùn)算符的操作數(shù)必須是指針類(lèi)型,運(yùn)算結(jié)果可以做左值。,3、指針類(lèi)型轉(zhuǎn)換 指針之間可以相互賦值,也可以用一個(gè)指針初始化另一個(gè)指針,例如: int *ptri = pi; 或者: int *ptri; ptri = pi; 本質(zhì)上就是把變量pi所保存的地址值賦 給變量ptri。 用一個(gè)指針給另一個(gè)指針賦值時(shí)要注意,兩個(gè)指針必須是同一類(lèi)型的。不是同一類(lèi)型時(shí)可以進(jìn)行強(qiáng)制類(lèi)型轉(zhuǎn)換然后賦值。,例如: float f=12.3; float *fptr= 不對(duì)。因?yàn)橹羔榩的類(lèi)型是int *,它指向的類(lèi)型是int。表達(dá)式&f 的結(jié)果是一個(gè)指針,指針的類(lèi)型是float *,它指向的類(lèi)型是float。,強(qiáng)制類(lèi)型轉(zhuǎn)換。 p=(int*) 如果有一個(gè)指針p,我們需要把它的類(lèi)型和所指向的類(lèi)型改為T(mén)YPE* 、TYPE, 那么語(yǔ)法格式是: (TYPE *)p; 這樣強(qiáng)制類(lèi)型轉(zhuǎn)換的結(jié)果是一個(gè)新指針,該新指針的類(lèi)型是TYPE *,它指向的類(lèi)型是TYPE,它指向的地址就是原指針指向的地址。而原來(lái)的指針p的一切屬性都沒(méi)有被修改。,4、算數(shù)運(yùn)算 指針可以加上或減去一個(gè)整數(shù)。指針的這種運(yùn)算的意義和通常的數(shù)值的加減運(yùn)算的意義是不一樣的,以單元為單位。 例1:char a20; int *ptr=(int *)a; /強(qiáng)制類(lèi)型轉(zhuǎn)換并不會(huì)改變a的類(lèi)型 ptr+; 第3句中,指針ptr被加了1,編譯器是這樣處理的:它把指針ptr的值加上了sizeof(int),在32位程序中,是被加上了4,因?yàn)樵?2位程序中,int占4個(gè)字節(jié)。 由于地址是用字節(jié)做單位的,故ptr所指向的地址由原來(lái)的變量a的地址向高地址方向增加了4個(gè)字節(jié)。由于char類(lèi)型的長(zhǎng)度是一個(gè)字節(jié),所以,原來(lái)ptr是指向數(shù)組a的第0號(hào)單元開(kāi)始的四個(gè)字節(jié),此時(shí)指向了數(shù)組a中從第4號(hào)單元開(kāi)始的四個(gè)字節(jié)。,一個(gè)指針ptrold 加(減)一個(gè)整數(shù)n 后,結(jié)果是一個(gè)新的指針ptrnew,ptrnew的類(lèi)型和ptrold的類(lèi)型相同,ptrnew所指向的類(lèi)型和ptrold所指向的類(lèi)型也相同。ptrnew的值將比ptrold的值增加(減少)了n乘sizeof(ptrold所指向的類(lèi)型)個(gè)字節(jié)。 兩個(gè)指針不能進(jìn)行加法運(yùn)算,這是非法操作,沒(méi)意義。 兩個(gè)指針可以進(jìn)行減法操作,但必須類(lèi)型相同 。 指針之間的進(jìn)行比較運(yùn)算比的是地址。,5、指針表達(dá)式 一個(gè)表達(dá)式的結(jié)果如果是一個(gè)指針,那么這個(gè)表達(dá)式就叫指針表式。 由于指針表達(dá)式的結(jié)果是一個(gè)指針,所以指針表達(dá)式也具有指針?biāo)哂械乃膫€(gè)要素:指針的類(lèi)型,指針?biāo)赶虻念?lèi)型,指針指向的內(nèi)存區(qū),指針自身占據(jù)的內(nèi)存。 當(dāng)一個(gè)指針表達(dá)式的結(jié)果指針已經(jīng)明確地具有了指針自身占據(jù)的內(nèi)存的話,這個(gè)指針表達(dá)式就是一個(gè)左值,否則就不是一個(gè)左值。,6、數(shù)組和指針的關(guān)系 數(shù)組的數(shù)組名其實(shí)可以看作一個(gè)指針。 聲明了一個(gè)數(shù)組TYPE arrayn,則數(shù)組名稱array就有了兩重含義:第一,它代表整個(gè)數(shù)組,它的類(lèi)型是TYPEn;第二 ,它是一個(gè)常量指針,該指針的類(lèi)型是TYPE*,該指針指向的類(lèi)型是TYPE,也就是數(shù)組單元的類(lèi)型,該指針指向的內(nèi)存區(qū)就是數(shù)組第0號(hào)單元,該指針自己占有單獨(dú)的內(nèi)存區(qū),注意它和數(shù)組第0號(hào)單元占據(jù)的內(nèi)存區(qū)是不同的。該指針的值是不能修改的,即類(lèi)似array+的表達(dá)式是錯(cuò)誤的。,例:int array10=0,1,2,3,4,5,6,7,8,9,value; value=array0; /也可寫(xiě)成:value=*array; value=array3; /也可寫(xiě)成:value=*(array+3); value=array4; /也可寫(xiě)成:value=*(array+4); 上例中,一般而言數(shù)組名array代表數(shù)組本身,類(lèi)型是int10,但如果把a(bǔ)rray看做指針的話,它指向數(shù)組的第0個(gè)單元,類(lèi)型是int*,所指向的類(lèi)型是數(shù)組單元的類(lèi)型即int。array+3是一個(gè)指向數(shù)組第3個(gè)單元的指針,所以*(array+3)等于3。 字符串相當(dāng)于是一個(gè)數(shù)組,在內(nèi)存中以數(shù)組的形式儲(chǔ)存,只不過(guò)字符串是一個(gè)數(shù)組常量,內(nèi)容不可改變,且只能是右值.如果看成指針的話,他即是常量指針,也是指針常量.,7、指針和結(jié)構(gòu)類(lèi)型的關(guān)系 可以聲明一個(gè)指向結(jié)構(gòu)類(lèi)型對(duì)象的指針。例子如下: struct MyStruct int a; int b; int c; ; struct MyStruct ss=20,30,40;/聲明了結(jié)構(gòu)對(duì)象ss,并把ss 的成員初始化為20,30 和40。 struct MyStruct *ptr=/聲明了一個(gè)指向結(jié)構(gòu)對(duì)象ss的指針。它的類(lèi)型是MyStruct *,它指向的類(lèi)型是MyStruct.。 通過(guò)指針p訪問(wèn)結(jié)構(gòu)體成員可以寫(xiě)成(*ptr).a、(*ptr).b和(*ptr).c,為了書(shū)寫(xiě)方便,C 語(yǔ)言提供了-運(yùn)算符,也可以寫(xiě)成ptr-a和ptr-b、ptr-b。,8、指針與函數(shù)的關(guān)系 可以把一個(gè)指針聲明成為一個(gè)指向函數(shù)的指針。函數(shù)指針存放的就是函數(shù)的入口地址。 int fun1(char *,int); int (*pfun1)(char *,int); pfun1=fun1; int a=(*pfun1)(“abcdefg“,7); /通過(guò)函數(shù)指針調(diào)用函數(shù)??梢园阎羔樧鳛楹瘮?shù)的形參。在函數(shù)調(diào)用語(yǔ)句中,可以用指針表達(dá)式來(lái)作為實(shí)參。 一個(gè)函數(shù)如果使用了指針作為形參,那么在函數(shù)調(diào)用語(yǔ)句的實(shí)參和形參的結(jié)合過(guò)程中,必須保證類(lèi)型一致 ,否則需要強(qiáng)制轉(zhuǎn)換.,分析一下變量f的類(lèi)型聲明int(*pfun1)( char*,int),pfun1首先跟*號(hào)結(jié)合在一起, 因此是一個(gè)指針。(*pfun1)外面是一個(gè)函數(shù)原型的格式,參數(shù)是char *和int,返回值是int,所以pfun1是指向這種函數(shù)的指針。,9、指針的安全問(wèn)題 (1)意外改寫(xiě)數(shù)據(jù) 例子:char a; int *ptr= 該例子完全可以通過(guò)編譯,并能執(zhí)行。但是,第3句對(duì)指針ptr進(jìn)行自加1運(yùn)算后,ptr指向了和整形變量a相鄰的高地址方向的一塊存儲(chǔ)區(qū)。這塊存儲(chǔ)區(qū)里是什么?我們不知道。有可能它是一個(gè)非常重要的數(shù)據(jù),甚至可能是一條代碼。而第4句竟然往這片存儲(chǔ)區(qū)里寫(xiě)入一個(gè)數(shù)據(jù)!這是嚴(yán)重的錯(cuò)誤。,為了避免這種情況可以使用const限定符。 const int *a; int const *a; 這兩種寫(xiě)法是一樣的,a是一個(gè)指向const int型的指針,a所指向的內(nèi)存單元 不可改寫(xiě),所以(*a)+是不允許的,但a可以改寫(xiě),所以a+是允許的。 int * const a; a是一個(gè)指向int型的const指針,*a是可以改寫(xiě)的,但a不允許改寫(xiě)。 int const * const a; a是一個(gè)指向const int型的const指針,因此*a和a都不允許改寫(xiě)。,指向非const變量的指針或者非const變量的地址可以傳給指向const變量的指 針,編譯器可以做隱式類(lèi)型轉(zhuǎn)換,例如: char c = a; const char *pc = 但是,指向const變量的指針或者const變量的地址不可以傳給指向非const變量的指針,以免透過(guò)后者意外改寫(xiě)了前者所指向的內(nèi)存單元。,(2)出現(xiàn)“野指令 ” 有一種情況需要特別注意,定義一個(gè)指針類(lèi)型的局 部變量而沒(méi)有初始化: int main(void) int *p; . *p = 0; . 在堆棧上分配的變量初始值是不確定的,也就是說(shuō)指針p所指向的內(nèi)存地址是不確定的,后面用*p訪問(wèn)不確定的地址就會(huì)導(dǎo)致不確定的后果。于是很容易出現(xiàn)”野指令“。,我們常把指向不確定地址的指針?lè)Q為“野指針“(Unbound Pointer),為避免出現(xiàn)野指針,在定義指針變量時(shí)就應(yīng)該給它明確的初值,或 者把它初始化為NULL: int main(void) int *p = NULL; . *p = 0; . ,NULL在C標(biāo)準(zhǔn)庫(kù)的頭文件stddef.h中定義:#define NULL (void *)0) 就是把地址0轉(zhuǎn)換成指針類(lèi)型,稱為空指針,它的特殊之處在于,操作系統(tǒng)不會(huì) 把任何數(shù)據(jù)保存在地址0及其附近,也不會(huì)把地址00xfff的頁(yè)面映射到物理內(nèi) 存,所以任何對(duì)地址0的訪問(wèn)都會(huì)立刻導(dǎo)致段錯(cuò)誤

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論