




版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
1、l嵌入式C編程指針的使用課程安排課程安排n指針的概念指針的概念n指針數(shù)據(jù)類型指針數(shù)據(jù)類型n指針與其他數(shù)據(jù)類型指針與其他數(shù)據(jù)類型n指針修飾符指針修飾符一般的一般的32位位CPU都有硬件都有硬件MMU單元,能將有限的硬件內(nèi)存單元,能將有限的硬件內(nèi)存(如如512M)虛擬成一個較大虛擬成一個較大(如如2G)的虛擬內(nèi)存的虛擬內(nèi)存這樣軟件可以在一個非常大的范圍里使用內(nèi)存這樣軟件可以在一個非常大的范圍里使用內(nèi)存每個內(nèi)存單元(每個內(nèi)存單元(8bits組成一個內(nèi)存單元組成一個內(nèi)存單元byte)都有一個地址)都有一個地址地址是一個無符號的整數(shù)表示,通常與地址是一個無符號的整數(shù)表示,通常與CPU字長相等字長相等(在
2、在32位位CPU上就是上就是4byte的空間的空間)內(nèi)存與地址內(nèi)存與地址1、變量是對程序中數(shù)據(jù)存儲空間、變量是對程序中數(shù)據(jù)存儲空間(地址和值地址和值)的抽象的抽象 int num = 100; printf(“num is %d, num addr is %pn”, num, &num);2、可以將變量的地址保存在一個整型變量中、可以將變量的地址保存在一個整型變量中 unsigned int addr = 0; addr = # printf(“addr is %#xn”, addr);3、問題是,怎么通過、問題是,怎么通過addr簡接獲取該地址內(nèi)保存的值(簡接獲取該地
3、址內(nèi)保存的值(100)?變量與地址變量與地址1、C定義了一種專門用于表示地址的變量定義了一種專門用于表示地址的變量指針指針 int* addr; /定義指針變量定義指針變量2、將內(nèi)存中數(shù)據(jù)的地址賦值給指針變量:表示將指針指向該數(shù)據(jù)、將內(nèi)存中數(shù)據(jù)的地址賦值給指針變量:表示將指針指向該數(shù)據(jù) addr = # /指針變量指針變量addr指向指向num變量變量3、通過指針變量可以間接訪問被指向的數(shù)據(jù)、通過指針變量可以間接訪問被指向的數(shù)據(jù) printf(“num is %dn”, *addr); /通過通過addr獲取獲取num *addr = 200; /通過通過addr修改修改num
4、 printf(“num is %dn”, num);指針的由來指針的由來用好指針可以用好指針可以:使程序簡潔、緊湊、高效使程序簡潔、緊湊、高效有效地表示復雜的數(shù)據(jù)結構有效地表示復雜的數(shù)據(jù)結構動態(tài)分配內(nèi)存動態(tài)分配內(nèi)存得到多于一個的函數(shù)返回值得到多于一個的函數(shù)返回值直接操作地址造就了直接操作地址造就了C/C+的強大的強大用不好指針造成:用不好指針造成:非法內(nèi)存訪問,程序死機或異常非法內(nèi)存訪問,程序死機或異常內(nèi)存泄露,減低系統(tǒng)性能內(nèi)存泄露,減低系統(tǒng)性能指針屬于間接訪問,指來指去最終變得不可維護指針屬于間接訪問,指來指去最終變得不可維護指針是把雙刃劍指針是把雙刃劍課程安排課程安排n指針的概念指針的概
5、念n指針數(shù)據(jù)類型指針數(shù)據(jù)類型n指針與其他數(shù)據(jù)類型指針與其他數(shù)據(jù)類型n指針修飾符指針修飾符指針的定義指針的定義 實例:實例:int *pi; char *pc; double* pd; info_t *pinfo; static int *pi; static char *pc; static info_t *pinfo;關鍵概念:關鍵概念:1、指針類型與指針指向對象類型、指針類型與指針指向對象類型2、指針的值與指針指向對象的值、指針的值與指針指向對象的值 指針內(nèi)存大小指針內(nèi)存大小指針變量用來表示內(nèi)存地址,指針變量用來表示內(nèi)存地址,32位位CPU上用上用4byte空間表示地址空間表示地址int
6、*pi; char *pc; double *pd; info_t *pinfo;sizeof(pi) = ? sizeof(pc) = ? sizeof(pd) = ? sizeof(pinfo) = ?指針初始化與賦值指針初始化與賦值1、初始化為指向對象的地址、初始化為指向對象的地址 int num = 100; int paddr = # /paddr指向指向num2、初始化為空指針、初始化為空指針 int *paddr = NULL; /NULL為為0,表示空地址,表示空地址3、指針變量定義后可以隨時改變所指向的變量、指針變量定義后可以隨時改變所指向的變量 int nu
7、m1 = 100, num2 = 200; int paddr = NULL; paddr = &num1; paddr = &num2;指針運算指針運算1、取值運算符、取值運算符 int num = 100; int* paddr = # 通過通過paddr間接取間接取num值值: *paddr2、取址運算符、取址運算符 &paddr = ?: 表示表示paddr這個指針變量的地址這個指針變量的地址3、加減運算:偏移指針類型字節(jié)數(shù)、加減運算:偏移指針類型字節(jié)數(shù) paddr + 1 = ? paddr + ? paddr 1 = ? paddr- ?4、
8、強制轉換、強制轉換 int num = 100; char *paddr = # *paddr = ? paddr + 1 = ? *(int*)paddr = ? (int*)paddr + 1 = ?通用通用(void)指針指針指針變量的類型表示指針所指向對象的類型指針變量的類型表示指針所指向對象的類型能不能定義一種通用指針,將來根據(jù)需要再指向特定對象?能不能定義一種通用指針,將來根據(jù)需要再指向特定對象?void *point = NULL; /void指針,定義不指定指針指向哪種類型數(shù)據(jù)指針,定義不指定指針指向哪種類型數(shù)據(jù)sizeof (point) = ? point+
9、 ? point- ?使用時需要進行強制類型轉換:使用時需要進行強制類型轉換:int num = 100; char ch = a; void *point = NULL;point = # printf(“num is %dn”, *(int*)point);point = &ch; printf(“ch is %cn”, *(char*)ch); 課程安排課程安排n指針的概念指針的概念n指針數(shù)據(jù)類型指針數(shù)據(jù)類型n指針與其他數(shù)據(jù)類型指針與其他數(shù)據(jù)類型n指針修飾符指針修飾符數(shù)組與指針數(shù)組與指針1、數(shù)組與指針的關系、數(shù)組與指針的關系數(shù)組名表示數(shù)組首地址,可以把數(shù)組名可作指
10、針常量數(shù)組名表示數(shù)組首地址,可以把數(shù)組名可作指針常量 int arr3 = 1, 2, 3; int *p = arr; p+ ? arr+ ? *p = ? *(p+1) = ? *(p + 2) = ?數(shù)組下標操作符內(nèi)部實現(xiàn)機制:通過指針取值運算符實現(xiàn)數(shù)組下標操作符內(nèi)部實現(xiàn)機制:通過指針取值運算符實現(xiàn) arr2 相當于相當于 *(arr+2)數(shù)組作為函數(shù)參數(shù),實際是轉化為指針實現(xiàn)數(shù)組作為函數(shù)參數(shù),實際是轉化為指針實現(xiàn)str_cpy(char src, char des) = str_cpy(char *src, char *des)數(shù)組作為函數(shù)返回值,必須通過指針實現(xiàn)數(shù)組作為函數(shù)返回值,必
11、須通過指針實現(xiàn)char *str_cpy(char *src, char *des) 數(shù)組與指針數(shù)組與指針2、指針數(shù)組:即數(shù)組的元素為指針類型。、指針數(shù)組:即數(shù)組的元素為指針類型。 char* var10; /10個個int型指針的數(shù)組型指針的數(shù)組 sizeof(var) = ? var + 1 ?3、數(shù)組指針:即指針的類型為數(shù)組(指向數(shù)組的指針)。、數(shù)組指針:即指針的類型為數(shù)組(指向數(shù)組的指針)。 char (*var)10; /指向指向10個個int型數(shù)組的指針型數(shù)組的指針 sizeof(var) = ? var + 1 ?4、字符串與指針、字符串與指針字符串是屬于典型的字符數(shù)組,因而通常
12、通過字符串是屬于典型的字符數(shù)組,因而通常通過char型指針處理字符串型指針處理字符串 數(shù)組與指針數(shù)組與指針將字符串直接賦值給指針,表示指針指向字符串內(nèi)存首地址將字符串直接賦值給指針,表示指針指向字符串內(nèi)存首地址注意:字符串常量內(nèi)存分配在只讀數(shù)據(jù)區(qū)(注意:字符串常量內(nèi)存分配在只讀數(shù)據(jù)區(qū)(RODATA)實例:實例:char *p = “xnf”; char arr = “xnf”;*p ? *p+ ? *+p ? *p = X ? arr0 = X ? strcpy(p, “XNF”) ? strcpy(arr, “XNF”) ? 數(shù)組與指針數(shù)組與指針通過指針數(shù)組表示字符串數(shù)組通過指針數(shù)組表示字符
13、串數(shù)組char a16 = “welcome”, “to”, “xnf”; 主函數(shù)參數(shù)就是通過指針數(shù)組實現(xiàn)的主函數(shù)參數(shù)就是通過指針數(shù)組實現(xiàn)的: int main (int argc, char *argv) 結構與指針結構與指針1、結構包含指針:結構體中包含指針域變量、結構包含指針:結構體中包含指針域變量 如:學生信息中如:學生信息中name與與phone定義為指針定義為指針 注意:在程序中動態(tài)修改學生信息表中的注意:在程序中動態(tài)修改學生信息表中的 name和和phone域可行么?域可行么? 結構與指針結構與指針2、指向結構體的指針、指向結構體的指針 結構體變量域通過結構體變量域通過.訪問,而
14、結構體指針域通過訪問,而結構體指針域通過-訪問訪問 sizeof(info) = ? sizeof(p) = ? 下面這段代碼錯在哪里?下面這段代碼錯在哪里? 結構與指針結構與指針 通過結構體指針傳遞參數(shù)比直接傳遞結構體變量更高效通過結構體指針傳遞參數(shù)比直接傳遞結構體變量更高效 實參傳遞給形參時只拷貝了實參傳遞給形參時只拷貝了4個字節(jié)個字節(jié) 指針與指針指針與指針1、指向指針變量的指針、指向指針變量的指針 int num = 100; int *p = # int *pp = &p; 實現(xiàn)指針二級訪問實現(xiàn)指針二級訪問: 函數(shù)與指針函數(shù)與指針1、指針作為函數(shù)的參數(shù)、指針作為
15、函數(shù)的參數(shù)向函數(shù)傳遞數(shù)組、字符串、結構向函數(shù)傳遞數(shù)組、字符串、結構: 如如strc_py、show_info作為函數(shù)的輸出參數(shù)作為函數(shù)的輸出參數(shù)例如:實現(xiàn)交換兩個整數(shù)的函數(shù)例如:實現(xiàn)交換兩個整數(shù)的函數(shù) void swap(int a, int b) 傳值,形參值改變并不能帶回給實參傳值,形參值改變并不能帶回給實參 傳址,在函數(shù)內(nèi)改變地址內(nèi)保存的內(nèi)容傳址,在函數(shù)內(nèi)改變地址內(nèi)保存的內(nèi)容 函數(shù)與指針函數(shù)與指針問題:問題: 要在函數(shù)能改變指針的值,怎么通過輸出參數(shù)返回?要在函數(shù)能改變指針的值,怎么通過輸出參數(shù)返回?例如:例如:void get_mem(char *pmem, int size)pmem
16、 = malloc(size); 動態(tài)分配的內(nèi)存能通過動態(tài)分配的內(nèi)存能通過pmem帶回么?帶回么? 不能!要將實參指針的地址傳遞給形參(二級指針)才能實現(xiàn)不能!要將實參指針的地址傳遞給形參(二級指針)才能實現(xiàn)! 更直接的方法是通過函數(shù)返回值實現(xiàn)更直接的方法是通過函數(shù)返回值實現(xiàn) 函數(shù)與指針函數(shù)與指針2、指針作為函數(shù)的返回值、指針作為函數(shù)的返回值 返回字符串、動態(tài)分配的內(nèi)存等,如返回字符串、動態(tài)分配的內(nèi)存等,如 *strcpy, *malloc 注意返回地址的有效性(函數(shù)執(zhí)行完畢后該地址未被回收)注意返回地址的有效性(函數(shù)執(zhí)行完畢后該地址未被回收) 下面兩個函數(shù)哪個是合法的?下面兩個函數(shù)哪個是合法
17、的?函數(shù)與指針函數(shù)與指針3、指向函數(shù)的指針、指向函數(shù)的指針 函數(shù)存放在函數(shù)存放在TEXT段,同樣具有地址段,同樣具有地址 函數(shù)名就是函數(shù)在函數(shù)名就是函數(shù)在TEXT段的入口地址段的入口地址 跟數(shù)組名一樣,函數(shù)名也可以看作是一個指針常量跟數(shù)組名一樣,函數(shù)名也可以看作是一個指針常量 所以,函數(shù)名也可以賦值給指針變量,那么該指針變量類型呢?所以,函數(shù)名也可以賦值給指針變量,那么該指針變量類型呢? 函數(shù)指針類型!通過函數(shù)指針,也可以間接調用函數(shù)。函數(shù)指針類型!通過函數(shù)指針,也可以間接調用函數(shù)。 函數(shù)與指針函數(shù)與指針函數(shù)指針的應用:函數(shù)指針的應用:1、作為函數(shù)參數(shù)實現(xiàn)回調函數(shù)、作為函數(shù)參數(shù)實現(xiàn)回調函數(shù) 所
18、謂回調函數(shù)是指通過調用其他函數(shù)反所謂回調函數(shù)是指通過調用其他函數(shù)反 過來調用某個函數(shù)過來調用某個函數(shù) 模擬面向對象的多態(tài),在模擬面向對象的多態(tài),在UI組件的大量使組件的大量使 用用 函數(shù)與指針函數(shù)與指針 2、作為結構體的動作域、作為結構體的動作域 模擬面向對象的類,在模擬面向對象的類,在Linux內(nèi)核中大量使用內(nèi)核中大量使用 作為一個現(xiàn)實中的對象,不但有數(shù)據(jù)屬性,還需要有行為屬性作為一個現(xiàn)實中的對象,不但有數(shù)據(jù)屬性,還需要有行為屬性 使用對象行為使用對象行為 課程安排課程安排n指針的概念指針的概念n指針數(shù)據(jù)類型指針數(shù)據(jù)類型n指針與其他數(shù)據(jù)類型指針與其他數(shù)據(jù)類型n指針修飾符指針修飾符const修
19、飾符修飾符1、const修飾符的作用:限定一個變量不允許被改變(只讀)修飾符的作用:限定一個變量不允許被改變(只讀) 如:如:const int num = 100; /num是只讀整型變量是只讀整型變量 const int arr3 = 10, 20, 30; /arr是只讀整型數(shù)組是只讀整型數(shù)組 num = 200 ? arr0 = 100 ? arr1 = 200? 2、const指針指針: 指向變量的只讀指針,指針本身只讀,但指向的對象非只讀指向變量的只讀指針,指針本身只讀,但指向的對象非只讀 如:如:int num1 = 100; int num2 = 200; int* const
20、 p = &num1; *p = 200 ? p = &num2 ? const修飾符修飾符3、指向、指向const變量的指針變量的指針: 指向只讀變量的指針,而指針本身不是只讀的指向只讀變量的指針,而指針本身不是只讀的 如:如: const int num1 = 100; const int num2 = 200; const int *p = &num1; *p = 200 ? p = &num2 ? 注意注意: const也可以在也可以在int之后,如之后,如int const num1 = 100; int const *p =&num14、指向
21、、指向const變量的變量的const指針:指針: 指針和指向的變量都是只讀的指針和指向的變量都是只讀的 如:如: const int num1 = 100; const int num2 = 200; const int* const p = &num1; *p = 200 ? p = &num2 ? volatile修飾符修飾符1、編譯器總是試圖優(yōu)化編譯使代碼運行得更快、編譯器總是試圖優(yōu)化編譯使代碼運行得更快 如果程序中變量未被改變,對變量的訪問盡量用寄存器代替內(nèi)存儲存如果程序中變量未被改變,對變量的訪問盡量用寄存器代替內(nèi)存儲存 寄存器屬于寄存器屬于CPU內(nèi)部的存儲單元,比起內(nèi)存訪問來得更快內(nèi)部的存儲單元,比起內(nèi)存訪問來得更快2、但對于硬件驅動程序來說,這樣做就存在風險、但對于硬件驅動程序來說,這樣做就存在風險 const unsigned int *paddr = 0 x0012ff7c; /假定假定0 x0012ff7c表示一個網(wǎng)卡內(nèi)存地址表示一個網(wǎng)卡內(nèi)存地址 data = *paddr; /第一次取網(wǎng)卡數(shù)據(jù)第一次取網(wǎng)卡數(shù)據(jù) data = *paddr; /第二次取網(wǎng)卡數(shù)據(jù)第二次取網(wǎng)卡數(shù)據(jù) 由于由于*paddr從未被程序改變,所以第二次取值從寄存器中進行,跟第一次值一樣從未被程序改變,所以第二次取值從寄存器中進行,跟第一次值一樣 但網(wǎng)卡內(nèi)存數(shù)據(jù)會隨時
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 土建瓦工勞務分包合同
- 常年法律顧問合同
- 詳細操作流程說明書
- 2025年撫州貨運資格證模擬考試題庫下載
- 2025年徐州市汽車租賃合同5篇
- 農(nóng)莊農(nóng)場合作經(jīng)營合同協(xié)議書范本6篇
- 公司副食品購銷合同7篇
- 房地產(chǎn)開發(fā)聯(lián)營合同
- 專利技術的授權與使用條款協(xié)議
- 無償保管合同范本-倉儲保管合同8篇
- 讀后續(xù)寫(2022新高考I卷)講解課件 高三英語寫作專項
- 三角形的內(nèi)角和-課件
- 國企工程施工分包管理2019(67P+PPT)
- 成人大專畢業(yè)論文怎么寫(通用6篇)
- 醫(yī)院高壓氧艙室施工方案
- 質量問題檢出獎勵申請表模板
- 中職學生日常行為規(guī)范主題班會講稿
- 《大數(shù)據(jù)分析與應用》教學大綱
- 2022年中國遠洋海運集團有限公司招聘考試題庫及答案解析
- 供應鏈管理課件第5章供應鏈合作伙伴選擇與評價
- 4D現(xiàn)場管理培訓ppt課件(PPT 45頁)
評論
0/150
提交評論