課件-c語(yǔ)言-ch08-6-指針數(shù)組與多重指針 動(dòng)態(tài)內(nèi)存分配_第1頁(yè)
課件-c語(yǔ)言-ch08-6-指針數(shù)組與多重指針 動(dòng)態(tài)內(nèi)存分配_第2頁(yè)
課件-c語(yǔ)言-ch08-6-指針數(shù)組與多重指針 動(dòng)態(tài)內(nèi)存分配_第3頁(yè)
課件-c語(yǔ)言-ch08-6-指針數(shù)組與多重指針 動(dòng)態(tài)內(nèi)存分配_第4頁(yè)
課件-c語(yǔ)言-ch08-6-指針數(shù)組與多重指針 動(dòng)態(tài)內(nèi)存分配_第5頁(yè)
已閱讀5頁(yè),還剩38頁(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)介

1、2022/8/311上一節(jié)我們學(xué)到了函數(shù)指針和指針函數(shù)2022/8/312第8章 善于利用指針8.1 指針是什么8.2 指針變量8.3 通過(guò)指針引用數(shù)組8.4 通過(guò)指針引用字符串8.4.1 字符串的引用方式8.4.2 字符指針作函數(shù)參數(shù)8.4.3 使用字符指針變量和字符數(shù)組的比較 指向函數(shù)的指針8.6 返回指針值的函數(shù)8.7 指針數(shù)組和多重指針8.8 動(dòng)態(tài)內(nèi)存分配與指向它的指針變量8.9 有關(guān)指針的小結(jié)本節(jié)內(nèi)容指針數(shù)組pointer array 多重指針int *帶參的main動(dòng)態(tài)內(nèi)存分配void*的引用和賦值野指針(懸掛指針)與指針相關(guān)的編程規(guī)則2022/8/314指針數(shù)組指針數(shù)組 指針組成

2、的數(shù)組例如:int *p4由于比*優(yōu)先級(jí)高, 因此p首先與結(jié)合,即p是數(shù)組, 4個(gè)元素分別為p0、 p1、 p2、 p3。數(shù)組每個(gè)元素的類型是int *。2022/8/315指針數(shù)組舉例例如, 圖書(shū)館有若干本書(shū)(圖 a), 要求對(duì)這些書(shū)目進(jìn)行排序和查詢。表示多個(gè)字符串的兩種數(shù)據(jù)結(jié)構(gòu)二維字符數(shù)組,圖bchar names550;缺點(diǎn),空間復(fù)雜度字符指針數(shù)組,圖cchar *names50;#include int main()int i;char *arr4 = C,C+,Java,VBA;for (i=0; i4; i+) printf(Address of String %d : %un,i

3、+1,arri);return 0;VBA0Java0C+0C003C04304204104003F03E03D04404B04A04904804704604504F04E04D04C0 x0042204C0 x004220480 x004220400 x0042203C2022/8/317arrchar *arr4 = C,C+,Java,VBA;C 0 C + + 0V B A 0J a v a0 000002022/8/319例8.27 將若干字符串按字母順序(由小到大)輸出。#include #include void sort(char *names, int n);void pri

4、nt(char *names, int n);int main() char *names = Follow me, BASIC, Great Wall, FORTRAN, Computer Design ; int n = sizeof(names)/sizeof(names0); sort(names, n); print(names, n);2022/8/3110void sort(char *names, int n)/選擇法排序 char *temp; int i, j, k; for (i=0; in-1; i+) k = i; for (j=i+1; j0) k = j; if

5、(k != i) temp = namesi; namesi = namesk; namesk = temp; 2022/8/3111void print(char *names, int n) int i; for (i=0; in; i+) printf(%sn, namesi); 運(yùn)行結(jié)果為: BASIC Computer Design FORTRAN Follow me Great all2022/8/31128.7.2 指向指針的指針指向指針數(shù)據(jù)的指針變量, 簡(jiǎn)稱為指向指針的指針。2022/8/3113指向指針的指針的定義char *p;*運(yùn)算符的結(jié)合性是從右到左, 因此*p相當(dāng)于*

6、(*p)(*p)前面部分是char *, 表明p是指向char *(即一個(gè)字符指針變量)的指針變量。2022/8/3114*p就是p所指向的那個(gè)指針變量, 例p = name + 2;printf(%xn, *p);printf(%sn, *p);2022/8/3115例8.28 使用指向指針的指針輸出各字符串。int main() char *name = Follow me, BASIC, Great Wall, FORTRAN, Computer Design ; char *p; int i; for (i=0; i5; i+) p = name + i; printf(%sn, *p

7、); 2022/8/3116例8.29 一個(gè)指針數(shù)組的元素指向整型數(shù)據(jù)的簡(jiǎn)單例子int main() int a5 = 1, 3, 5, 7, 9; int *num5 = &a0, &a1, &a2, &a3, &a4; int *p, i; p = num; for (i=0; i1)+argv; / 程序名被跳過(guò)printf(%sn, *argv);-argc;return 0;3argcargv“mainpara”“”“”2022/8/3121上面程序可以改寫(xiě)為int main(int argc, char *argv) while(argc-1) printf(%sn, *+argv

8、); return 0;2022/8/3122為什么使用動(dòng)態(tài)內(nèi)存分配數(shù)組靜態(tài)數(shù)組int a10;動(dòng)態(tài)數(shù)組數(shù)組長(zhǎng)度動(dòng)態(tài)指定2022/8/3123動(dòng)態(tài)分配內(nèi)存在 和中均定義了下面的函數(shù)void* malloc(size_t size);size_t是在中定義的數(shù)據(jù)類型,就是一個(gè)unsigned int向系統(tǒng)申請(qǐng)大小為size的內(nèi)存塊,把指向首地址的指針?lè)祷?。如果申?qǐng)不成功(如空間不足),返回NULLvoid free(void* block);釋放由malloc()申請(qǐng)的內(nèi)存塊。block是指向此塊的指針24int *pi, i;.pi = (int *)malloc(100*sizeof(int

9、);if (pi = NULL)printf(Out of memory!n);exit(1);.for (i=0; i100; +i)pii = 0;.free(pi);pi = NULL;2022/8/3125例8.30 建立動(dòng)態(tài)數(shù)組,輸入n(n由用戶輸入)個(gè)學(xué)生的成績(jī),另外用一個(gè)函數(shù)輸出不合格的成績(jī)。2022/8/3126#include #include / void printfailinggrade(int *, int); void printfailinggrade(int *p, int n) int i; printf(nThe failing grade:); for (

10、i=0; in; i+) if (pi 60) printf(%d , pi); printf(n); 27int main() int *pscore, i, n; printf(請(qǐng)輸入學(xué)生人數(shù): ); scanf(%d, &n); pscore = (int *)malloc(n * sizeof(int); if (NULL = pscore) printf(“Error: Out of memory!n);exit(1); printf(請(qǐng)輸入%d個(gè)成績(jī),用空格隔開(kāi): , n); for (i=0; in; i+) scanf(%d, pscore+i); printfailinggr

11、ade(pscore, n); free(pscore); pscore = NULL; return 0;2022/8/3128void *calloc(size_t n, size_t size);向系統(tǒng)申請(qǐng)n個(gè)長(zhǎng)度為size的連續(xù)內(nèi)存空間,可以保存一個(gè)數(shù)組申請(qǐng)空間初始化為0void *realloc(void *p, size_t size);重新分配size大小的空間如分配不成功,返回NULL已經(jīng)通過(guò)molloc和calloc獲得了動(dòng)態(tài)空間用來(lái)增加已分配空間的大小2022/8/3129防止內(nèi)存泄露之道在需要的時(shí)候才malloc,并盡量減少malloc的次數(shù)能用自動(dòng)變量解決的問(wèn)題,就不要

12、用malloc來(lái)解決malloc一般在大塊內(nèi)存分配和動(dòng)態(tài)內(nèi)存分配時(shí)使用malloc本身的執(zhí)行效率就不高,所以過(guò)多的malloc會(huì)使程序性能下降可以重復(fù)利用malloc申請(qǐng)到的內(nèi)存盡量讓malloc和與之配套的free在一個(gè)函數(shù)內(nèi)盡量把malloc集中在函數(shù)的入口處,free集中在函數(shù)的出口處以上做法只能盡量降低產(chǎn)生泄露的概率。完全杜絕內(nèi)存泄露,關(guān)鍵要靠程序員的細(xì)心與責(zé)任感2022/8/31308.8.3 void指針類型ANSI新標(biāo)準(zhǔn)增加了一種void指針類型, 即可定義一個(gè)指針變量, 但不指定它是指向哪一種類型數(shù)據(jù)的。void *則為無(wú)類型指針,可以指向任何類型的數(shù)據(jù)。 float *p1;

13、int *p2;p1 = p2;其中p1 = p2語(yǔ)句會(huì)編譯出錯(cuò),提示= : cannot convert from int * to float *必須改為:p1 = (float *)p2; 2022/8/3131而void *則不同,任何類型的指針都可以直接賦值給它,無(wú)需進(jìn)行強(qiáng)制類型轉(zhuǎn)換: void *p1;int *p2;p1 = p2;下面的語(yǔ)句編譯出錯(cuò):void *p1;int *p2;p2 = p1; 提示= : cannot convert from void * to int *。2022/8/3132void的使用規(guī)則一:如果函數(shù)沒(méi)有返回值,那么應(yīng)聲明為void類型 規(guī)則二

14、:如果函數(shù)無(wú)參數(shù),那么應(yīng)聲明其參數(shù)為void規(guī)則三:小心使用void指針類型 規(guī)則四:如果函數(shù)的參數(shù)可以是任意類型指針,那么應(yīng)聲明其參數(shù)為void *2022/8/3133關(guān)于野指針(懸掛指針)懸掛指針:既不為空,也沒(méi)有被設(shè)置為與另一個(gè)對(duì)象有鏈接關(guān)系的指針。野指針是非常危險(xiǎn)的,所以要杜絕野指針。參見(jiàn)高質(zhì)量C+/C編程指南 - 第7章 內(nèi)存管理 (2) 2022/8/3134野指針的成因主要有兩種:(1)指針變量沒(méi)有被初始化。 未被初始化的指針變的缺省值是隨機(jī)的。所以,指針變量在定義的同時(shí)應(yīng)當(dāng)被初始化,要么將指針設(shè)置為NULL,要么讓它指向合法的內(nèi)存。例如char *p = NULL;char

15、*str = (char *) malloc(100);(2)指針p被free或者delete之后,沒(méi)有置為NULL,讓人誤以為p是個(gè)合法的指針。2022/8/3135(3)指針操作超越了變量的作用范圍。這種情況讓人防不勝防,示例程序如下:class A public:void Func(void) cout Func of class A Func();/ p是野指針函數(shù)Test在執(zhí)行語(yǔ)句p-Func()時(shí),對(duì)象a已經(jīng)消失,而p是指向a的,所以p就成了野指針。但奇怪的是我運(yùn)行這個(gè)程序時(shí)居然沒(méi)有出錯(cuò),這可能與編譯器有關(guān)。2022/8/3136與指針相關(guān)的編程規(guī)則減少出錯(cuò)的根本是徹底理解指針。與

16、指針相關(guān)的編程規(guī)則1) 未使用的指針初始化為NULL 。2) 在給指針?lè)峙淇臻g前、分配后均應(yīng)作判斷。3) 指針?biāo)赶虻膬?nèi)容刪除后也要清除指針本身。37遵循這些規(guī)則可以有效地減少指針出錯(cuò),我們來(lái)看下面的例子:#include #include int main(void) char *str = (char *) malloc(100); strcpy(str, hello); free(str); if(str != NULL) strcpy(str, world); printf(str); 請(qǐng)問(wèn)運(yùn)行Test函數(shù)可能會(huì)有什么樣的結(jié)果?2022/8/3138篡改動(dòng)態(tài)內(nèi)存區(qū)的內(nèi)容,后果難以預(yù)料,

17、非常危險(xiǎn)。因?yàn)閒ree(str);之后,str成為野指針,if(str != NULL)語(yǔ)句不起作用。如果我們牢記規(guī)則3,在free(str)后增加語(yǔ)句:str = NULL;那么,就可以防止這樣的錯(cuò)誤發(fā)生。 習(xí)題下面的標(biāo)識(shí)符是什么類型?float (*def)10;def是個(gè)二級(jí)指針,它指向一個(gè)一維數(shù)組的指針,數(shù)組元素是float型。 double *(*gh)10;gh是一個(gè)指向一維數(shù)組的指針,數(shù)組元素是double*型。 double (*f10)();f是一個(gè)函數(shù)指針數(shù)組,數(shù)組元素都是指向函數(shù)的指針,函數(shù)類型是沒(méi)有參數(shù)且返回 double的函數(shù)。 int * (*b)10;和int*(

18、*b)10一樣,b是一維數(shù)組的指針,數(shù)組元素類型為int*。 long (*fun)(int)fun是一個(gè)函數(shù)指針,指向一個(gè)有一個(gè)int形參并返回long的函數(shù)習(xí)題static int a33=1,3,5,7,9,11,13,15,17,y,x,*p=&a22;for (x=0;x3;+x) y+=*(p-4*x);printf(“n%d”, y);習(xí)題請(qǐng)用變量a給出下面的定義,你能做到嗎?a)一個(gè)有10個(gè)指針的數(shù)組,該指針是指向一個(gè)整型數(shù)的(Anarrayof10pointerstointegers)b)一個(gè)指向整型數(shù)的指針(Apointertoaninteger)c)一個(gè)指向指針的的指針,它指向的指針是指向一個(gè)整型數(shù)(Apointertoapointertoaninteger)d)一個(gè)有10個(gè)整型數(shù)的數(shù)

溫馨提示

  • 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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論