版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、北京郵電大學(xué)出版社,第8章 指針,8.1 地址與指針 8.2 指針變量 8.3 指針與數(shù)組 8.4 指針與字符串 8.5 指針與函數(shù) 8.6 指針數(shù)組 8.7 多級指針 本章小結(jié) 習(xí)題參考答案,北京郵電大學(xué)出版社,8.1 地址與指針,地址:一般把存儲(chǔ)器中的一個(gè)字節(jié)稱為一個(gè)內(nèi)存單元。計(jì)算機(jī)為每個(gè)內(nèi)存單元進(jìn)行編號(hào),內(nèi)存單元的編號(hào)也就是內(nèi)存單元的地址. 指針:通常也把這個(gè)地址稱為指針。所以說指針本質(zhì)上就是地址。 注:內(nèi)存單元的地址(即指針)和內(nèi)存單元的內(nèi)容是兩個(gè)不同的概念。 指針變量:在語言中,允許用一個(gè)變量來存放指針,這種變量稱為指針變量。,北京郵電大學(xué)出版社,指針和指針變量:一個(gè)指針是一個(gè)地址,
2、是一個(gè)常量。而一個(gè)指針變量卻可以被賦予不同的指針值,是變量。 但常把指針變量簡稱為指針。 引進(jìn)指針的目的,就是為了能直接訪問內(nèi)存單元。 獲取數(shù)據(jù)單元或代碼的指針: 例如變量a,使用取地址運(yùn)算符 /* 不允許保存整型數(shù)據(jù)*/ pointer1= /* 3.14是常數(shù),不能使用 其中,*表示這是一個(gè)指針變量。 類型說明符表示本指針變量所指向的變量的數(shù)據(jù)類型。 而指針變量自身的類型就是指針型。 例如: int *p2; /*p2是指向整型變量的指針變量*/ float *p3; /*p3是指向浮點(diǎn)變量的指針變量*/ char *p4; /*p4是指向字符變量的指針變量*/,北京郵電大學(xué)出版社,8.2
3、.2指針變量的引用 兩種與指針有關(guān)的運(yùn)算符: /* *p表示取指針變量p所指向單元的內(nèi)容,即變量x的值,因此y=10 */ 注意:在第一個(gè)語句中“*p”表示將p定義為一個(gè)指針變量,用以區(qū)別一般的變量,而第三個(gè)語句中的“*p”是使用指針變量,此時(shí)“*”是指針運(yùn)算符,表示取出指針變量p所指向單元的內(nèi)容。如圖8.3:,北京郵電大學(xué)出版社,8.2.3 指針變量的使用 指針變量的初始化方式有兩種: 1指針變量初始化的方法 int a; int *p=,北京郵電大學(xué)出版社,x=*ip; *ip訪問的是地址為1800的存儲(chǔ)單元 等價(jià)于 x=i; 另外,指針變量值是可以改變的,即可以改變它們的指向,假設(shè) ch
4、ar i,j,*p1,*p2; i=a; j=b; p1=,北京郵電大學(xué)出版社,北京郵電大學(xué)出版社,這時(shí)賦值表達(dá)式語句: p2=p1; 就是使p2與p1指向同一對象i,此時(shí)的*p2就等價(jià)于i,而不是j,如圖8.6所示:,北京郵電大學(xué)出版社,如果執(zhí)行如下賦值表達(dá)式語句: *p2=*p1; 實(shí)際上就是j=i; 則表示把p1指向的內(nèi)容賦給p2所指的區(qū)域,,此時(shí)就變成圖8.7所示,北京郵電大學(xué)出版社,通過指針訪問它所指向的一個(gè)變量是以間接訪問的形式進(jìn)行的,所以比直接訪問一個(gè)變量要費(fèi)時(shí)間,而且不直觀。 例如*p2=*p1;實(shí)際上就是j=i;,前者不僅速度慢而且目的不明。但靈活性,使代碼簡潔和有效。 指針
5、變量可出現(xiàn)在表達(dá)式中。設(shè) int x,y;*px= px+ */ ),北京郵電大學(xué)出版社,例8.1寫出下列程序的運(yùn)行結(jié)果 main() int a ,b ,p; int *p1, *p2; a=10; b=20; p1= 運(yùn)行結(jié)果: 20,10 20,10,北京郵電大學(xué)出版社,例8.2寫出下列程序的運(yùn)行結(jié)果。 main() int a,b; int *p1, *p2,*p; a=10; b=20; p1= 運(yùn)行結(jié)果: 10,20 20,10 請讀者自己思考本題與例題8.1的區(qū)別在哪兒?為什么結(jié)果不一樣?,北京郵電大學(xué)出版社,8.3 指針與數(shù)組,8.3.1通過指針訪問一維數(shù)組 在C語言中,指針和
6、數(shù)組有著非常緊密的聯(lián)系,其原因在于凡是由數(shù)組下標(biāo)完成的操作皆可用指針來實(shí)現(xiàn)。在數(shù)組中我們知道,可以通過數(shù)組的下標(biāo)唯一確定數(shù)組中的某個(gè)元素,這種訪問方式稱為“下標(biāo)法”。 例如: int a5=1,2,3,4,5 ,x , y; x=a0 ; /* 通過下標(biāo)將數(shù)組a中下標(biāo)為0的元素賦給x,x=1 */ y=a3 ; /*通過下標(biāo)將數(shù)組a中下標(biāo)為3的元素賦給y,y=4 */ 由于數(shù)組中的每個(gè)元素都相當(dāng)于相應(yīng)類型的變量,指針變量可以指向一般的變量,因此指針變量也可以指向數(shù)組中的元素,也可以用“指針法”來訪問數(shù)組中的元素。我們以前知道數(shù)組中的各個(gè)元素都是按順序連續(xù)的存在內(nèi)存中,因此,我們只要知道一個(gè)數(shù)組
7、的首地址即第一個(gè)元素的地址,然后依次往下移動(dòng),就能找到該數(shù)組的所有元素。,北京郵電大學(xué)出版社,例 8.3 main() int a= 1,2,3,4,5,6; int x,y,*p; p=”表示將數(shù)組a的首地址即a0的地址賦給指針變量p,即p就指向了該數(shù)組的首地址。,北京郵電大學(xué)出版社,在C語言中,獲取數(shù)組的首地址有兩種方法: 1數(shù)組中第一個(gè)元素的地址,如:”等價(jià)于“p=a”。 如例8.3對于指針變量p指向了數(shù)組的首地址,p+1就代表數(shù)組中元素a1的地址,p+2也代表元素a2的地址,依次類推,p+i 就代表ai的地址,同樣 a+i也代表ai的地址;因此對于數(shù)組的元素ai的值,同樣可以用*(p+
8、i)或*(a+i)表示,這種訪問數(shù)組元素的方法也稱為指針法。如圖8.9所示:,北京郵電大學(xué)出版社,對于數(shù)組元素的訪問,下標(biāo)法和指針法是等價(jià)的。設(shè)a是一個(gè)數(shù)組名,指針變量p指向了數(shù)組a的首地址,對于數(shù)組a元素的表示方法有4種: 1下標(biāo)法:ai 或 pi 2指針法:*(a+i) 或 *(p+i) 但是讀者要注意,數(shù)組名和指針變量p本身并不完全等同;數(shù)組名代表一個(gè)地址常量,是數(shù)組的首地址,不能被用戶改變它的值,不同于指針變量,指針變量的值是可以被改變的。因此語句:p+、+p、p=p+1都是正確的;而語句:a+、+a、a=a+1都是錯(cuò)誤的。 例8.4 輸出數(shù)組a中的全部元素。 main() int a
9、10,i; for(i=0;i10;i+) *(a+i)=i; for(i=0;i10;i+) printf(a%d=%dn,i,*(a+i); ,北京郵電大學(xué)出版社,例8.5分析以下程序。 main() int a=1,2,3,4,5,*p; p=a; printf(%dn,*p); printf(%dn,*(+p); printf(%dn,*(p-); p+=3; printf(%dn%dn,*p,*(a+3); ,運(yùn)行結(jié)果: 1 2 2 4 4,北京郵電大學(xué)出版社,例 8.6 通過移動(dòng)指針來訪問數(shù)組中的所有元素。 main() int *p,i,a8; p=a; for(i=0;i8;i
10、+,p+) *p=i; p=a; for(i=0;i8;i+,p+) printf(a%d=%dn,i,*p); ,北京郵電大學(xué)出版社,8.3.2通過指針訪問二維數(shù)組 在C語言中,二維數(shù)組是按行優(yōu)先的規(guī)律轉(zhuǎn)換一維數(shù)組存放在內(nèi)存中,因此,可以通過指針訪問二維數(shù)組中的元素。若有: int a43 ,*p; p= 則二維數(shù)組a的數(shù)據(jù)元素在內(nèi)存中存儲(chǔ)順序及地址關(guān)系如圖8.10所示:,北京郵電大學(xué)出版社,這里,a表示二維數(shù)組的首地址;a0表示0行的元素的起始地址,a1表示1行的元素的起始地址,a2表示2行的元素的起始地址,a3表示3行的元素的起始地址。因此a和a0是數(shù)組a00的地址,也是0行的地址。a+
11、1和a1是數(shù)組元素a10的地址,也是1行的首地址。 由于a是二維數(shù)組,經(jīng)過兩次下標(biāo)運(yùn)算 之后才能訪問到數(shù)組元素。所以根據(jù)C語言的地址計(jì)算方法,a要經(jīng)過兩次*操作才能訪問到數(shù)組元素。這樣就有,*a或a0就是數(shù)組元素 a00的地址,*a就是元素a00,同樣*a0也表示數(shù)組元素a00。 1二維數(shù)組的指針 假設(shè)有如下數(shù)組定義語句: int array34; (1)從二維數(shù)組角度看,數(shù)組名array代表數(shù)組的起始地址。 array+i:行指針值,指向二維數(shù)組的第i行。 *(array+i):(列)指針值,指向第i行第0列(控制由行轉(zhuǎn)為列,但仍為指針)。 *(*(array+i):數(shù)組元素arrayi0的
12、值。 用array作指針訪問數(shù)組元素arrayij的格式: *(*(array+i)j),北京郵電大學(xué)出版社,(2)從一維數(shù)組角度看,數(shù)組名array和第1維下標(biāo)的每一個(gè)值,共同構(gòu)成一組新的一維數(shù)組名array0、array1、array2,它們均由4個(gè)元素組成。 C語言規(guī)定:數(shù)組名代表數(shù)組的起始地址,所以arrayi是第i行一維數(shù)組的地址,它指向該行的第0列元素,是一個(gè)以數(shù)組元素為單位進(jìn)行控制的列指針: arrayi+j:(列)指針值,指向數(shù)組元素arrayij。 *(arrayi+j):數(shù)組元素arrayij的值。 如果有“int array34,*p=array0;”,則p+1指向下一個(gè)
13、元素,如圖8.12所示。,北京郵電大學(xué)出版社,用p作指針訪問數(shù)組元素arrayij的格式: *(p+(*每行列數(shù)+j) 2行指針變量(數(shù)組指針)指向由n個(gè)元素組成的一維數(shù)組的指針變量 (1)定義格式 數(shù)據(jù)類型 (*指針變量)n; 注意:“*指針變量”外的括號(hào)不能缺,否則成了指針數(shù)組數(shù)組的每個(gè)元素都是一個(gè)指針變量。 (2)賦值 行指針變量 二維數(shù)組名 (或行指針變量);,北京郵電大學(xué)出版社,例8.7 使用行指針輸出二維數(shù)組的任一元素。 main() int array34=1,2,3,4,5,6,7,8,9,10,11,12; int (*p)4, row, col; p=array; prin
14、tf(Input row=); scanf(%d, ,北京郵電大學(xué)出版社,例 8.8 使用列指針輸出二維數(shù)組的任一元素。 main() int array34=1,2,3,4,5,6,7,8,9,10,11,12; int *p, row, col; /*定義一個(gè)(列)指針變量p*/ p=array0; /*給(列)指針變量p賦值*/ printf(Input row=); scanf(%d, 程序運(yùn)行結(jié)果: Input row=1 Input col=1 array11=6,北京郵電大學(xué)出版社,8.3.3指針的基本運(yùn)算 對于指針的運(yùn)算有三種:指針與正整數(shù)的加減運(yùn)算、兩個(gè)指針的關(guān)系運(yùn)算以及兩個(gè)
15、指針的減法運(yùn)算。 指針與正整數(shù)的加減運(yùn)算 當(dāng)指針p指向數(shù)組中的元素時(shí),n為一個(gè)正整數(shù),則表達(dá)式: p+n 表示:指針p所指向當(dāng)前元素之后的第n個(gè)元素。而表達(dá)式 p-n 表示:指針p所指向當(dāng)前元素之前的第n個(gè)元素。 最常見的指針加減運(yùn)算為p+的含義是:指針加1,指向數(shù)組中的下一個(gè)元素;p-的含義是:指針減1,指向數(shù)組中的前一個(gè)元素。 由于指針p所指的具體對象不同,所以對指針與整數(shù)進(jìn)行加減運(yùn)算時(shí),C語言會(huì)根據(jù)所指的不同對象計(jì)算出不同的放大因子,以保證正確操作實(shí)際的運(yùn)算對象。對于字符型,放大因子為1;對于整型,放大因子為2;對于長整型,放大因子為4;對于雙精度類型,放大因子為8。也就是說不同數(shù)據(jù)類型
16、的放大因子等于該數(shù)據(jù)類型在內(nèi)存所占的字節(jié)數(shù)。,北京郵電大學(xué)出版社,例 8.9 用指針進(jìn)行字符串的復(fù)制,把字符串str1復(fù)制到字符串str2。 # include main() char str180,str280,*p1,*p2; printf(Enter string 1:); gets(str1); p1=str1; p2=str2; while(*p2=*p1)!=0) p1+; p2+; printf(String 2:); puts(str2); ,北京郵電大學(xué)出版社,2兩個(gè)指針的關(guān)系運(yùn)算 只有當(dāng)兩個(gè)指針指向同一個(gè)數(shù)組的元素時(shí),才能進(jìn)行關(guān)系運(yùn)算。 當(dāng)指針p和指針q指向同一數(shù)組時(shí),則:
17、 當(dāng)p所指的元素在q所指的元素之前時(shí),pq; 當(dāng)p和q指向同一元素時(shí),p=q。 不允許兩個(gè)指向不同數(shù)組的指針進(jìn)行比較,因?yàn)檫@樣的判斷沒有任何實(shí)際的意義。,北京郵電大學(xué)出版社,例 8.10 編寫程序?qū)⒁粋€(gè)字符串反序 # include main() char str50,*p,*s,c; printf(Enter string:); gets(str); p=s=str; while(*p) p+; p-; while(sp) c=*s; *s+=*p; *p-=c; puts(str); ,北京郵電大學(xué)出版社,兩個(gè)指針的減法運(yùn)算 兩個(gè)指針變量之間的運(yùn)算:只有指向同一數(shù)組的兩個(gè)指針變量之間才能進(jìn)
18、行減法運(yùn)算,否則運(yùn)算毫無意義。 兩指針變量相減:兩指針變量相減所得之差是兩個(gè)指針?biāo)笖?shù)組元素之間相差的元素個(gè)數(shù)。實(shí)際上是兩個(gè)指針值(地址)相減之差再除以該數(shù)組元素的長度(字節(jié)數(shù))。例如pf1和pf2是指向同一單精度型數(shù)組的兩個(gè)指針變量,設(shè)pf1的值為2010H,pf2的值為2000H,而浮點(diǎn)數(shù)組每個(gè)元素占4個(gè)字節(jié),所以pf1-pf2的結(jié)果為(2000H-2010H)/4=4,表示pf1和 pf2之間相差4個(gè)元素。兩個(gè)指針變量不能進(jìn)行加法運(yùn)算。例如,pf1+pf2是什么意思呢?毫無實(shí)際意義。,北京郵電大學(xué)出版社,例 8.11 用指針相減求字符串的長度 # include main() char
19、str50,*p=str; printf(Enter string:); gets(str); while(*p) p+; printf(String Length=%dn,p-str); ,北京郵電大學(xué)出版社,8.4 指針與字符串,8.4.1 字符數(shù)組與字符指針 我們在前面詳細(xì)討論過字符數(shù)組與字符串,字符指針也可以指向一個(gè)字符串??梢杂米址A繉ψ址羔樳M(jìn)行初始化。例如,有說明語句: char *str1=”How are you!”; 此時(shí)字符指針指向的是一個(gè)字符串常量的首地址,即指向字符串的首地址。 這里要注意字符指針與字符數(shù)組的區(qū)別,例如,有說明語句: char str2 =”How
20、 are you!”; 此時(shí),str2是字符數(shù)組,它存放一個(gè)字符串。 字符指針str1與字符數(shù)組str2的區(qū)別是:str1是一個(gè)變量,可以改變str1的值,即str1可以指向不同內(nèi)存單元;str2是一個(gè)數(shù)組名,數(shù)組名str2的值不能改變,也就是說str2的值也是一個(gè)內(nèi)存單元的地址,但是地址不能被用戶改變。,北京郵電大學(xué)出版社,例如: char *str ,*str1=”Hello!”; char string100=”China”; 則下面語句是正確的: str+; str=”Computer”; str=str1; strcpy(string,”ABCEFGH”); strcat(strin
21、g,str); 而下面語句是錯(cuò)誤的: string+; /* 不能對數(shù)組名進(jìn)行+運(yùn)算 */ string=”How do you do!”; /* 不能給數(shù)組名進(jìn)行賦值操作 */ string=str; /* 不能給數(shù)組名進(jìn)行賦值操作 */,北京郵電大學(xué)出版社,8.4.2 字符指針舉例 在C語言中,如我們上節(jié)所討論的,有兩種方法訪問一個(gè)字符串: 1用字符數(shù)組存放一個(gè)字符串,然后輸出該字符串。 例812寫出下列程序的運(yùn)行結(jié)果 main() char string=”I love China!”; printf(%sn,string); 運(yùn)行結(jié)果: I love China! 說明:和前面介紹的數(shù)
22、組屬性一樣,string是數(shù)組名,它代表字符數(shù)組的首地址。 2用字符指針指向一個(gè)字符串。 可以不定義字符數(shù)組,而定義一個(gè)字符指針變量,用字符指針變量指向字符串中的字符。,北京郵電大學(xué)出版社,2用字符指針指向一個(gè)字符串。 可以不定義字符數(shù)組,而定義一個(gè)字符指針變量,用字符指針變量指向字符串中的字符。 例8.13寫出下列程序的運(yùn)行結(jié)果 main() char *string=”I love China!”; printf(%sn,string); 運(yùn)行結(jié)果: I love China!,例8.14在輸入的字符串中查找有無k字符。 main() char st20,*ps; int i; print
23、f(input a string:n); ps=st; scanf(%s,ps); for(i=0;psi!=0;i+) if(psi=k) printf(there is a k in the stringn); break; if(psi=0) printf(There is no k in the stringn); ,北京郵電大學(xué)出版社,例8.15將s所指字符串下標(biāo)為偶數(shù)的字符刪掉,s中剩余的字符形成的新串放在t所指的數(shù)組中。例如:當(dāng)s所指字符串為ABCDEFGHIJK,在t中所指數(shù)組中的內(nèi)容為:BDGFHJ,#include #include void fun(char *s,cha
24、r t) int i,j,n; n=strlen(s); for(i=0,j=0;in;i+) if(i%2!=0) tj=si;j+; tj= 0; main() char s80,t80; printf(nplease enter string:); scanf(%s,s); fun(s,t); printf(nthere is :%sn,t); ,北京郵電大學(xué)出版社,8.5 指針與函數(shù),我們知道在函數(shù)之間可以傳遞一般變量的值,在函數(shù)之間同樣可以傳遞地址(指針)。函數(shù)與指針之間有著密切的關(guān)系,它包含三種關(guān)系:指針作為函數(shù)的參數(shù),函數(shù)的返回值為指針及指向函數(shù)的指針。 8.5.1指針作函數(shù)的參
25、數(shù) 變量的地址屬性是變量的一個(gè)重要特性,知道了變量的地址就可以通過地址間接訪問變量的數(shù)值,變量的地址在C語言中就是指針,通過地址間接訪問變量的數(shù)值就是通過指針間接訪問指針?biāo)傅膬?nèi)容。指針作函數(shù)的參數(shù)就是在函數(shù)間傳遞變量的地址。 在函數(shù)間傳遞變量地址時(shí),函數(shù)間傳遞的不再是變量中的數(shù)據(jù),而是變量的地址。此時(shí),變量的地址在調(diào)用函數(shù)時(shí)作為實(shí)參,被調(diào)用函數(shù)使用指針變量作為形參接收傳遞的地址。這里實(shí)參的數(shù)據(jù)類型要與形參的指針?biāo)傅膶ο蟮臄?shù)據(jù)類型一致。,北京郵電大學(xué)出版社,例816 輸入的兩個(gè)整數(shù)按大小順序輸出。 swap(int *p1,int *p2) int temp; temp=*p1; *p1=*
26、p2; *p2=temp; main() int a,b; int *pointer_1,*pointer_2; scanf(%d,%d, 運(yùn)行結(jié)果: 5,7 7,5,北京郵電大學(xué)出版社,例8.17 請注意,不能企圖通過改變指針形參的值而使指針實(shí)參的值改變。 swap(int *p1,int *p2) int *p; p=p1; p1=p2; p2=p; main() int a,b; int *pointer_1,*pointer_2; scanf(%d,%d, 運(yùn)行結(jié)果: 5,9 5,9,北京郵電大學(xué)出版社,例8.18 輸入a、b、c三個(gè)整數(shù),按大小順序輸出。 swap(int *pt1,
27、int *pt2) int temp; temp=*pt1; *pt1=*pt2; *pt2=temp; exchange(int *q1,int *q2,int *q3) if(*q1*q2)swap(q1,q2); if(*q1*q3)swap(q1,q3); if(*q2*q3)swap(q2,q3); main() int a,b,c,*p1,*p2,*p3; scanf(%d,%d,%d, ,程序運(yùn)行結(jié)果: 1,2,3 3,2,1,北京郵電大學(xué)出版社,8.5 指針與函數(shù),8.5.2數(shù)組名作函數(shù)的參數(shù) 數(shù)組名可以作函數(shù)的實(shí)參和形參。本質(zhì)上也是地址傳遞。 例如: main() int a
28、rray10; f(array,10); f(int arr,int n); ,北京郵電大學(xué)出版社,其中array為實(shí)參數(shù)組名,arr為形參數(shù)組名。在學(xué)習(xí)指針變量之后就更容易理解這個(gè)問題了。數(shù)組名就是數(shù)組的首地址,實(shí)參向形參傳送數(shù)組名實(shí)際上就是傳送數(shù)組的首地址,形參得到該地址后也指向同一數(shù)組。這就好象同一件物品有兩個(gè)彼此不同的名稱一樣。如圖8.19所示。,北京郵電大學(xué)出版社,同樣,指針變量的值也是地址,數(shù)組名即為數(shù)組的首地址,當(dāng)然也可作為函數(shù)的參數(shù)使用。 例819 輸入10個(gè)學(xué)生的成績,求學(xué)生的平均成績。 float aver(float *pa); main() float score10,
29、av,*sp; int i; sp=score; printf(ninput 10 scores:n); for(i=0;i10;i+) scanf(%f, ,北京郵電大學(xué)出版社,例8.20 利用函數(shù)從10個(gè)數(shù)中找出其中最大值和最小值。 本題要求不能改變數(shù)組元素的值,求出其中的最大值和最小值,而函數(shù)調(diào)用只能得到一個(gè)返回值,因此本題利用用全局變量在函數(shù)之間“傳遞”數(shù)據(jù)。程序如下: int max,min; /*全局變量*/ void max_min_value(int array,int n) int *p,*array_end; array_end=array+n; max=min=*arra
30、y; for(p=array+1;pmax) max=*p; else if(*pmin) min=*p; ,main() int i,number10; printf(Enter 10 numbers:n); for(i=0;i10;i+) scanf(%d, 程序運(yùn)行結(jié)果: Enter 10 integer numbers: 5 4 10 9 16 8 20 12 7 11 max=20,min=4,北京郵電大學(xué)出版社,例821 將數(shù)組a中的n個(gè)整數(shù)按相反順序存放。 求解此題的算法為:將a0與an-1對換,再a1與an-2對換,直到將a(n-1/2)與an-int(n-1)/2)對換?,F(xiàn)用
31、循環(huán)處理此問題,設(shè)兩個(gè)“位置指示變量”i和j,i的初值為0(指向數(shù)組中開始的元素),j的初值為n-1(指向數(shù)組中最后的元素)。將ai與aj交換,然后使i的值加1(指向下一個(gè)元素),j的值減1(指向前一個(gè)元素),再將ai與aj交換,直到i=(n-1)/2為止。,北京郵電大學(xué)出版社,程序如下: void inv(int x,int n) /*形參x是數(shù)組名*/ int temp,i,j,m=(n-1)/2; for(i=0;i=m;i+) j=n-1-i; temp=xi; xi=xj; xj=temp; ,main() int i,a10=5,8,10,9,0,6,7,3,14,1; print
32、f(The original array:n); for(i=0;i10;i+) printf(%d,ai); printf(n); inv(a,10); printf(The array has been inverted:n); for(i=0;i10;i+) printf(%d,ai); printf(n); 程序運(yùn)行結(jié)果: The original array: 5,8,10,9,0,6,7,3,14,1 The array has been inverted: 1,14,3,7,6,0,9,10,8,5,北京郵電大學(xué)出版社,例822 用實(shí)參為指針變量改寫例題821。 void inv
33、(int *x,int n) int *p,m,temp,*i,*j; m=(n-1)/2; i=x; j=x+n-1; p=x+m; for(;i=p;i+,j-) temp=*i; *i=*j; *j=temp; ,main() int i,arr10=5,8,10,9,0,6,7,3,14,1,*p; p=arr; printf(The original array:n); for(i=0;i10;i+,p+) printf(%d,*p); printf(n); p=arr; inv(p,10); printf(The array has been inverted:n); for(p=
34、arr;parr+10;p+) printf(%d,*p); printf(n); 注意:main函數(shù)中的指針變量p是有確定值的。即如果用指針變量作為實(shí)參,必須要使指針變量有確定值,指向一個(gè)已定義的數(shù)組。,北京郵電大學(xué)出版社,例8.23 用選擇法對10個(gè)整數(shù)排序。 main() int *p,i,a10=3,7,9,11,0,6,7,5,4,2; printf(The original array:n); for(i=0;i10;i+) printf(%d,ai); printf(n); p=a; sort(p,10); for(p=a,i=0;i10;i+) printf(%d ,*p);
35、p+; printf(n); ,sort(int x,int n) int i,j,k,t; for(i=0;ixk) k=j; if(k!=i) t=xi;xi=xk;xk=t; 程序運(yùn)行結(jié)果: The original array: 3,7,9,11,0,6,7,5,4,2, 0 2 3 4 5 6 7 7 9 11 說明:函數(shù)sort用數(shù)組名作為形參,也可改為用指針變量,這時(shí)函數(shù)的首部可以改為: sort(int *x,int n) 其他可一律不改。,北京郵電大學(xué)出版社,8.5.3函數(shù)返回值是指針 函數(shù)的返回值可以是指針,返回指針的函數(shù)一般說明形式應(yīng)該是: 數(shù)據(jù)類型 *函數(shù)名(參數(shù)列表)
36、 “數(shù)據(jù)類型”后面的*表示函數(shù)的返回值是一個(gè)指向該數(shù)據(jù)類型的指針。注意,此時(shí)說明的是函數(shù),而不是指針變量。 例8.24 使用函數(shù)求兩個(gè)數(shù)的最大值。 #include int *max(int *p1,int *p2) int *p; p=*p1*p2?p1:p2; return (p); ,北京郵電大學(xué)出版社,main() int a,b,*pmax; printf(Enter a b:); scanf(%d%d, 程序運(yùn)行結(jié)果: Enter a b: 10 20 max=20 說明:函數(shù)max返回值的類型是整型指針,在函數(shù)max中使指針變量p指向大的數(shù)8,然后把p的值返回給函數(shù)max。在主函
37、數(shù)中把函數(shù)max的值賦給pmax,最后輸出pmax所指的值為20。,北京郵電大學(xué)出版社,8.5.4 指向函數(shù)的指針 在C語言中,指針的使用方法非常靈活,指向函數(shù)的指針就是一個(gè)在其它高級語言中非常罕見的功能。在定義一個(gè)函數(shù)后,編譯系統(tǒng)就為每個(gè)函數(shù)確定了一個(gè)入口地址,當(dāng)調(diào)用該函數(shù)的時(shí)候,系統(tǒng)就會(huì)從這個(gè)“入口地址”開始執(zhí)行該函數(shù)。存放函數(shù)的入口地址的指針變量就是一個(gè)指向函數(shù)的指針。其定義方式為: 類型標(biāo)識(shí)符(*指針變量)(); 類型標(biāo)識(shí)符為函數(shù)返回值的類型。特別值得注意的是,由于C語言中()的優(yōu)先級比*高,因此,“*指針變量”外部必須用括號(hào),否則指針變量首先與后面的()結(jié)合,就是前面介紹的“函數(shù)返回
38、值是指針”。試比較下面兩個(gè)說明語句: int (*pf)(); /*定義一個(gè)指向函數(shù)的指針,該函數(shù)的返回值為整型數(shù)據(jù)*/ int *f(); /*定義一個(gè)返回值為指針的函數(shù),該指針指向一個(gè)整型數(shù)據(jù)*/ 和變量的指針一樣,函數(shù)的指針也必須賦初值,才能指向具體的函數(shù)。由于函數(shù)名代表了該函數(shù)的入口地址,因此,一個(gè)簡單的方法就是直接用函數(shù)名為函數(shù)指針賦值,即: 函數(shù)指針名=函數(shù)名;,北京郵電大學(xué)出版社,例如: double fun(); /*函數(shù)原型聲明*/ double (*f)(); /*函數(shù)指針說明*/ f=fun; /*f指向fun函數(shù)*/ 函數(shù)的指針經(jīng)定義和初始化之后,在程序中就可以引用該指
39、針,目的是調(diào)用被指針?biāo)傅暮瘮?shù),由此可見,使用函數(shù)的指針增加了函數(shù)的調(diào)用方式。 例8.25 用指針調(diào)用函數(shù),實(shí)現(xiàn)輸出兩個(gè)數(shù)中的較大數(shù) #include main() int max(int,int); int (*pf)(); int a,b,c; pf=max; scanf(%d%d, ,北京郵電大學(xué)出版社,max(int a,int b) return (ab?a:b); 程序運(yùn)行結(jié)果: 8 10 a=8,b=10,max=10 在該例中,語句c=(*pf)(a,b)等價(jià)于c=max(a,b),因此當(dāng)一個(gè)指針指向一個(gè)函數(shù)時(shí),通過訪問該指針,就可以訪問它所指向的函數(shù)。 需要注意的是:一個(gè)函數(shù)
40、指針可以先后指向不同的函數(shù),將哪個(gè)函數(shù)的地址賦給它,它就指向哪個(gè)函數(shù),使用該指針,就可以調(diào)用哪個(gè)函數(shù),但是,必須用函數(shù)的地址為函數(shù)指針賦值。另外,如果有函數(shù)指針(*pf)( ),則pf+,pf+n,pf等運(yùn)算是無意義的。 引用函數(shù)指針,除了增加函數(shù)的調(diào)用方式之外,還可以將其作為函數(shù)的參數(shù),在函數(shù)中傳遞地址數(shù)據(jù),這是C語言中一個(gè)比較深入的問題,可以參考其它的書籍。,北京郵電大學(xué)出版社,8.6 指針數(shù)組,8.6.1指針數(shù)組 一個(gè)數(shù)組的元素都是指針則稱為指針數(shù)組。指針數(shù)組是一組有序的指針的集合。指針數(shù)組的所有元素都必須是具有相同存儲(chǔ)類型和指向相同數(shù)據(jù)類型的指針變量。 指針數(shù)組說明的一般形式為: 類型
41、說明符 *數(shù)組名數(shù)組長度; 其中類型說明符為指針值所指向的變量的類型。 例如: int *pa3; 表示pa是一個(gè)指針數(shù)組,它有三個(gè)數(shù)組元素,每個(gè)元素值都是一個(gè)指針,指向整型變量。 注意:不要寫成 int (*pa)3;這是一個(gè)指向一維數(shù)組的指針變量(該一維數(shù)組包括三個(gè)元素),在前面章節(jié)中已學(xué)過。 為什么要用指針數(shù)組呢?它比較適合于用來指向若干個(gè)字符串,使字符串處理更加方便靈活。這時(shí)指針數(shù)組的每個(gè)元素被賦予一個(gè)字符串的首地址。指向字符串的指針數(shù)組的初始化更為簡單。,北京郵電大學(xué)出版社,例如: char *name=Sunday,Monday,Tuesday,Wednesday,Thursday
42、, Friday,Saturday; 完成這個(gè)初始化賦值之后,name0即指向字符串Sunday,name1指向Monday, 例 8.26 輸入數(shù)字0-6,輸出對應(yīng)的星期幾的英文名稱。 # include char *week_day7=Sunday,Monday,Tuesday,Wednesday, Thursday,Friday,Saturday; main() int day; char *p,*lookstr(); printf(Enter Day:); scanf(%d, ,char *lookstr(table ,day) char *table; int day; int i;
43、 for(i=0;i!=day ,北京郵電大學(xué)出版社,8.6.2 main函數(shù)的參數(shù) 指針數(shù)組的一個(gè)重要應(yīng)用是作為main函數(shù)的形參。在我們以前的學(xué)習(xí)過程中,main函數(shù)的第一行全部寫成了以下的形式: main() 括號(hào)中為空,表示沒有參數(shù),實(shí)際上main函數(shù)是可以帶參數(shù)的,其一般形式為: main(int argc,char *argv ) 其中形參argc表示命令行參數(shù)的個(gè)數(shù),形參argv是指向命令行參數(shù)的指針數(shù)組。,北京郵電大學(xué)出版社,在操作系統(tǒng)下運(yùn)行C程序時(shí),可以以命令行參數(shù)形式向main函數(shù)傳遞參數(shù)。命令行參數(shù)的一般形式是: 運(yùn)行文件名 參數(shù)1 參數(shù)2 參數(shù)n 運(yùn)行文件名和參數(shù)之間、各個(gè)參數(shù)之間要用一個(gè)空格分隔。 argc表示命令行參數(shù)的個(gè)數(shù)(包括運(yùn)行文件名),argv是指向命令行參數(shù)的指針數(shù)組,指針數(shù)組元素argv0指向的字符串是運(yùn)行文件名,argv1指向的字符串是命令行中的參數(shù)1,argv2指向的字符串是命令行中的參數(shù)2,等等。 例8.27下列文件的運(yùn)行文件名為TEST1
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二四年企業(yè)短信服務(wù)與輿情監(jiān)控合同3篇
- 山東省臨沭縣2025屆中考生物對點(diǎn)突破模擬試卷含解析
- 二零二五年度節(jié)能減排環(huán)保產(chǎn)業(yè)投資合作協(xié)議3篇
- 2025年版鋼材貿(mào)易代理及分銷渠道建設(shè)合同4篇
- 2025年物業(yè)管理公司員工安全責(zé)任與應(yīng)急疏散通道維護(hù)合同3篇
- 2025年度鋁材產(chǎn)品質(zhì)量檢測與認(rèn)證服務(wù)合同4篇
- 二零二五年度旅游車輛租賃與景區(qū)景點(diǎn)講解合同4篇
- 2025年度洗滌房租賃與洗滌技術(shù)培訓(xùn)合同3篇
- 二零二五年度城市綠化工程臨時(shí)工派遣服務(wù)合同模板4篇
- 2025年昌月離婚協(xié)議書全新版本2篇
- GB/T 11072-1989銻化銦多晶、單晶及切割片
- GB 15831-2006鋼管腳手架扣件
- 有機(jī)化學(xué)機(jī)理題(福山)
- 醫(yī)學(xué)會(huì)自律規(guī)范
- 商務(wù)溝通第二版第4章書面溝通
- 950項(xiàng)機(jī)電安裝施工工藝標(biāo)準(zhǔn)合集(含管線套管、支吊架、風(fēng)口安裝)
- 微生物學(xué)與免疫學(xué)-11免疫分子課件
- 《動(dòng)物遺傳育種學(xué)》動(dòng)物醫(yī)學(xué)全套教學(xué)課件
- 弱電工程自檢報(bào)告
- 民法案例分析教程(第五版)完整版課件全套ppt教學(xué)教程最全電子教案
- 7.6用銳角三角函數(shù)解決問題 (2)
評論
0/150
提交評論