嵌入式C編程01指針的使用.ppt_第1頁
嵌入式C編程01指針的使用.ppt_第2頁
嵌入式C編程01指針的使用.ppt_第3頁
嵌入式C編程01指針的使用.ppt_第4頁
嵌入式C編程01指針的使用.ppt_第5頁
已閱讀5頁,還剩31頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

指針的使用,課程安排,指針的概念 指針數(shù)據(jù)類型 指針與其他數(shù)據(jù)類型 指針修飾符,一般的32位CPU都有硬件MMU單元,能將有限的硬件內(nèi)存(如 512M)虛擬成一個較大(如2G)的虛擬內(nèi)存 這樣軟件可以在一個非常大的范圍里使用內(nèi)存 每個內(nèi)存單元(8bits組成一個內(nèi)存單元byte)都有一個地址 地址是一個無符號的整數(shù)表示,通常與CPU字長相等(在32位 CPU上就是4byte的空間),內(nèi)存與地址,1、變量是對程序中數(shù)據(jù)存儲空間(地址和值)的抽象 int num = 100; printf(“num is %d, num addr is %pn”, num, 3、問題是,怎么通過addr簡接獲取該地址內(nèi)保存的值(100)?,變量與地址,1、C定義了一種專門用于表示地址的變量指針 int* addr; /定義指針變量 2、將內(nèi)存中數(shù)據(jù)的地址賦值給指針變量:表示將指針指向該數(shù)據(jù) addr = ,指針的由來,用好指針可以: 使程序簡潔、緊湊、高效 有效地表示復(fù)雜的數(shù)據(jù)結(jié)構(gòu) 動態(tài)分配內(nèi)存 得到多于一個的函數(shù)返回值 直接操作地址造就了C/C+的強(qiáng)大 用不好指針造成: 非法內(nèi)存訪問,程序死機(jī)或異常 內(nèi)存泄露,減低系統(tǒng)性能 指針屬于間接訪問,指來指去最終變得不可維護(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)存大小,指針變量用來表示內(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ū)ο蟮念愋?能不能定義一種通用指針,將來根據(jù)需要再指向特定對象? void *point = NULL; /void指針,定義不指定指針指向哪種類型數(shù)據(jù) sizeof (point) = ? point+ ? point- ? 使用時需要進(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ī)制:通過指針取值運(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ù)返回值,必須通過指針實(shí)現(xiàn) char *str_cpy(char *src, char *des),數(shù)組與指針,2、指針數(shù)組:即數(shù)組的元素為指針類型。 char* var10; /10個int型指針的數(shù)組 sizeof(var) = ? var + 1 ? 3、數(shù)組指針:即指針的類型為數(shù)組(指向數(shù)組的指針)。 char (*var)10; /指向10個int型數(shù)組的指針 sizeof(var) = ? var + 1 ? 4、字符串與指針 字符串是屬于典型的字符數(shù)組,因而通常通過char型指針處理字符串,數(shù)組與指針,將字符串直接賦值給指針,表示指針指向字符串內(nèi)存首地址 注意:字符串常量內(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ù)組與指針,通過指針數(shù)組表示字符串?dāng)?shù)組 char a16 = “welcome”, “to”, “xnf”; 主函數(shù)參數(shù)就是通過指針數(shù)組實(shí)現(xiàn)的: int main (int argc, char *argv),結(jié)構(gòu)與指針,1、結(jié)構(gòu)包含指針:結(jié)構(gòu)體中包含指針域變量 如:學(xué)生信息中name與phone定義為指針 注意:在程序中動態(tài)修改學(xué)生信息表中的 name和phone域可行么?,結(jié)構(gòu)與指針,2、指向結(jié)構(gòu)體的指針 結(jié)構(gòu)體變量域通過.訪問,而結(jié)構(gòu)體指針域通過-訪問 sizeof(info) = ? sizeof(p) = ? 下面這段代碼錯在哪里?,結(jié)構(gòu)與指針,通過結(jié)構(gòu)體指針傳遞參數(shù)比直接傳遞結(jié)構(gòu)體變量更高效 實(shí)參傳遞給形參時只拷貝了4個字節(jié),指針與指針,1、指向指針變量的指針 int num = 100; int *p = 實(shí)現(xiàn)指針二級訪問:,函數(shù)與指針,1、指針作為函數(shù)的參數(shù) 向函數(shù)傳遞數(shù)組、字符串、結(jié)構(gòu): 如strc_py、show_info 作為函數(shù)的輸出參數(shù) 例如:實(shí)現(xiàn)交換兩個整數(shù)的函數(shù) void swap(int a, int b) 傳值,形參值改變并不能帶回給實(shí)參 傳址,在函數(shù)內(nèi)改變地址內(nèi)保存的內(nèi)容,函數(shù)與指針,問題: 要在函數(shù)能改變指針的值,怎么通過輸出參數(shù)返回? 例如: void get_mem(char *pmem, int size) pmem = malloc(size); 動態(tài)分配的內(nèi)存能通過pmem帶回么? 不能!要將實(shí)參指針的地址傳遞給形參(二級指針)才能實(shí)現(xiàn)! 更直接的方法是通過函數(shù)返回值實(shí)現(xiàn),函數(shù)與指針,2、指針作為函數(shù)的返回值 返回字符串、動態(tài)分配的內(nèi)存等,如 *strcpy, *malloc 注意返回地址的有效性(函數(shù)執(zhí)行完畢后該地址未被回收) 下面兩個函數(shù)哪個是合法的?,函數(shù)與指針,3、指向函數(shù)的指針 函數(shù)存放在TEXT段,同樣具有地址 函數(shù)名就是函數(shù)在TEXT段的入口地址 跟數(shù)組名一樣,函數(shù)名也可以看作是一個指針常量 所以,函數(shù)名也可以賦值給指針變量,那么該指針變量類型呢? 函數(shù)指針類型!通過函數(shù)指針,也可以間接調(diào)用函數(shù)。,函數(shù)與指針,函數(shù)指針的應(yīng)用: 1、作為函數(shù)參數(shù)實(shí)現(xiàn)回調(diào)函數(shù) 所謂回調(diào)函數(shù)是指通過調(diào)用其他函數(shù)反 過來調(diào)用某個函數(shù) 模擬面向?qū)ο蟮亩鄳B(tài),在UI組件的大量使 用,函數(shù)與指針,2、作為結(jié)構(gòu)體的動作域 模擬面向?qū)ο蟮念悾贚inux內(nèi)核中大量使用 作為一個現(xiàn)實(shí)中的對象,不但有數(shù)據(jù)屬性,還需要有行為屬性 使用對象行為,課程安排,指針的概念 指針數(shù)據(jù)類型 指針與其他數(shù)據(jù)類型 指針修飾符,const修飾符,1、const修飾符的作用:限定一個變量不允許被改變(只讀) 如:const int num = 100; /num是只讀整型變量 const int arr3 = 10, 20, 30; /arr是只讀整型數(shù)組 num = 200 ? arr0 = 100 ? arr1 = 200? 2、const指針: 指向變量的只讀指針,指針本身只讀,但指向的對象非只讀 如: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)行得更快 如果程序中變量未被改變,對變量的訪問盡量用寄存器代替內(nèi)存儲存 寄存器屬于CPU內(nèi)部的存儲單元,比起內(nèi)存訪問來得更快 2、但對于硬件驅(qū)動程序來說,這樣做就存在風(fēng)險 const unsigned int *paddr = 0x0012ff7c; /假定0x0012ff7c表示一個網(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ù)會隨時在通信中發(fā)生改變!,volatile修飾符,3、使用volatile修飾符 volatile告訴編譯器,不要對其修飾的變量作優(yōu)化 總是從內(nèi)存進(jìn)行讀寫,而不是僅僅在寄存器 volatile const unsigned int *p = 0x0012ff7c; /假定0x0012ff7c表示一個網(wǎng)卡內(nèi)存地址,typedef修飾符,1、指針相關(guān)數(shù)據(jù)類型,typedef修飾符,2、更復(fù)雜的指針相關(guān)數(shù)據(jù)類型 從變量名括號開始解釋,括號外面表示類型可以用typedef自定義類型來簡化 int (*p3)(int); typedef int (func_t)(int); /定義返回整數(shù)的函數(shù)類型 funct_t *p3; /定義包含3個函數(shù)指針的數(shù)組 int *(*p3)(int); typedef int *(func_t)(int); /定義返回整數(shù)指針的函數(shù)類型 func_t *p3; /定義包含3個函數(shù)指針的數(shù)組,typedef修飾符,int (*p)3(int); /錯誤,不能聲明函數(shù)的數(shù)組 如何定義指向包含3個返回整數(shù)函數(shù)指針數(shù)組的指針? typedef int (func_t)(int); /定義返回整型函數(shù)指針類型 typedef func_t *pfarr_t3; /定義包含3個函數(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. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論