




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、linux c中指針的使用 學號:姓名: 1、指針的概念 指針是一個特殊的變量,它里面存儲的數值被解釋成為內存里的一個地址。 把一個變量所在的內存單元的地址保存在另外一個內存單元中,保存地址的這個內存單元稱為指針。 重點:指針的四方面的內容:指針的類型、指針所指向的類型、指針的值(或者叫指針所指向的內存區)、指針本身所占據的內存區。 (1)指針的類型 判斷指針類型的方法:把指針聲明語句里的指針名字去掉,剩下的部分就是這個指針的類型。 如:int*ptr;/指針的類型是int* char*ptr;/指針的類型是char* int*ptr;/指針的類型是int* int(*ptr)3;/指針的類型
2、是int(*)3 int*(*ptr)4;/指針的類型是int*(*)4 (2)指針所指向的類型 把指針聲明語句中的指針名字和名字左邊的指針聲明符*去掉,剩下的就是指針所指向的類型。 int*ptr; /指針所指向的類型是int char*ptr; /指針所指向的的類型是char int*ptr; /指針所指向的的類型是int* int(*ptr)3; /指針所指向的的類型是int()3 int*(*ptr)4; /指針所指向的的類型是int*()4 .(3)指針的值-或者叫指針所指向的內存區或地址 指針的值是指針本身存儲的數值,這個值將被編譯器當作一個地址,而不是一個一般的數值。 在32位程
3、序里,所有類型的指針的值都是一個32位整數,因為32位程序里內存地址全都是32位長。 指針所指向的內存區就是從指針的值所代表的那個內存地址開始,長度為sizeof(指針所指向的類型)的一片內存區。 (4)指針本身所占據的內存區 只要用函數sizeof(指針的類型)測一下就可以知道。在32位平臺里,指針本身占據了4個字節的長度。在64位平臺上指針變量都占8個字節。 注意: sizeof(指針的名稱)測到的是指針自身類型的大小。 2、指針中&和* &是取地址運算符,*號是指針間接尋址運算符。&i表示取變量 i 的地址。*pi表示取指針pi 所指向的變量的值。 &運算符的操作數必須是左值,因為只有左
4、值才表示一個內存單元,才會有地址, 運算結果是指針類型。 *運算符的操作數必須是指針類型,運算結果可以做左值。 3、指針類型轉換 指針之間可以相互賦值,也可以用一個指針初始化另一個指針,例如: int *ptri = pi; 或者: int *ptri; ptri = pi; 本質上就是把變量pi所保存的地址值賦 給變量ptri。 用一個指針給另一個指針賦值時要注意,兩個指針必須是同一類型的。不是同一類型時可以進行強制類型轉換然后賦值。 例如: float f=12.3; float *fptr=&f; int *p; 假如我們想讓指針p指向實數f,該怎么辦? p=&f;不對。因為指針p的類型
5、是int *,它指向的類型是int。表達式&f 的結果是一個指針,指針的類型是float *,它指向的類型是float。 強制類型轉換。 p=(int*)&f; 如果有一個指針p,我們需要把它的類型和所指向的類型改為type* 、type, 那么語法格式是: (type *)p; 這樣強制類型轉換的結果是一個新指針,該新指針的類型是type *,它指向的類型是type,它指向的地址就是原指針指向的地址。而原來的指針p的一切屬性都沒有被修改。4、算數運算 指針可以加上或減去一個整數。指針的這種運算的意義和通常的數值的加減運算的意義是不一樣的,以單元為單位。 例1:char a20; int *p
6、tr=(int *)a; /強制類型轉換并不會改變a的類型 ptr+; 第3句中,指針ptr被加了1,編譯器是這樣處理的:它把指針ptr的值加上了sizeof(int),在32位程序中,是被加上了4,因為在32位程序中,int占4個字節。 由于地址是用字節做單位的,故ptr所指向的地址由原來的變量a的地址向高地址方向增加了4個字節。由于char類型的長度是一個字節,所以,原來ptr是指向數組a的第0號單元開始的四個字節,此時指向了數組a中從第4號單元開始的四個字節。 一個指針ptrold 加(減)一個整數n 后,結果是一個新的指針ptrnew,ptrnew的類型和ptrold的類型相同,ptr
7、new所指向的類型和ptrold所指向的類型也相同。ptrnew的值將比ptrold的值增加(減少)了n乘sizeof(ptrold所指向的類型)個字節。 兩個指針不能進行加法運算,這是非法操作,沒意義。 兩個指針可以進行減法操作,但必須類型相同 。 指針之間的進行比較運算比的是地址。 5、指針表達式 一個表達式的結果如果是一個指針,那么這個表達式就叫指針表式。 由于指針表達式的結果是一個指針,所以指針表達式也具有指針所具有的四個要素:指針的類型,指針所指向的類型,指針指向的內存區,指針自身占據的內存。 當一個指針表達式的結果指針已經明確地具有了指針自身占據的內存的話,這個指針表達式就是一個左
8、值,否則就不是一個左值。 6、數組和指針的關系 數組的數組名其實可以看作一個指針。 聲明了一個數組type arrayn,則數組名稱array就有了兩重含義:第一,它代表整個數組,它的類型是typen;第二 ,它是一個常量指針,該指針的類型是type*,該指針指向的類型是type,也就是數組單元的類型,該指針指向的內存區就是數組第0號單元,該指針自己占有單獨的內存區,注意它和數組第0號單元占據的內存區是不同的。該指針的值是不能修改的,即類似array+的表達式是錯誤的。 例:int array10=0,1,2,3,4,5,6,7,8,9,value; value=array0; /也可寫成:v
9、alue=*array; value=array3; /也可寫成:value=*(array+3); value=array4; /也可寫成:value=*(array+4); 上例中,一般而言數組名array代表數組本身,類型是int10,但如果把array看做指針的話,它指向數組的第0個單元,類型是int*,所指向的類型是數組單元的類型即int。array+3是一個指向數組第3個單元的指針,所以*(array+3)等于3。 字符串相當于是一個數組,在內存中以數組的形式儲存,只不過字符串是一個數組常量,內容不可改變,且只能是右值.如果看成指針的話,他即是常量指針,也是指針常量. 7、指針和結
10、構類型的關系 可以聲明一個指向結構類型對象的指針。例子如下:struct mystructint a;int b;int c;struct mystruct ss=20,30,40;/聲明了結構對象ss,并把ss 的成員初始化為20,30 和40。struct mystruct *ptr=&ss;/聲明了一個指向結構對象ss的指針。它的類型是mystruct *,它指向的類型是mystruct.。 通過指針p訪問結構體成員可以寫成(*ptr).a、(*ptr).b和(*ptr).c,為了書寫方便,c 語言提供了-運算符,也可以寫成ptr-a和ptr-b、ptr-b。 8 8、指針與函數的關系、
11、指針與函數的關系 可以把一個指針聲明成為一個指向函數的指針。函數指針存放的就是函數的入口地址。 int fun1(char *,int); int (*pfun1)(char *,int); pfun1=fun1; int a=(*pfun1)(abcdefg,7); /通過函數指針調用函數。可以把指針作為函數的形參。在函數調用語句中,可以用指針表達式來作為實參。 一個函數如果使用了指針作為形參,那么在函數調用語句的實參和形參的結合過程中,必須保證類型一致 ,否則需要強制轉換. 分析一下變量f的類型聲明int(*pfun1)( char*,int),pfun1首先跟*號結合在一起, 因此是一個
12、指針。(*pfun1)外面是一個函數原型的格式,參數是char *和int,返回值是int,所以pfun1是指向這種函數的指針。 9、指針的安全問題(1)意外改寫數據 例子:char a; int *ptr=&a; ptr+; *ptr=115; 該例子完全可以通過編譯,并能執行。但是,第3句對指針ptr進行自加1運算后,ptr指向了和整形變量a相鄰的高地址方向的一塊存儲區。這塊存儲區里是什么?我們不知道。有可能它是一個非常重要的數據,甚至可能是一條代碼。而第4句竟然往這片存儲區里寫入一個數據!這是嚴重的錯誤。 為了避免這種情況可以使用const限定符。 const int *a; int c
13、onst *a; 這兩種寫法是一樣的,a是一個指向const int型的指針,a所指向的內存單元 不可改寫,所以(*a)+是不允許的,但a可以改寫,所以a+是允許的。 int * const a; a是一個指向int型的const指針,*a是可以改寫的,但a不允許改寫。 int const * const a; a是一個指向const int型的const指針,因此*a和a都不允許改寫。 指向非const變量的指針或者非const變量的地址可以傳給指向const變量的指 針,編譯器可以做隱式類型轉換,例如: char c = a; const char *pc = &c; 但是,指向const
14、變量的指針或者const變量的地址不可以傳給指向非const變量的指針,以免透過后者意外改寫了前者所指向的內存單元。 (2)出現“野指令 ” 有一種情況需要特別注意,定義一個指針類型的局 部變量而沒有初始化: int main(void) int *p; . *p = 0; . 在堆棧上分配的變量初始值是不確定的,也就是說指針p所指向的內存地址是不確定的,后面用*p訪問不確定的地址就會導致不確定的后果。于是很容易出現”野指令“。 我們常把指向不確定地址的指針稱為野指針(unbound pointer),為避免出現野指針,在定義指針變量時就應該給它明確的初值,或 者把它初始化為null: int main(void) int *p = null; . *p = 0; . null在c標準庫的頭文件stddef.h中定義:#define null (void *)0) 就是把地址0轉換成指針類型,稱為空指針,它的特殊之處在于,操作系統不會 把任何數據保存在地址0及其附近,也不會把地址00 xfff的頁面映射到物理內 存,所以任何對地
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 房地產委托代辦合同
- 養殖場抵押借款合同
- 工地施工人員勞務合同
- 《室內設計手繪快速表現》中職全套教學課件
- 出售土地房屋合同范本
- 學校超市采購合同范本
- 基地養殖花卉合同范本
- 營銷策劃 -可口可樂OBPPC渠道營銷原理
- 北京2025年七年級英語下學期期中模擬卷(二)-解析版
- 鞋子采購合同范本模板
- T-CNHAW 0011-2024 干眼診療中心分級建設要求
- 2025屆湖北省武漢市重點中學高三第一次模擬考試數學試卷含解析
- 2023年國際貿易試題庫
- 商務樓裝修施工合同
- 中建幕墻高處防墜落專項方案方案
- 九下語文教材課后習題答案
- 2024年10月自考13887經濟學原理中級試題及答案含評分參考
- 孕產婦高危五色管理(醫學講座培訓課件)
- 2024年市場調研委托合同
- 地方導游基礎知識電子教案 專題七 學習情境四 新疆維吾爾自治區課時教案
- 2024年煙草知識考試題庫
評論
0/150
提交評論