




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、C語(yǔ)言教程課件第09章第第9章章 指指 針針指針是語(yǔ)言中的重要概念,也是語(yǔ)言的重要特色。使用指針,可以使程序更加簡(jiǎn)潔、緊湊、高效。9.1 指針和指針變量的概念 9.2 指針變量的定義與應(yīng)用 9.3 數(shù)組的指針和指向數(shù)組的指針變量 9.4 字符串的指針和指向字符串的指針變量9.5 返回指針值的函數(shù) 9.6 指針數(shù)組與主函數(shù)main()的形參 9.7 函數(shù)的指針和指向函數(shù)的指針變量ReturnC語(yǔ)言教程課件第09章9.1 指針和指針變量的概念指針和指針變量的概念 1.內(nèi)存地址內(nèi)存中存儲(chǔ)單元的編號(hào)(1)計(jì)算機(jī)硬件系統(tǒng)的內(nèi)存儲(chǔ)器中,擁有大量的存儲(chǔ)單元(容量為字節(jié))。為了方便管理,必須為每一個(gè)存儲(chǔ)單元編
2、號(hào),這個(gè)編號(hào)就是存儲(chǔ)單元的“地址”。每個(gè)存儲(chǔ)單元都有一個(gè)惟一的地址。(2)在地址所標(biāo)識(shí)的存儲(chǔ)單元中存放數(shù)據(jù)。注意:內(nèi)存單元的地址與內(nèi)存單元中的數(shù)據(jù)是兩個(gè)完全不同的概念。2.變量地址系統(tǒng)分配給變量的內(nèi)存單元的起始地址假設(shè)有這樣一個(gè)程序:C語(yǔ)言教程課件第09章 main() int num; scanf(%d,&num); printf(num=%dn, num); C編譯程序編譯到該變量定義語(yǔ)句時(shí),將變量num 登錄到“符號(hào)表”中。符號(hào)表的關(guān)鍵屬性有兩個(gè):一是“標(biāo)識(shí)符名(id)” ,二是該標(biāo)識(shí)符在內(nèi)存空間中的“地址(addr)” 。為描述方便,假設(shè)系統(tǒng)分配給變量num的2字節(jié)存儲(chǔ)單元為
3、3000 和3001,則起始地址3000就是變量num在內(nèi)存中的地址。 3.變量值的存取通過(guò)變量在內(nèi)存中的地址進(jìn)行系統(tǒng)執(zhí)行“scanf(”%d“,&num);”和“printf(”num=%dn“, num);”時(shí),存取變量num值的方式可以有兩種:C語(yǔ)言教程課件第09章 (1)直接訪問(wèn)直接訪問(wèn)直接利用變量的地址進(jìn)行存取 1)上例中scanf(“%d”,&num)的執(zhí)行過(guò)程是這樣的: 用變量名num作為索引值,檢索符號(hào)表,找到變量num的起始地址3000;然后將鍵盤(pán)輸入的值(假設(shè)為)送到內(nèi)存單元3000和3001中。此時(shí),變量num在內(nèi)存中的地址和值,如圖9-1所示。 2)pr
4、intf(num=%dn,num)的執(zhí)行過(guò)程,與scanf()很相似: 首先找到變量num的起始地址3000,然后從3000和3001中取出其值,最后將它輸出。 (2)間接訪問(wèn)間接訪問(wèn)通過(guò)另一變量訪問(wèn)該變量的值 語(yǔ)言規(guī)定:在程序中可以定義一種特殊的變量(稱為指針變量),用來(lái)存放其它變量的地址。C語(yǔ)言教程課件第09章例如,假設(shè)定義了這樣一個(gè)指針變量num_pointer,它被分 配 到 4 0 0 0 、 4 0 0 1 單 元 , 其 值 可 通 過(guò) 賦 值 語(yǔ) 句“num_pointer=num;”得到。此時(shí),指針變量num_pointer的值就是變量num在內(nèi)存中的起始地址3000,如圖9
5、-1所示。通過(guò)指針變量num_pointer存取變量num值的過(guò)程如下:首先找到指針變量num_pointer的地址(4000),取出其值3000(正好是變量num 的起始地址); 然后從3000、3001中取出變量num的值(3)。 (3)兩種訪問(wèn)方式的比較 兩種訪問(wèn)方式之間的關(guān)系,可以用某人甲(系統(tǒng))要找某人乙(變量)來(lái)類(lèi)比。一種情況是,甲知道乙在何處,直接去找就是(即直接訪問(wèn))。另一種情況是,甲不知道乙在哪,但丙(指針變量)知道,此時(shí)甲可以這么做:先找丙,從丙處獲得乙的去向,然后再找乙(即間接訪問(wèn))。C語(yǔ)言教程課件第09章4.指針與指針變量指針與指針變量(1)指針即地址 一個(gè)變量的地址稱
6、為該變量的指針。通過(guò)變量的指針能夠找到該變量。(2)指針變量專(zhuān)門(mén)用于存儲(chǔ)其它變量地址的變量指針變量num_pointer的值就是變量num的地址。指針與指針變量的區(qū)別,就是變量值與變量的區(qū)別。(3)為表示指針變量和它指向的變量之間的關(guān)系,用指針運(yùn)算符“*”表示。 例如,指針變量num_pointer與它所指向的變量num的關(guān)系,表示為:*num_pointer,即*num_pointer等價(jià)于變量num。因此,下面兩個(gè)語(yǔ)句的作用相同:num=3; /*將3直接賦給變量num*/num_pointer=# /*使num_pointer指向num */*num_pointer=3;
7、 /*將3賦給指針變量num_pointer所指向的變量*/ReturnC語(yǔ)言教程課件第09章9.2 指針變量的定義與應(yīng)用指針變量的定義與應(yīng)用 9.2.1 指針變量的定義與相關(guān)運(yùn)算指針變量的定義與相關(guān)運(yùn)算案例案例9.1 指針變量的定義與相關(guān)運(yùn)算示例。 /*案例代碼文件名:AL9_1.C*/ main() int num_int=12, *p_int; /*定義一個(gè)指向int型數(shù)據(jù)的指針變量p_int */ float num_f=3.14, *p_f;/*定義一個(gè)指向float型數(shù)據(jù)的指針變量p_f */ char num_ch=p, *p_ch;/*定義一個(gè)指向char型數(shù)據(jù)的指針變量p_c
8、h */ p_int=&num_int; /*取變量num_int的地址,賦值給p_int */ p_f=&num_f; /*取變量num_f的地址,賦值給p_f */ p_ch=&num_ch; /*取變量num_ch的地址,賦值給p_ch */ printf(“num_int=%d, *p_int=%dn”, num_int, *p_int); printf(“num_f=%4.2f, *p_f=%4.2fn”, num_f, *p_f); printf(“num_ch=%c, *p_ch=%cn”, num_ch, *p_ch); C語(yǔ)言教程課件第09章程序運(yùn)行結(jié)
9、果:num_int=12, *p_int=12num_f=3.14, *p_f=3.14num_ch=p, *p_ch=p 程序說(shuō)明程序說(shuō)明:(1)頭三行的變量定義語(yǔ)句指針變量的定義 與一般變量的定義相比,除變量名前多了一個(gè)星號(hào)“*” (指針變量的定義標(biāo)識(shí)符)外,其余一樣:數(shù)據(jù)類(lèi)型數(shù)據(jù)類(lèi)型 *指針變量指針變量, *指針變量指針變量2; 注意注意:此時(shí)的指針變量p_int、p_f、p_ch,并未指向某個(gè)具體的變量(稱指針是懸空的)。使用懸空指針很容易破壞系統(tǒng),導(dǎo)致系統(tǒng)癱瘓。C語(yǔ)言教程課件第09章 (2)中間三行的賦值語(yǔ)句取地址運(yùn)算()取地址運(yùn)算的格式: 變量變量例如,&num_int、&
10、amp;num_f、&num_ch的結(jié)果,分別為變量num_int、num_f、num_ch的地址。注意注意:指針變量只能存放指針(地址),且只能是相同類(lèi)型變量的地址。例如,指針變量p_int、p_f、p_ch,只能分別接收int型、float型、char型變量的地址,否則出錯(cuò)。(3)后三行的輸出語(yǔ)句指針運(yùn)算(*)使用直接訪問(wèn)和間接訪問(wèn)兩種方式,分別輸出變量num_int、num_f、num_ch的值。注意注意:這三行出現(xiàn)在指針變量前的星號(hào)“*”是指針運(yùn)算符,訪問(wèn)指針變量所指向的變量的值,而非指針運(yùn)算符。C語(yǔ)言教程課件第09章案例案例9.2 使用指針變量求解:輸入2個(gè)整數(shù),按升序(從小
11、到大排序)輸出。/*案例代碼文件名:AL9_2.C*/*程序功能:使用指針變量求解2個(gè)整數(shù)的升序輸出*/main() int num1,num2; int *num1_p=&num1, *num2_p=&num2, *pointer; printf(“Input the first number: ”); scanf(“%d”,num1_p); printf(“Input the second number: ”); scanf(“%d”,num2_p); printf(“num1=%d, num2=%dn”, num1, num2); if( *num1_p *num2_p
12、) /*如果num1num2,則交換指針*/ pointer= num1_p, num1_p= num2_p, num2_p=pointer; printf(“min=%d, max=%dn”, *num1_p, *num2_p); C語(yǔ)言教程課件第09章程序運(yùn)行情況:Input the first number:9Input the second number:6num1=9, num2=6min=6, max=9程序說(shuō)明程序說(shuō)明:(1)第5行的if語(yǔ)句 如果*num1_p*num2_p (即num1num2),則交換指針,使num1_p指向變量num2(較小值),num2_p指向變量num
13、1(較大值)。(2)printf(“min=%d, max=%dn”, *num1_p, *num2_p); 語(yǔ)句:通過(guò)指針變量,間接訪問(wèn)變量的值。C語(yǔ)言教程課件第09章 本案例的處理思路處理思路是:交換指針變量num1_p 和num2_p的值,而不是變量num1和num2的值(變量num1和num2并未交換,仍保持原值),最后通過(guò)指針變量輸出處理結(jié)果。9.2.2 指針變量作函數(shù)參數(shù)指針變量作函數(shù)參數(shù)1.指針變量,既可以作為函數(shù)的形參,也可以作函數(shù)的實(shí)參。2.指針變量作實(shí)參時(shí),與普通變量一樣,也是“值傳遞”,即將指針變量的值(一個(gè)地址)傳遞給被調(diào)用函數(shù)的形參(必須是一個(gè)指針變量)。注意注意:被
14、調(diào)用函數(shù)不能改變實(shí)參指針變量的值,但可以改變實(shí)參指針變量所指向的變量的值。C語(yǔ)言教程課件第09章案例案例9.3 使用函數(shù)調(diào)用方式改寫(xiě)案例案例9.2,要求實(shí)參為指針變量。/*案例代碼文件名:AL9_3.C*/*/*exchange()功能:交換2個(gè)形參指針變量所指向的變量的值 */*形參:2個(gè),均為指向整型數(shù)據(jù)的指針變量 */*返回值:無(wú) */*/void exchange(int *pointer1, int *pointer2) int temp; temp=*pointer1, *pointer1=*pointer2, *pointer2=temp; /*主函數(shù)main()*/main()
15、 int num1,num2; /*定義并初始化指針變量num1_p和 num2_p */ int *num1_p=&num1, *num2_p=&num2;C語(yǔ)言教程課件第09章 printf(“Input the first number: ”); scanf(“%d”, num1_p); printf(“Input the second number: ”); scanf(“%d”, num2_p); printf(“num1=%d, num2=%dn”, num1, num2); if( *num1_p *num2_p ) /* 即num1num2)*/ exchang
16、e(num1_p, num2_p); /*指針變量作實(shí)參*/ /*輸出排序后的num1和num2的值*/ printf(“min=%d, max=%dn”, num1, num2); 程序運(yùn)行情況:Input the first number:9Input the second number:6num1=9, num2=6min=6, max=9C語(yǔ)言教程課件第09章調(diào)用函數(shù)exchange()之前、之時(shí)、結(jié)束時(shí)和結(jié)束后的情況,如圖9-5所示。形參指針變量pointer1(指向變量num1)和pointer2(指向變量num2),在函數(shù)調(diào)用開(kāi)始時(shí)才分配存儲(chǔ)空間,函數(shù)調(diào)用結(jié)束后立即被釋放。雖然被
17、調(diào)用函數(shù)不能改變實(shí)參指針變量的值,但可以改變它們所指向的變量的值??偨Y(jié)總結(jié):為了利用被調(diào)用函數(shù)改變的變量值,應(yīng)該使用指針(或指針變量)作函數(shù)實(shí)參。其機(jī)制為:在執(zhí)行被調(diào)用函數(shù)時(shí),使形參指針變量所指向的變量的值發(fā)生變化;函數(shù)調(diào)用結(jié)束后,通過(guò)不變的實(shí)參指針(或?qū)崊⒅羔樧兞浚⒆兓闹当A粝聛?lái)。C語(yǔ)言教程課件第09章 案例案例9.4 輸入3個(gè)整數(shù),按降序(從大到小的順序)輸出。要求使用變量的指針作函數(shù)調(diào)用的實(shí)參來(lái)實(shí)現(xiàn)。/*案例代碼文件名:AL9_4.C*/*/*exchange()功能:交換2個(gè)形參指針變量所指向的變量的值 */*形參:2個(gè),均為指向整型數(shù)據(jù)的指針變量 */*返回值:無(wú) */*/voi
18、d exchange(int *pointer1, int *pointer2) int temp; temp=*pointer1, *pointer1=*pointer2, *pointer2=temp; C語(yǔ)言教程課件第09章/*主函數(shù)main()*/main() int num1,num2,num3; /*從鍵盤(pán)上輸入3個(gè)整數(shù)*/ printf(“Input the first number: ”); scanf(“%d”, &num1); printf(“Input the second number: ”); scanf(“%d”, &num2); printf(“I
19、nput the third number: ”); scanf(“%d”, &num3); printf(“num1=%d, num2=%d, num3=%dn”, num1, num2, num3); /*排序*/ if( num1 num2 ) /*num1num2*/ exchange( &num1, &num2 ); if( num1 num3 ) exchange( &num1, &num3 ); if( num2 num3 ) exchange( &num2, &num3 ); /*輸出排序結(jié)果*/ printf(“排序結(jié)果
20、: %d, %d, %dn”,num1,num2,num3); C語(yǔ)言教程課件第09章程序運(yùn)行情況:Input the first number:9Input the second number:6Input the third number:12num1=9, num2=6, num3=12排序結(jié)果: 12, 9, 6ReturnC語(yǔ)言教程課件第09章9.3 數(shù)組的指針和指向數(shù)組的指針變量數(shù)組的指針和指向數(shù)組的指針變量9.3.1 概述概述1.概念數(shù)組的指針數(shù)組在內(nèi)存中的起始地址,數(shù)組元素的指針數(shù)組元素在內(nèi)存中的起始地址。2.指向數(shù)組的指針變量的定義指向數(shù)組的指針變量的定義,與指向普通變量的指
21、針變量的定義方法一樣。例如,int array10, *pointer=array(或&array0);或者: int array10, *pointer; pointerarray;注意注意:數(shù)組名代表數(shù)組在內(nèi)存中的起始地址(與第1個(gè)元素的地址相同),所以可以用數(shù)組名給指針變量賦值。C語(yǔ)言教程課件第09章3.數(shù)組元素的引用數(shù)組元素的引用,既可用下標(biāo)法,也可用指針?lè)?。使用下?biāo)法,直觀;而使用指針?lè)?,能使目?biāo)程序占用內(nèi)存少、運(yùn)行速度快。9.3.2 通過(guò)指針引用數(shù)組元素通過(guò)指針引用數(shù)組元素如果有“int array10,*pointer=array;” ,則:(1)pointer+i和ar
22、ray+i都是數(shù)組元素arrayi的地址,如圖9-6所示。 (2)*(pointer+i)和*(array+i)就是數(shù)組元素arrayi。(3)指向數(shù)組的指針變量,也可將其看作是數(shù)組名,因而可按下標(biāo)法來(lái)使用。例如,pointeri等價(jià)于*(pointer+i)。注意注意:pointer+1指向數(shù)組的下一個(gè)元素,而不是簡(jiǎn)單地使指針變量pointer的值+1。其實(shí)際變化為pointer+1*size(size為一個(gè)元素占用的字節(jié)數(shù))。例如,假設(shè)指針變量pointer的當(dāng)前值為3000,則pointer+1為3000+1*2=3002,而不是3001。C語(yǔ)言教程課件第09章 案例案例9.5 使用指向
23、數(shù)組的指針變量來(lái)引用數(shù)組元素。/*案例代碼文件名:AL9_5.C*/*程序功能:使用指向數(shù)組的指針變量來(lái)引用數(shù)組元素*/main() int array10, *pointer=array, i; printf(“Input 10 numbers: ”); for(i=0; i10; i+) scanf(“%d”, pointer+i);/*使用指針變量來(lái)輸入數(shù)組元素的值*/ printf(“array10: ”); for(i=0; i10; i+) printf(“%d ”, *(pointer+i); /*使用指向數(shù)組的指針變量輸出數(shù)組*/ printf(“n”); 程序運(yùn)行情況:Inp
24、ut 10 numbers: 0 1 2 3 4 5 6 7 8 9array10: 0 1 2 3 4 5 6 7 8 9C語(yǔ)言教程課件第09章程序說(shuō)明程序說(shuō)明:程序中第3行和第6行的2個(gè)for語(yǔ)句,等價(jià)于下面的程序段:for(i=0; i10; i+,pointer+) scanf(“%d”,pointer);printf(“array10: ”);pointer=array; /*使pointer重新指向數(shù)組的第一個(gè)元素*/for(i=0; i10; i+,pointer+) printf(“%d”,*pointer);思考題思考題:(1)如果去掉“pointer=array;”行,程序
25、運(yùn)行結(jié)果會(huì)如何?請(qǐng)上機(jī)驗(yàn)證。(2)在本案例中,也可以不使用i來(lái)作循環(huán)控制變量,程序怎么修改?提示:指針可以參與關(guān)系運(yùn)算。C語(yǔ)言教程課件第09章 說(shuō)明說(shuō)明: (1)指針變量的值是可以改變的,所以必須注意其當(dāng)前值,否則容易出錯(cuò)。 (2)指向數(shù)組的指針變量,可以指向數(shù)組以后的內(nèi)存單元,雖然沒(méi)有實(shí)際意義。 (3)對(duì)指向數(shù)組的指針變量(px和py)進(jìn)行算術(shù)運(yùn)算和關(guān)系運(yùn)算的含義 1)可以進(jìn)行的算術(shù)運(yùn)算,只有以下幾種: pxn, px+/+px, px-/-px, px-py pxn:將指針從當(dāng)前位置向前(+n)或回退(-n)n個(gè)數(shù)據(jù)單位,而不是n個(gè)字節(jié)。顯然,px+/+px和px-/-px是pxn的特例(
26、n=1)。 px-py:兩指針之間的數(shù)據(jù)個(gè)數(shù),而不是指針的地址之差。C語(yǔ)言教程課件第09章 2)關(guān)系運(yùn)算 表示兩個(gè)指針?biāo)傅刂分g、位置的前后關(guān)系:前者為小,后者為大。例如,如果指針px所指地址在指針py所指地址之前,則pxpy的值為1。 9.3.3 再論數(shù)組作函數(shù)參數(shù)再論數(shù)組作函數(shù)參數(shù)數(shù)組名作形參時(shí),接收實(shí)參數(shù)組的起始地址;作實(shí)參時(shí),將數(shù)組的起始地址傳遞給形參數(shù)組。 引入指向數(shù)組的指針變量后,數(shù)組及指向數(shù)組的指針變量作函數(shù)參數(shù)時(shí),可有種等價(jià)形式(本質(zhì)上是一種,即指針數(shù)據(jù)作函數(shù)參數(shù)):(1)形參、實(shí)參都用數(shù)組名(2)形參、實(shí)參都用指針變量(3)形參用指針變量、實(shí)參用數(shù)組名(4)形參用數(shù)組名、實(shí)
27、參用指針變量 C語(yǔ)言教程課件第09章9.3.4 2維數(shù)組的指針及其指針變量維數(shù)組的指針及其指針變量 1. 2維數(shù)組的指針 假設(shè)有如下數(shù)組定義語(yǔ)句: int array34; (1)從2維數(shù)組角度看,數(shù)組名array代表數(shù)組的起始地址, 是一個(gè)以行為單位進(jìn)行控制的行指針: array+i:行指針值,指向2維數(shù)組的第i行。 *(array+i):(列)指針值,指向第i行第列(控制由行轉(zhuǎn)為列,但仍為指針)。 *(*(array+i):數(shù)組元素arrayi0的值。 用array作指針訪問(wèn)數(shù)組元素arrayij的格式: *(*(array+i)j)注意注意:行指針是一個(gè)級(jí)指針,如圖9-7所示。(2)從1
28、維數(shù)組角度看,數(shù)組名array和第1維下標(biāo)的每一個(gè)值, 共同構(gòu)成一組新的1維數(shù)組名array0、array1、array2,它們均由4個(gè)元素組成。C語(yǔ)言教程課件第09章 語(yǔ)言規(guī)定:數(shù)組名代表數(shù)組的地址數(shù)組名代表數(shù)組的地址,所以arrayi是第i行1維數(shù)組的地址, 它指向該行的第0列元素,是一個(gè)以數(shù)組元素為單位進(jìn)行控制的列指針:arrayi+j:(列)指針值,指向數(shù)組元素arrayij。*(arrayi+j):數(shù)組元素arrayij的值。如果有“int array34,*p=array0;”,則p+1指向下一個(gè)元素,如圖9-8所示。用p作指針訪問(wèn)數(shù)組元素arrayij的格式: *(p+(*每行列
29、數(shù)每行列數(shù)+j) )2.行指針變量指向由n個(gè)元素組成的一維數(shù)組的指針變量(1)定義格式 數(shù)據(jù)類(lèi)型數(shù)據(jù)類(lèi)型 (*指針變量指針變量)n;C語(yǔ)言教程課件第09章注意注意:“*指針變量”外的括號(hào)不能缺,否則成了指針數(shù)組數(shù)組的每個(gè)元素都是一個(gè)指針指針數(shù)組(本章第6節(jié)介紹)。(2)賦值 行指針變量行指針變量 2維數(shù)組名維數(shù)組名 | 行指針變量行指針變量;案例案例9.6 使用行指針和列指針兩種方式輸出2維數(shù)組的任一元素。(1) 使用行指針/*案例代碼文件名:AL9_6_1.C*/*程序功能:使用行指針輸出2維數(shù)組的任一元素*/main() int array34=1,2,3,4,5,6,7,8,9,10,1
30、1,12; int (*pointer)4, row, col; pointer=array; printf(“Input row = ”); scanf(“%d”, &row); printf(“Input col = ”); scanf(“%d”, &col);C語(yǔ)言教程課件第09章 printf(“array%1d%1d = %dn”, row, col, *(*(pointer+row)+col); 程序運(yùn)行情況: Input row = 1 Input col = 2 array12 = 7思考題思考題:本題也可以直接使用數(shù)組名array作指針,應(yīng)如何修改?(2)使用
31、列指針/*案例代碼文件名:AL9_6_2.C*/*程序功能:使用列指針輸出2維數(shù)組的任一元素*/main() int array34=1,2,3,4,5,6,7,8,9,10,11,12; int *pointer, row, col; /*定義一個(gè)(列)指針變量pointer*/ pointer=array0; /*給(列)指針變量pointer賦值*/ printf(“Input row = ”); scanf(“%d”,&row); printf(“Input col = ”); scanf(“%d”,&col); printf(“array%1d%1d = %dn”,
32、row, col, *(pointer+(row*4+col); C語(yǔ)言教程課件第09章 3. 2維數(shù)組指針作函數(shù)參數(shù) 2維數(shù)組的指針作函數(shù)實(shí)參時(shí),有列指針和行指針兩種形式。相應(yīng)的,用來(lái)接受實(shí)參數(shù)組指針的形參,必須使用相應(yīng)形式的指針變量,如下所示: 實(shí)參: 列指針 行指針 形參: (列)指針變量 行指針變量 9.3.5 動(dòng)態(tài)數(shù)組的實(shí)現(xiàn)動(dòng)態(tài)數(shù)組的實(shí)現(xiàn) 在程序運(yùn)行過(guò)程中,數(shù)組的大小是不能改變的。這種數(shù)組稱為靜態(tài)數(shù)組。靜態(tài)數(shù)組的缺點(diǎn)是:對(duì)于事先無(wú)法準(zhǔn)確估計(jì)數(shù)據(jù)量的情況,無(wú)法做到既滿足處理需要,又不浪費(fèi)內(nèi)存空間。 所謂動(dòng)態(tài)數(shù)組是指動(dòng)態(tài)數(shù)組是指,在程序運(yùn)行過(guò)程中,根據(jù)實(shí)際需要指定數(shù)組的大小。 在C語(yǔ)言中
33、,可利用內(nèi)存的申請(qǐng)和釋放庫(kù)函數(shù),以及指向數(shù)組的指針變量可當(dāng)數(shù)組名使用的特點(diǎn),來(lái)實(shí)現(xiàn)動(dòng)態(tài)數(shù)組。 C語(yǔ)言教程課件第09章 動(dòng)態(tài)數(shù)組的本質(zhì)是動(dòng)態(tài)數(shù)組的本質(zhì)是:一個(gè)指向數(shù)組的指針變量一個(gè)指向數(shù)組的指針變量。案例案例9.7 動(dòng)態(tài)數(shù)組的實(shí)現(xiàn)。/*案例代碼文件名:AL9_7.C*/*程序功能:實(shí)現(xiàn)動(dòng)態(tài)數(shù)組*/#include “alloc.h”#include “stdlib.h”main() int *array=NULL, num, i; printf(“Input the number of element: ”); scanf(“%d”, &num); /*申請(qǐng)動(dòng)態(tài)數(shù)組使用的內(nèi)存塊*/ ar
34、ray=(int *)malloc( sizeof(int) * num ); if ( array=NULL )/*內(nèi)存申請(qǐng)失?。禾崾荆顺?/ printf(“out of memory, press any key to quit”); exit(0);/*exit():終止程序運(yùn)行,返回操作系統(tǒng)*/ C語(yǔ)言教程課件第09章 /*提示輸入num個(gè)數(shù)據(jù)*/ printf(“Input %d elements: ”, num); for (i=0; inum; i+) scanf(“%d”, &arrayi); /*輸出剛輸入的num個(gè)數(shù)據(jù)*/ printf(“%d elements
35、 are: ”, num); for (i=0; inum; i+) printf(“%d,”, arrayi); printf(“b ”);/*刪除最后一個(gè)數(shù)據(jù)后的分隔符“,”*/ free(array);/*釋放由malloc()函數(shù)申請(qǐng)的內(nèi)存塊*/ 程序運(yùn)行情況程序運(yùn)行情況: Input the number of element: 3 Input 3 elements: 1 2 3 3 elements are: 1,2,3 C語(yǔ)言教程課件第09章程序說(shuō)明程序說(shuō)明:(1) array=(int *)malloc( sizeof(int) * num );語(yǔ)句malloc()函數(shù)和siz
36、eof運(yùn)算符1)庫(kù)函數(shù)malloc()用法:void *malloc(unsigned size)功能:在內(nèi)存的動(dòng)態(tài)存儲(chǔ)區(qū)分配個(gè)長(zhǎng)度為size的連續(xù)空間。返回值:申請(qǐng)成功,則返回新分配內(nèi)存塊的起始地址;否則,返回NULL。函數(shù)原型:alloc.h,stdlib.h。malloc()函數(shù)的返回值是一個(gè)無(wú)類(lèi)型指針,其特點(diǎn)是可以指向任何類(lèi)型的數(shù)據(jù)。但在實(shí)際使用實(shí)際使用malloc()函數(shù)時(shí),必須將其返回值強(qiáng)制轉(zhuǎn)換成函數(shù)時(shí),必須將其返回值強(qiáng)制轉(zhuǎn)換成被賦值指針變量的數(shù)據(jù)類(lèi)型被賦值指針變量的數(shù)據(jù)類(lèi)型,以免出錯(cuò)。2)運(yùn)算符sizeof格式:sizeof(變量名類(lèi)型名)功能:求變量類(lèi)型占用的內(nèi)存字節(jié)數(shù)(正整數(shù)
37、)。例如,在IBM-PC機(jī)上,sizeof(int)=2。C語(yǔ)言教程課件第09章思考題思考題:在該語(yǔ)句中,使用sizeof(int)求出1個(gè)int型數(shù)據(jù)占用的內(nèi)存字節(jié)數(shù),而不是使用常量“2”,為什么?(2) scanf(“%d”, &arrayi);語(yǔ)句和printf(“%d,”, arrayi);語(yǔ)句將指向數(shù)組的指針變量當(dāng)作數(shù)組名使用,所以就必須按引用數(shù)組元素的語(yǔ)法規(guī)則來(lái)使用。(3) printf(“b ”);語(yǔ)句 “b” 在該語(yǔ)句中的作用是,使光標(biāo)定位到最后一個(gè)數(shù)據(jù)后的分隔符“,”上,然后再輸出一個(gè)空格,以達(dá)到刪除之目的。C語(yǔ)言教程課件第09章(4) free(array);語(yǔ)句庫(kù)
38、函數(shù)free()用法:void free(void *ptr)功能:釋放由ptr指向的內(nèi)存塊(ptr是調(diào)用malloc() 函數(shù)的返回值)。返回值:無(wú)。函數(shù)原型:stdlib.h,alloc.h。原則上,使用使用malloc()函數(shù)申請(qǐng)的內(nèi)存塊,操作結(jié)束后,函數(shù)申請(qǐng)的內(nèi)存塊,操作結(jié)束后,應(yīng)及時(shí)使用應(yīng)及時(shí)使用free()函數(shù)予以釋放。函數(shù)予以釋放。尤其是循環(huán)使用malloc()函數(shù)時(shí),如果不及時(shí)釋放不再使用的內(nèi)存塊,很可能很快就耗盡系統(tǒng)的內(nèi)存資源,從而導(dǎo)致程序無(wú)法繼續(xù)運(yùn)行。ReturnC語(yǔ)言教程課件第09章9.4 字符串的指針和指向字符串的指針變量字符串的指針和指向字符串的指針變量字符串在內(nèi)存中
39、的起始地址稱為字符串的指針,可以定義一個(gè)字符指針變量指向一個(gè)字符串。9.4.1 字符串的表示與引用字符串的表示與引用在語(yǔ)言中,既可以用字符數(shù)組表示字符串,也可用字符指針變量來(lái)表示;引用時(shí),既可以逐個(gè)字符引用,也可以整體引用。1.逐個(gè)引用案例案例9.8 使用字符指針變量表示和引用字符串。/*案例代碼文件名:AL9_8.C*/main() char *string=”I love Beijing.”; for(; *string!=0; string+) printf(“%c”, *string); printf(“n”); C語(yǔ)言教程課件第09章程序運(yùn)行結(jié)果: I love Beijing.程序
40、說(shuō)明:程序說(shuō)明:char *string=I love Beijing.;語(yǔ)句定義并初始化字符指針變量string:用串常量“I love Beijing.”的地址(由系統(tǒng)自動(dòng)開(kāi)辟、存儲(chǔ)串常量的內(nèi)存塊的首地址)給string賦初值。該語(yǔ)句也可分成如下所示的兩條語(yǔ)句: char *string; string=I love Beijing.;注意注意:字符指針變量string中,僅存儲(chǔ)串常量的地址,而串常量的內(nèi)容(即字符串本身),是存儲(chǔ)在由系統(tǒng)自動(dòng)開(kāi)辟的內(nèi)存塊中,并在串尾添加一個(gè)結(jié)束標(biāo)志0。C語(yǔ)言教程課件第09章2.整體引用案例案例9.9 采取整體引用的辦法,改寫(xiě)案例案例9.8。/*案例代碼文件
41、名:AL9_9.C*/*程序功能:使用字符指針變量表示和引用字符串*/main() char *string=”I love Beijing.”; printf(“%sn”,string); 程序說(shuō)明程序說(shuō)明:printf(%sn,string);語(yǔ)句通過(guò)指向字符串的指針變量string,整體引用它所指向的字符串的原理:系統(tǒng)首先輸出string指向的第一個(gè)字符,然后使string自動(dòng)加,使之指向下一個(gè)字符;重復(fù)上述過(guò)程,直至遇到字符串結(jié)束標(biāo)志。C語(yǔ)言教程課件第09章注意注意:其它類(lèi)型的數(shù)組,是不能用數(shù)組名來(lái)一次性輸出它的全部元素的,只能逐個(gè)元素輸出。例如: int array10=; . pr
42、intf(%dn,array); /*這種用法是非法的*/ .3.字符指針變量與字符數(shù)組之比較雖然用字符指針變量和字符數(shù)組都能實(shí)現(xiàn)字符串的存儲(chǔ)和處理,但二者是有區(qū)別的,不能混為一談。(1)存儲(chǔ)內(nèi)容不同。字符指針變量中存儲(chǔ)的是字符串的首地址,而字符數(shù)組中存儲(chǔ)的是字符串本身(數(shù)組的每個(gè)元素存放一個(gè)字符)。C語(yǔ)言教程課件第09章(2)賦值方式不同。對(duì)字符指針變量,可采用下面的賦值語(yǔ)句賦值: char *pointer; pointer=This is a example.;而字符數(shù)組,雖然可以在定義時(shí)初始化,但不能用賦值語(yǔ)句整體賦值。下面的用法是非法的: char char_array20; cha
43、r_array=This is a example.; /*非法用法*/(3)指針變量的值是可以改變的,字符指針變量也不例外;而數(shù)組名代表數(shù)組的起始地址,是一個(gè)常量,而常量是不能被改變的。9.4.2 字符串指針作函數(shù)參數(shù)字符串指針作函數(shù)參數(shù)C語(yǔ)言教程課件第09章案例案例9.10 用函數(shù)調(diào)用方式,實(shí)現(xiàn)字符串的復(fù)制。/*案例代碼文件名:AL9_10.C*/*/*string_copy()函數(shù):復(fù)制一個(gè)字符串 */*形參:字符指針str_from接收源串,字符指針 str_to存儲(chǔ)目標(biāo)串 */*返回值:無(wú) */*/void string_copy(char *str_from, char *str_
44、to) int i=0; for(; (*(str_to+i)=*(str_from+i)!=0; i+) ; /*循環(huán)體為空語(yǔ)句*/ main() char array_str120=”I am a teacher.”; char array_str220; string_copy(array_str1, array_str2); /*數(shù)組名作實(shí)參*/ printf(“array_str2=%sn”, array_str2); C語(yǔ)言教程課件第09章程序運(yùn)行結(jié)果: I am a teacher.程序說(shuō)明程序說(shuō)明:for(; (*(str_to+i)=*(str_from+i)!=0; i+)
45、 ; 語(yǔ)句的執(zhí)行過(guò)程為:首先將源串中的當(dāng)前字符,復(fù)制到目標(biāo)串中;然后判斷該字符(即賦值表達(dá)式的值)是否是結(jié)束標(biāo)志。如果不是,則相對(duì)位置變量i的值增1,以便復(fù)制下一個(gè)字符;如果是結(jié)束標(biāo)志,則結(jié)束循環(huán)。其特點(diǎn)是:先復(fù)制、后判斷,循環(huán)結(jié)束前,結(jié)束標(biāo)志已經(jīng)復(fù)制。在C語(yǔ)言中,用賦值運(yùn)算符、而不是賦值語(yǔ)句來(lái)實(shí)現(xiàn)賦值操作,能給某些處理帶來(lái)很大的靈活性,該語(yǔ)句(實(shí)現(xiàn)字符串的復(fù)制)的用法就是最好的例證。ReturnC語(yǔ)言教程課件第09章9.5 返回指針值的函數(shù)返回指針值的函數(shù) 一個(gè)函數(shù)可以返回一個(gè)int型、float型、char型的數(shù)據(jù),也可以返回一個(gè)指針類(lèi)型的數(shù)據(jù)。 返回指針值的函數(shù)(簡(jiǎn)稱指針函數(shù))的定義格式
46、如下: 函數(shù)類(lèi)型函數(shù)類(lèi)型 *函數(shù)名函數(shù)名(形參表形參表) 案例案例9.11 某數(shù)理化三項(xiàng)競(jìng)賽訓(xùn)練組有3個(gè)人,找出其中至少有一項(xiàng)成績(jī)不合格者。要求使用指針函數(shù)實(shí)現(xiàn)。/*案例代碼文件名:AL9_11.C*/*/*seek()函數(shù):判斷是否有不合格成績(jī) */*形參:指向由3個(gè)int型元素組成的1維數(shù)組的行指針變量 */*返回值:(1)有不合格成績(jī),則返回指向本行首列的一個(gè)(列)指針; */* (2)沒(méi)有有不合格成績(jī),返回值為指向下一行的一個(gè)(列)指針 */*/C語(yǔ)言教程課件第09章int *seek( int (*pnt_row)3 ) int i=0, *pnt_col; /*定義一個(gè)(列)指針變
47、量pnt_col */ pnt_col=*(pnt_row+1); /*使pnt_col指向下一行之首(作標(biāo)志用)*/ for(; i3; i+) if(*(*pnt_row+i)60) /*某項(xiàng)成績(jī)不合格*/ pnt_col=*pnt_row; /*使pnt_col指向本行之首*/ break; /*退出循環(huán)*/ return(pnt_col); C語(yǔ)言教程課件第09章/*主函數(shù)main()*/main() int grade33=55,65,75,65,75,85,75,80,90; int i,j,*pointer; /*定義一個(gè)(列)指針變量pointer */ for(i=0; i3
48、; i+) /*控制每個(gè)學(xué)生*/ pointer=seek(grade+i); /*用行指針作實(shí)參,調(diào)用seek()函數(shù)*/ if(pointer=*(grade+i) /*該學(xué)生至少有一項(xiàng)成績(jī)不合格*/ /*輸出該學(xué)生的序號(hào)和各項(xiàng)成績(jī)*/ printf(“No.%d grade list: ”, i+1); for(j=0; j3; j+) printf(“%d ”,*(pointer+j); printf(“n”); 程序運(yùn)行結(jié)果:No.1 grade list: 55 65 75C語(yǔ)言教程課件第09章 程序說(shuō)明:程序說(shuō)明:(1) 主函數(shù)中的pointer=seek(grade+i);語(yǔ)句
49、調(diào)用seek()函數(shù)時(shí),將實(shí)參grade+i(行指針)的值,復(fù)制到形參pnt_row(行指針變量)中,使形參pnt_row指向grade數(shù)組的第i行。(2)在指針函數(shù)seek()中: 1) pnt_col=*(pnt_row+1);語(yǔ)句*(pnt_row+1)將行指針轉(zhuǎn)換為列指針,指向grade數(shù)組的第i+1行第列,并賦值給(列)指針變量pnt_col。2) if(*(*pnt_row+i)60)行pnt_row是一個(gè)行指針,指向數(shù)組grade的第i行;*pnt_row使指針由行轉(zhuǎn)換為列,指向數(shù)組grade的第i行列;*pnt_row+j的值還是一個(gè)指針,指向數(shù)組的第i行第j列;*(*pnt_
50、rowj)是一個(gè)數(shù)據(jù)(數(shù)組元素gradeij的值)。ReturnC語(yǔ)言教程課件第09章9.6 指針數(shù)組與主函數(shù)指針數(shù)組與主函數(shù)main()的形參的形參9.6.1 指針數(shù)組指針數(shù)組 1.概念 數(shù)組的每個(gè)元素都是一個(gè)指針數(shù)據(jù)。指針數(shù)組比較適合用于指向多個(gè)字符串,使字符串處理更加方便、靈活。 2.定義格式 數(shù)據(jù)類(lèi)型數(shù)據(jù)類(lèi)型 *數(shù)組名數(shù)組名元素個(gè)數(shù)元素個(gè)數(shù) 注意注意:與行指針變量定義格式“(*行指針變量)”的差別。 案例案例9.12 有若干計(jì)算機(jī)圖書(shū),請(qǐng)按字母順序,從小到大輸出書(shū)名。解題要求:使用排序函數(shù)完成排序,在主函數(shù)中進(jìn)行輸入輸出。/*案例代碼文件名:AL9_12.C*/*程序功能:指針數(shù)組應(yīng)用
51、示例*/C語(yǔ)言教程課件第09章/*/* sort()函數(shù):對(duì)字符指針數(shù)組進(jìn)行排序 */*形參:name字符指針數(shù)組,count元素個(gè)數(shù)*/*返回值:無(wú) */*/void sort(char *name, int count) char *temp_p; int i,j,min; /*使用選擇法排序*/ for(i=0; icount-1; i+) /*外循環(huán):控制選擇次數(shù)*/ min=i; /*預(yù)置本次最小串的位置*/ for(j=i+1; j0) /*存在更小的串*/ min=j; /*保存之*/ if(min!=i) /*存在更小的串,交換位置*/ temp_p=namei,namei=n
52、amemin,namemin=temp_p; C語(yǔ)言教程課件第09章/*主函數(shù)main()*/main() char *name5=“BASIC”,”FORTRAN”,”P(pán)ASCAL”,”C”,”FoxBASE”; int i=0; sort(name,5); /*使用字符指針數(shù)組名作實(shí)參,調(diào)用排序函數(shù)sort()*/ /*輸出排序結(jié)果*/ for(; i5; i+) printf(“%sn”,namei); 程序運(yùn)行結(jié)果:BASICCFORTRANFoxBASEPASCALC語(yǔ)言教程課件第09章程序說(shuō)明:程序說(shuō)明:(1)實(shí)參對(duì)形參的值傳遞: sort( name , 5 ); void sort(char *name, int count)(2)字符串的比較只能使用strcmp()函數(shù)。形參字符指針數(shù)組n a m e 的 每 個(gè) 元 素 , 都 是 一 個(gè) 指 向 字 符 串 的 指 針 , 所 以 有strcmp(namemin,namej)。9.6.2 主函數(shù)主函數(shù)main()的形參的形參在以往的程序中,主函數(shù)main()都使用其無(wú)參形式。實(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年教師多媒體培訓(xùn)計(jì)劃:打造高質(zhì)量教育體系的關(guān)鍵
- 校本培訓(xùn)個(gè)人工作總結(jié)
- 企業(yè)出納專(zhuān)員崗位職責(zé)與工作內(nèi)容(30篇)
- 夏令營(yíng)開(kāi)營(yíng)講話稿(4篇)
- 2025年小學(xué)英語(yǔ)教學(xué)研討會(huì):微型課教案研究
- 養(yǎng)貓藥品知識(shí)培訓(xùn)課件
- 2025年宏觀經(jīng)濟(jì)學(xué)課件模板
- 物流系統(tǒng)分析 課件 任務(wù)四 認(rèn)識(shí)物流系統(tǒng)的要素
- 2023年天津卷高考真題數(shù)學(xué)試卷
- 汽車(chē)故障診斷與修復(fù)流程
- 煙臺(tái)大學(xué)化學(xué)化工學(xué)院實(shí)驗(yàn)室儀器設(shè)備搬遷項(xiàng)目
- 安全生產(chǎn)管理組織架構(gòu)圖
- 2022版10kV架空配電線路無(wú)人機(jī)自主巡檢作業(yè)導(dǎo)則
- 近二十年俄羅斯修辭學(xué)研究述評(píng)
- 委托付款三方協(xié)議中英文版
- 約克中央空調(diào)冷水機(jī)組年度維保方案
- 高中英語(yǔ)-Unit 2 Reading and Thinking A day in the clouds教學(xué)課件設(shè)計(jì)
- 新聞采訪與寫(xiě)作課件第十九章融合報(bào)道
- 《消防專(zhuān)篇》編制規(guī)定
- 常用小學(xué)生詞語(yǔ)成語(yǔ)積累歸類(lèi)大全
- 提高出院患者隨訪率持續(xù)改進(jìn)項(xiàng)目
評(píng)論
0/150
提交評(píng)論