




已閱讀5頁(yè),還剩31頁(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)介
指針的使用,課程安排,指針的概念 指針數(shù)據(jù)類型 指針與其他數(shù)據(jù)類型 指針修飾符,一般的32位CPU都有硬件MMU單元,能將有限的硬件內(nèi)存(如 512M)虛擬成一個(gè)較大(如2G)的虛擬內(nèi)存 這樣軟件可以在一個(gè)非常大的范圍里使用內(nèi)存 每個(gè)內(nèi)存單元(8bits組成一個(gè)內(nèi)存單元byte)都有一個(gè)地址 地址是一個(gè)無(wú)符號(hào)的整數(shù)表示,通常與CPU字長(zhǎng)相等(在32位 CPU上就是4byte的空間),內(nèi)存與地址,1、變量是對(duì)程序中數(shù)據(jù)存儲(chǔ)空間(地址和值)的抽象 int num = 100; printf(“num is %d, num addr is %pn”, num, 3、問(wèn)題是,怎么通過(guò)addr簡(jiǎn)接獲取該地址內(nèi)保存的值(100)?,變量與地址,1、C定義了一種專門(mén)用于表示地址的變量指針 int* addr; /定義指針變量 2、將內(nèi)存中數(shù)據(jù)的地址賦值給指針變量:表示將指針指向該數(shù)據(jù) addr = ,指針的由來(lái),用好指針可以: 使程序簡(jiǎn)潔、緊湊、高效 有效地表示復(fù)雜的數(shù)據(jù)結(jié)構(gòu) 動(dòng)態(tài)分配內(nèi)存 得到多于一個(gè)的函數(shù)返回值 直接操作地址造就了C/C+的強(qiáng)大 用不好指針造成: 非法內(nèi)存訪問(wèn),程序死機(jī)或異常 內(nèi)存泄露,減低系統(tǒng)性能 指針屬于間接訪問(wèn),指來(lái)指去最終變得不可維護(hù),指針是把雙刃劍,課程安排,指針的概念 指針數(shù)據(jù)類型 指針與其他數(shù)據(jù)類型 指針修飾符,指針的定義,實(shí)例:int *pi; char *pc; double* pd; info_t *pinfo; static int *pi; static char *pc; static info_t *pinfo; 關(guān)鍵概念: 1、指針類型與指針指向?qū)ο箢愋?2、指針的值與指針指向?qū)ο蟮闹?指針內(nèi)存大小,指針變量用來(lái)表示內(nèi)存地址,32位CPU上用4byte空間表示地址 int *pi; char *pc; double *pd; info_t *pinfo; sizeof(pi) = ? sizeof(pc) = ? sizeof(pd) = ? sizeof(pinfo) = ?,指針初始化與賦值,1、初始化為指向?qū)ο蟮牡刂?int num = 100; int paddr = ,指針運(yùn)算,1、取值運(yùn)算符 int num = 100; int* paddr = *paddr = ? paddr + 1 = ? *(int*)paddr = ? (int*)paddr + 1 = ?,通用(void)指針,指針變量的類型表示指針?biāo)赶驅(qū)ο蟮念愋?能不能定義一種通用指針,將來(lái)根據(jù)需要再指向特定對(duì)象? void *point = NULL; /void指針,定義不指定指針指向哪種類型數(shù)據(jù) sizeof (point) = ? point+ ? point- ? 使用時(shí)需要進(jìn)行強(qiáng)制類型轉(zhuǎn)換: int num = 100; char ch = a; void *point = NULL; point = ,課程安排,指針的概念 指針數(shù)據(jù)類型 指針與其他數(shù)據(jù)類型 指針修飾符,數(shù)組與指針,1、數(shù)組與指針的關(guān)系 數(shù)組名表示數(shù)組首地址,可以把數(shù)組名可作指針常量 int arr3 = 1, 2, 3; int *p = arr; p+ ? arr+ ? *p = ? *(p+1) = ? *(p + 2) = ? 數(shù)組下標(biāo)操作符內(nèi)部實(shí)現(xiàn)機(jī)制:通過(guò)指針取值運(yùn)算符實(shí)現(xiàn) arr2 相當(dāng)于 *(arr+2) 數(shù)組作為函數(shù)參數(shù),實(shí)際是轉(zhuǎn)化為指針實(shí)現(xiàn) str_cpy(char src, char des) = str_cpy(char *src, char *des) 數(shù)組作為函數(shù)返回值,必須通過(guò)指針實(shí)現(xiàn) char *str_cpy(char *src, char *des),數(shù)組與指針,2、指針數(shù)組:即數(shù)組的元素為指針類型。 char* var10; /10個(gè)int型指針的數(shù)組 sizeof(var) = ? var + 1 ? 3、數(shù)組指針:即指針的類型為數(shù)組(指向數(shù)組的指針)。 char (*var)10; /指向10個(gè)int型數(shù)組的指針 sizeof(var) = ? var + 1 ? 4、字符串與指針 字符串是屬于典型的字符數(shù)組,因而通常通過(guò)char型指針處理字符串,數(shù)組與指針,將字符串直接賦值給指針,表示指針指向字符串內(nèi)存首地址 注意:字符串常量?jī)?nèi)存分配在只讀數(shù)據(jù)區(qū)(RODATA) 實(shí)例:char *p = “xnf”; char arr = “xnf”; *p ? *p+ ? *+p ? *p = X ? arr0 = X ? strcpy(p, “XNF”) ? strcpy(arr, “XNF”) ?,數(shù)組與指針,通過(guò)指針數(shù)組表示字符串?dāng)?shù)組 char a16 = “welcome”, “to”, “xnf”; 主函數(shù)參數(shù)就是通過(guò)指針數(shù)組實(shí)現(xiàn)的: int main (int argc, char *argv),結(jié)構(gòu)與指針,1、結(jié)構(gòu)包含指針:結(jié)構(gòu)體中包含指針域變量 如:學(xué)生信息中name與phone定義為指針 注意:在程序中動(dòng)態(tài)修改學(xué)生信息表中的 name和phone域可行么?,結(jié)構(gòu)與指針,2、指向結(jié)構(gòu)體的指針 結(jié)構(gòu)體變量域通過(guò).訪問(wèn),而結(jié)構(gòu)體指針域通過(guò)-訪問(wèn) sizeof(info) = ? sizeof(p) = ? 下面這段代碼錯(cuò)在哪里?,結(jié)構(gòu)與指針,通過(guò)結(jié)構(gòu)體指針傳遞參數(shù)比直接傳遞結(jié)構(gòu)體變量更高效 實(shí)參傳遞給形參時(shí)只拷貝了4個(gè)字節(jié),指針與指針,1、指向指針變量的指針 int num = 100; int *p = 實(shí)現(xiàn)指針二級(jí)訪問(wèn):,函數(shù)與指針,1、指針作為函數(shù)的參數(shù) 向函數(shù)傳遞數(shù)組、字符串、結(jié)構(gòu): 如strc_py、show_info 作為函數(shù)的輸出參數(shù) 例如:實(shí)現(xiàn)交換兩個(gè)整數(shù)的函數(shù) void swap(int a, int b) 傳值,形參值改變并不能帶回給實(shí)參 傳址,在函數(shù)內(nèi)改變地址內(nèi)保存的內(nèi)容,函數(shù)與指針,問(wèn)題: 要在函數(shù)能改變指針的值,怎么通過(guò)輸出參數(shù)返回? 例如: void get_mem(char *pmem, int size) pmem = malloc(size); 動(dòng)態(tài)分配的內(nèi)存能通過(guò)pmem帶回么? 不能!要將實(shí)參指針的地址傳遞給形參(二級(jí)指針)才能實(shí)現(xiàn)! 更直接的方法是通過(guò)函數(shù)返回值實(shí)現(xiàn),函數(shù)與指針,2、指針作為函數(shù)的返回值 返回字符串、動(dòng)態(tài)分配的內(nèi)存等,如 *strcpy, *malloc 注意返回地址的有效性(函數(shù)執(zhí)行完畢后該地址未被回收) 下面兩個(gè)函數(shù)哪個(gè)是合法的?,函數(shù)與指針,3、指向函數(shù)的指針 函數(shù)存放在TEXT段,同樣具有地址 函數(shù)名就是函數(shù)在TEXT段的入口地址 跟數(shù)組名一樣,函數(shù)名也可以看作是一個(gè)指針常量 所以,函數(shù)名也可以賦值給指針變量,那么該指針變量類型呢? 函數(shù)指針類型!通過(guò)函數(shù)指針,也可以間接調(diào)用函數(shù)。,函數(shù)與指針,函數(shù)指針的應(yīng)用: 1、作為函數(shù)參數(shù)實(shí)現(xiàn)回調(diào)函數(shù) 所謂回調(diào)函數(shù)是指通過(guò)調(diào)用其他函數(shù)反 過(guò)來(lái)調(diào)用某個(gè)函數(shù) 模擬面向?qū)ο蟮亩鄳B(tài),在UI組件的大量使 用,函數(shù)與指針,2、作為結(jié)構(gòu)體的動(dòng)作域 模擬面向?qū)ο蟮念?,在Linux內(nèi)核中大量使用 作為一個(gè)現(xiàn)實(shí)中的對(duì)象,不但有數(shù)據(jù)屬性,還需要有行為屬性 使用對(duì)象行為,課程安排,指針的概念 指針數(shù)據(jù)類型 指針與其他數(shù)據(jù)類型 指針修飾符,const修飾符,1、const修飾符的作用:限定一個(gè)變量不允許被改變(只讀) 如:const int num = 100; /num是只讀整型變量 const int arr3 = 10, 20, 30; /arr是只讀整型數(shù)組 num = 200 ? arr0 = 100 ? arr1 = 200? 2、const指針: 指向變量的只讀指針,指針本身只讀,但指向的對(duì)象非只讀 如:int num1 = 100; int num2 = 200; int* const p = *p = 200 ? p = &num2 ?,const修飾符,3、指向const變量的指針: 指向只讀變量的指針,而指針本身不是只讀的 如: const int num1 = 100; const int num2 = 200; const int *p = *p = 200 ? p = &num2 ?,volatile修飾符,1、編譯器總是試圖優(yōu)化編譯使代碼運(yùn)行得更快 如果程序中變量未被改變,對(duì)變量的訪問(wèn)盡量用寄存器代替內(nèi)存儲(chǔ)存 寄存器屬于CPU內(nèi)部的存儲(chǔ)單元,比起內(nèi)存訪問(wèn)來(lái)得更快 2、但對(duì)于硬件驅(qū)動(dòng)程序來(lái)說(shuō),這樣做就存在風(fēng)險(xiǎn) const unsigned int *paddr = 0x0012ff7c; /假定0x0012ff7c表示一個(gè)網(wǎng)卡內(nèi)存地址 data = *paddr; /第一次取網(wǎng)卡數(shù)據(jù) data = *paddr; /第二次取網(wǎng)卡數(shù)據(jù) 由于*paddr從未被程序改變,所以第二次取值從寄存器中進(jìn)行,跟第一次值一樣 但網(wǎng)卡內(nèi)存數(shù)據(jù)會(huì)隨時(shí)在通信中發(fā)生改變!,volatile修飾符,3、使用volatile修飾符 volatile告訴編譯器,不要對(duì)其修飾的變量作優(yōu)化 總是從內(nèi)存進(jìn)行讀寫(xiě),而不是僅僅在寄存器 volatile const unsigned int *p = 0x0012ff7c; /假定0x0012ff7c表示一個(gè)網(wǎng)卡內(nèi)存地址,typedef修飾符,1、指針相關(guān)數(shù)據(jù)類型,typedef修飾符,2、更復(fù)雜的指針相關(guān)數(shù)據(jù)類型 從變量名括號(hào)開(kāi)始解釋,括號(hào)外面表示類型可以用typedef自定義類型來(lái)簡(jiǎn)化 int (*p3)(int); typedef int (func_t)(int); /定義返回整數(shù)的函數(shù)類型 funct_t *p3; /定義包含3個(gè)函數(shù)指針的數(shù)組 int *(*p3)(int); typedef int *(func_t)(int); /定義返回整數(shù)指針的函數(shù)類型 func_t *p3; /定義包含3個(gè)函數(shù)指針的數(shù)組,typedef修飾符,int (*p)3(int); /錯(cuò)誤,不能聲明函數(shù)的數(shù)組 如何定義指向包含3個(gè)返回整數(shù)函數(shù)指針數(shù)組的指針? typedef int (func_t)(int); /定義返回整型函數(shù)指針類型 typedef func_t *pfarr_t3; /定義包含3個(gè)函數(shù)指針數(shù)組類型 pfarr_t *p; /定義指向數(shù)組的指針,上機(jī)實(shí)驗(yàn),1、指針應(yīng)用 (1)用指針實(shí)現(xiàn)char* str_cpy(char *des, char *src)
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 公司茶藝活動(dòng)策劃方案
- 公司春節(jié)游園活動(dòng)方案
- 公司聚會(huì)創(chuàng)意活動(dòng)方案
- 公司無(wú)人文關(guān)懷活動(dòng)方案
- 公司端午宣傳活動(dòng)方案
- 公司舞會(huì)活動(dòng)方案
- 公司春節(jié)留守活動(dòng)方案
- 公司景區(qū)活動(dòng)策劃方案
- 公司熱極年會(huì)活動(dòng)方案
- 公司知識(shí)闖關(guān)活動(dòng)方案
- 高血壓病人個(gè)體化健康教育方案
- 腦挫傷患者的護(hù)理
- 腰椎間盤(pán)突出癥手術(shù)的圍手術(shù)期護(hù)理
- 警衛(wèi)道路培訓(xùn)課件
- 感染性疾病分子診斷試劑行業(yè)深度調(diào)研及發(fā)展戰(zhàn)略咨詢報(bào)告
- GB/T 45355-2025無(wú)壓埋地排污、排水用聚乙烯(PE)管道系統(tǒng)
- 安全生產(chǎn)風(fēng)險(xiǎn)防控課件
- ISO45001 2024職業(yè)健康安全管理體系要求及使用指南
- 2025年湖南株洲南方中學(xué)自主招生英語(yǔ)試卷真題(含答案詳解)
- 勞務(wù)綠化合同范本
- 2025年云南黃金礦業(yè)集團(tuán)股份有限公司招聘筆試參考題庫(kù)含答案解析
評(píng)論
0/150
提交評(píng)論