




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、linuxC中指針的使用linux C中指針的使用 學(xué)號(hào):姓名:linuxC中指針的使用 1、指針的概念 指針是一個(gè)特殊的變量,它里面存儲(chǔ)的數(shù)值被解釋成為內(nèi)存里的一個(gè)地址。 把一個(gè)變量所在的內(nèi)存單元的地址保存在另外一個(gè)內(nèi)存單元中,保存地址的這個(gè)內(nèi)存單元稱為指針。 重點(diǎn):指針的四方面的內(nèi)容:指針的類型、指針?biāo)赶虻念愋?、指針的?或者叫指針?biāo)赶虻膬?nèi)存區(qū))、指針本身所占據(jù)的內(nèi)存區(qū)。linuxC中指針的使用 (1)指針的類型 判斷指針類型的方法:把指針聲明語句里的指針名字去掉,剩下的部分就是這個(gè)指針的類型。 如:int*ptr;/指針的類型是int* char*ptr;/指針的類型是char* i
2、nt*ptr;/指針的類型是int* int(*ptr)3;/指針的類型是int(*)3 int*(*ptr)4;/指針的類型是int*(*)4linuxC中指針的使用 (2)指針?biāo)赶虻念愋?把指針聲明語句中的指針名字和名字左邊的指針聲明符*去掉,剩下的就是指針?biāo)赶虻念愋汀?int*ptr; /指針?biāo)赶虻念愋褪莍nt char*ptr; /指針?biāo)赶虻牡念愋褪莄har int*ptr; /指針?biāo)赶虻牡念愋褪莍nt* int(*ptr)3; /指針?biāo)赶虻牡念愋褪莍nt()3 int*(*ptr)4; /指針?biāo)赶虻牡念愋褪莍nt*()4linuxC中指針的使用 .(3)指針的值-或者叫
3、指針?biāo)赶虻膬?nèi)存區(qū)或地址 指針的值是指針本身存儲(chǔ)的數(shù)值,這個(gè)值將被編譯器當(dāng)作一個(gè)地址,而不是一個(gè)一般的數(shù)值。 在32位程序里,所有類型的指針的值都是一個(gè)32位整數(shù),因?yàn)?2位程序里內(nèi)存地址全都是32位長。 指針?biāo)赶虻膬?nèi)存區(qū)就是從指針的值所代表的那個(gè)內(nèi)存地址開始,長度為sizeof(指針?biāo)赶虻念愋?的一片內(nèi)存區(qū)。linuxC中指針的使用 (4)指針本身所占據(jù)的內(nèi)存區(qū) 只要用函數(shù)sizeof(指針的類型)測一下就可以知道。在32位平臺(tái)里,指針本身占據(jù)了4個(gè)字節(jié)的長度。在64位平臺(tái)上指針變量都占8個(gè)字節(jié)。 注意: sizeof(指針的名稱)測到的是指針自身類型的大小。linuxC中指針的使用 2
4、、指針中&和* &是取地址運(yùn)算符,*號(hào)是指針間接尋址運(yùn)算符。&i表示取變量 i 的地址。*pi表示取指針pi 所指向的變量的值。 &運(yùn)算符的操作數(shù)必須是左值,因?yàn)橹挥凶笾挡疟硎疽粋€(gè)內(nèi)存單元,才會(huì)有地址, 運(yùn)算結(jié)果是指針類型。 *運(yùn)算符的操作數(shù)必須是指針類型,運(yùn)算結(jié)果可以做左值。linuxC中指針的使用 3、指針類型轉(zhuǎn)換 指針之間可以相互賦值,也可以用一個(gè)指針初始化另一個(gè)指針,例如: int *ptri = pi; 或者: int *ptri; ptri = pi; 本質(zhì)上就是把變量pi所保存的地址值賦 給變量ptri。 用一個(gè)指針給另一個(gè)指針賦值時(shí)要注意,兩個(gè)指針必須是同一類型的。不是同一類型
5、時(shí)可以進(jìn)行強(qiáng)制類型轉(zhuǎn)換然后賦值。linuxC中指針的使用 例如: float f=12.3; float *fptr=&f; int *p; 假如我們想讓指針p指向?qū)崝?shù)f,該怎么辦? p=&f;不對(duì)。因?yàn)橹羔榩的類型是int *,它指向的類型是int。表達(dá)式&f 的結(jié)果是一個(gè)指針,指針的類型是float *,它指向的類型是float。linuxC中指針的使用 強(qiáng)制類型轉(zhuǎn)換。 p=(int*)&f; 如果有一個(gè)指針p,我們需要把它的類型和所指向的類型改為TYPE* 、TYPE, 那么語法格式是: (TYPE *)p; 這樣強(qiáng)制類型轉(zhuǎn)換的結(jié)果是一個(gè)新指針,該新指針的類型是TYPE *,它指向的類型
6、是TYPE,它指向的地址就是原指針指向的地址。而原來的指針p的一切屬性都沒有被修改。linuxC中指針的使用4、算數(shù)運(yùn)算 指針可以加上或減去一個(gè)整數(shù)。指針的這種運(yùn)算的意義和通常的數(shù)值的加減運(yùn)算的意義是不一樣的,以單元為單位。 例1:char a20; int *ptr=(int *)a; /強(qiáng)制類型轉(zhuǎn)換并不會(huì)改變a的類型 ptr+; 第3句中,指針ptr被加了1,編譯器是這樣處理的:它把指針ptr的值加上了sizeof(int),在32位程序中,是被加上了4,因?yàn)樵?2位程序中,int占4個(gè)字節(jié)。 由于地址是用字節(jié)做單位的,故ptr所指向的地址由原來的變量a的地址向高地址方向增加了4個(gè)字節(jié)。由
7、于char類型的長度是一個(gè)字節(jié),所以,原來ptr是指向數(shù)組a的第0號(hào)單元開始的四個(gè)字節(jié),此時(shí)指向了數(shù)組a中從第4號(hào)單元開始的四個(gè)字節(jié)。linuxC中指針的使用 一個(gè)指針ptrold 加(減)一個(gè)整數(shù)n 后,結(jié)果是一個(gè)新的指針ptrnew,ptrnew的類型和ptrold的類型相同,ptrnew所指向的類型和ptrold所指向的類型也相同。ptrnew的值將比ptrold的值增加(減少)了n乘sizeof(ptrold所指向的類型)個(gè)字節(jié)。 兩個(gè)指針不能進(jìn)行加法運(yùn)算,這是非法操作,沒意義。 兩個(gè)指針可以進(jìn)行減法操作,但必須類型相同 。 指針之間的進(jìn)行比較運(yùn)算比的是地址。linuxC中指針的使用
8、5、指針表達(dá)式 一個(gè)表達(dá)式的結(jié)果如果是一個(gè)指針,那么這個(gè)表達(dá)式就叫指針表式。 由于指針表達(dá)式的結(jié)果是一個(gè)指針,所以指針表達(dá)式也具有指針?biāo)哂械乃膫€(gè)要素:指針的類型,指針?biāo)赶虻念愋?,指針指向的?nèi)存區(qū),指針自身占據(jù)的內(nèi)存。 當(dāng)一個(gè)指針表達(dá)式的結(jié)果指針已經(jīng)明確地具有了指針自身占據(jù)的內(nèi)存的話,這個(gè)指針表達(dá)式就是一個(gè)左值,否則就不是一個(gè)左值。linuxC中指針的使用 6、數(shù)組和指針的關(guān)系 數(shù)組的數(shù)組名其實(shí)可以看作一個(gè)指針。 聲明了一個(gè)數(shù)組TYPE arrayn,則數(shù)組名稱array就有了兩重含義:第一,它代表整個(gè)數(shù)組,它的類型是TYPEn;第二 ,它是一個(gè)常量指針,該指針的類型是TYPE*,該指針指向
9、的類型是TYPE,也就是數(shù)組單元的類型,該指針指向的內(nèi)存區(qū)就是數(shù)組第0號(hào)單元,該指針自己占有單獨(dú)的內(nèi)存區(qū),注意它和數(shù)組第0號(hào)單元占據(jù)的內(nèi)存區(qū)是不同的。該指針的值是不能修改的,即類似array+的表達(dá)式是錯(cuò)誤的。 linuxC中指針的使用 例:int array10=0,1,2,3,4,5,6,7,8,9,value; value=array0; /也可寫成:value=*array; value=array3; /也可寫成:value=*(array+3); value=array4; /也可寫成:value=*(array+4); 上例中,一般而言數(shù)組名array代表數(shù)組本身,類型是int1
10、0,但如果把a(bǔ)rray看做指針的話,它指向數(shù)組的第0個(gè)單元,類型是int*,所指向的類型是數(shù)組單元的類型即int。array+3是一個(gè)指向數(shù)組第3個(gè)單元的指針,所以*(array+3)等于3。 字符串相當(dāng)于是一個(gè)數(shù)組,在內(nèi)存中以數(shù)組的形式儲(chǔ)存,只不過字符串是一個(gè)數(shù)組常量,內(nèi)容不可改變,且只能是右值.如果看成指針的話,他即是常量指針,也是指針常量. linuxC中指針的使用7、指針和結(jié)構(gòu)類型的關(guān)系 可以聲明一個(gè)指向結(jié)構(gòu)類型對(duì)象的指針。例子如下:struct MyStructint a;int b;int c;struct MyStruct ss=20,30,40;/聲明了結(jié)構(gòu)對(duì)象ss,并把ss
11、的成員初始化為20,30 和40。struct MyStruct *ptr=&ss;/聲明了一個(gè)指向結(jié)構(gòu)對(duì)象ss的指針。它的類型是MyStruct *,它指向的類型是MyStruct.。 通過指針p訪問結(jié)構(gòu)體成員可以寫成(*ptr).a、(*ptr).b和(*ptr).c,為了書寫方便,C 語言提供了-運(yùn)算符,也可以寫成ptr-a和ptr-b、ptr-b。linuxC中指針的使用 8 8、指針與函數(shù)的關(guān)系、指針與函數(shù)的關(guān)系 可以把一個(gè)指針聲明成為一個(gè)指向函數(shù)的指針。函數(shù)指針存放的就是函數(shù)的入口地址。 int fun1(char *,int); int (*pfun1)(char *,int);
12、 pfun1=fun1; int a=(*pfun1)(abcdefg,7); /通過函數(shù)指針調(diào)用函數(shù)。可以把指針作為函數(shù)的形參。在函數(shù)調(diào)用語句中,可以用指針表達(dá)式來作為實(shí)參。 一個(gè)函數(shù)如果使用了指針作為形參,那么在函數(shù)調(diào)用語句的實(shí)參和形參的結(jié)合過程中,必須保證類型一致 ,否則需要強(qiáng)制轉(zhuǎn)換.linuxC中指針的使用 分析一下變量f的類型聲明int(*pfun1)( char*,int),pfun1首先跟*號(hào)結(jié)合在一起, 因此是一個(gè)指針。(*pfun1)外面是一個(gè)函數(shù)原型的格式,參數(shù)是char *和int,返回值是int,所以pfun1是指向這種函數(shù)的指針。linuxC中指針的使用 9、指針的安
13、全問題(1)意外改寫數(shù)據(jù) 例子:char a; int *ptr=&a; ptr+; *ptr=115; 該例子完全可以通過編譯,并能執(zhí)行。但是,第3句對(duì)指針ptr進(jìn)行自加1運(yùn)算后,ptr指向了和整形變量a相鄰的高地址方向的一塊存儲(chǔ)區(qū)。這塊存儲(chǔ)區(qū)里是什么?我們不知道。有可能它是一個(gè)非常重要的數(shù)據(jù),甚至可能是一條代碼。而第4句竟然往這片存儲(chǔ)區(qū)里寫入一個(gè)數(shù)據(jù)!這是嚴(yán)重的錯(cuò)誤。linuxC中指針的使用 為了避免這種情況可以使用const限定符。 const int *a; int const *a; 這兩種寫法是一樣的,a是一個(gè)指向const int型的指針,a所指向的內(nèi)存單元 不可改寫,所以(*a
14、)+是不允許的,但a可以改寫,所以a+是允許的。 int * const a; a是一個(gè)指向int型的const指針,*a是可以改寫的,但a不允許改寫。 int const * const a; a是一個(gè)指向const int型的const指針,因此*a和a都不允許改寫。linuxC中指針的使用 指向非const變量的指針或者非const變量的地址可以傳給指向const變量的指 針,編譯器可以做隱式類型轉(zhuǎn)換,例如: char c = a; const char *pc = &c; 但是,指向const變量的指針或者const變量的地址不可以傳給指向非const變量的指針,以免透過后者意外改寫了
15、前者所指向的內(nèi)存單元。linuxC中指針的使用 (2)出現(xiàn)“野指令 ” 有一種情況需要特別注意,定義一個(gè)指針類型的局 部變量而沒有初始化: int main(void) int *p; . *p = 0; . 在堆棧上分配的變量初始值是不確定的,也就是說指針p所指向的內(nèi)存地址是不確定的,后面用*p訪問不確定的地址就會(huì)導(dǎo)致不確定的后果。于是很容易出現(xiàn)”野指令“。 linuxC中指針的使用 我們常把指向不確定地址的指針稱為野指針(Unbound Pointer),為避免出現(xiàn)野指針,在定義指針變量時(shí)就應(yīng)該給它明確的初值,或 者把它初始化為NULL: int main(void) int *p = NULL; . *p = 0; . linuxC中指針的使用 NULL在C標(biāo)準(zhǔn)庫的頭文件stddef.h中定義:#define NULL (void *)0) 就是把地址0轉(zhuǎn)換成指針類型,稱為空指針,它的特殊之處在于,操作系統(tǒng)不會(huì) 把任何數(shù)據(jù)保存在地址0及其附近,也不會(huì)把地址00 xfff的頁面映射到物理內(nèi) 存,所以任何對(duì)地址0的訪問都會(huì)立刻
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 設(shè)備系統(tǒng)維保合同協(xié)議
- 2025幼兒園數(shù)學(xué)考試題與答案
- 第九章異步電動(dòng)機(jī)基本結(jié)構(gòu)和運(yùn)行分析39課件
- 2025年酒店管理專業(yè)大學(xué)生考試卷及答案
- 第34屆全國中學(xué)生物理競賽復(fù)賽試題
- 快遞代收委托協(xié)議書范本
- 品牌合作解除合同協(xié)議
- 快餐飯店轉(zhuǎn)讓合同協(xié)議
- 員工宿舍外包合同協(xié)議
- 2025年上海住房租賃合同范本參考
- 光伏項(xiàng)目服務(wù)承諾書
- 人教版三年級(jí)下冊(cè)數(shù)學(xué)口算題題卡1000道帶答案可打印
- 竣工結(jié)算審計(jì)服務(wù)投標(biāo)方案(2024修訂版)(技術(shù)方案)
- 《健康成年人身體活動(dòng)能量消耗參考值》
- 熱力學(xué)統(tǒng)計(jì)物理-第四版-汪志誠-課后答案
- 《鐵路工務(wù)維修現(xiàn)場實(shí)戰(zhàn)技巧》課件 任務(wù)2.9軌道檢查儀作業(yè)
- 中國常規(guī)肺功能檢查基層指南(2024年)解讀
- 水域景觀課件用
- 村集體小二型水庫承包協(xié)議書
- 一例乳癌個(gè)案護(hù)理
- DBJ04∕T 290-2012 袖閥管注漿加固地基技術(shù)規(guī)程
評(píng)論
0/150
提交評(píng)論