第八章指針課件_第1頁(yè)
第八章指針課件_第2頁(yè)
第八章指針課件_第3頁(yè)
第八章指針課件_第4頁(yè)
第八章指針課件_第5頁(yè)
已閱讀5頁(yè),還剩69頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、第8章 指 針,指針是C 語(yǔ)言中的一個(gè)重要概念,是C 語(yǔ)言的 精華、靈魂。,1. 內(nèi)存單元地址 程序中定義了變量后,在編譯時(shí)系統(tǒng)就給這個(gè)變量分配內(nèi)存單元。內(nèi)存中每一個(gè)內(nèi)存單元都有一個(gè)編號(hào),這就是“地址”。 內(nèi)存單元地址 就是編譯后系統(tǒng)分配給變量的內(nèi)存空間位置。 例如: int i , j, k;,8.1 地址和指針的概念, 數(shù)據(jù)在內(nèi)存中的存取方式:直接訪問方式 和 間接訪問方式。 直接訪問方式:按變量地址存取變量值。 間接訪問方式: 把一個(gè)變量的地址放在另一個(gè)變量中。, 內(nèi)存單元的內(nèi)容 內(nèi)存單元中存放的數(shù)值。 例如:i=3 ;j=6 ; 在2000單元中存放數(shù)值 3,3 即為內(nèi)容。 在2002

2、單元中存放數(shù)值 6,6 即為內(nèi)容。,例: printf(%d, i ) ; 其執(zhí)行是這樣的:根據(jù)變量名與地址的對(duì)應(yīng)關(guān)系,找到變量i 的地址2000,然后從由2000開始的兩個(gè)字節(jié)中取出數(shù)據(jù)(即變量的值3),把它輸出。 這種按變量地址存取變量值的方式稱為“直接訪問”方式。,例如,我們定義一個(gè)變量 i_pointer ,用來存放整型變量i 的地址: i_pointer = /* 把變量 i 的地址賦給變量 i_pointer */ 這時(shí)i_pointer的值 就是變量 i 所占用的內(nèi)存單元的起始地址(2000)。 如何存取變量i 的值?,間接訪問方式: 通過存儲(chǔ)在某一個(gè)內(nèi)存單元中的地址去存取該地址

3、所指向的內(nèi)存單元中的變量值。,要存取變量i 的值,先要找到存放i 的地址的變量(i_pointer),從中取出i 的地址(2000),然后到2000、2001字節(jié)中取出i 的值(3)。,表示將數(shù)值3送到變量中,有兩種方法: 將3 送到變量i 所標(biāo)志的單元中。 將3 送到變量i_pointer 所“指向”的單元中。 所謂“指向”就是通過地址來體現(xiàn)的。 (如右圖所示),由于通過地址可以找到所需的變量單元,因此可以說,地址“指向”該內(nèi)存單元。在C 語(yǔ)言中,將地址形象化地稱為“指針”。 一個(gè)變量的地址稱為該變量的“指針”。例如地址2000是變量i的指針。 如果有一個(gè)變量,專門用來存放另一個(gè)變量的地址(

4、即指針),則它稱為“指針變量 ”。如前面所說的i_pointer變量稱為指針變量。指針變量的值是指針(地址)。 注意:(1) “指針” 和 “指針變量” 這兩個(gè)不同的概念。 (2) 通過指針變量如何訪問變量 i 的值? (間接訪問),變量的指針就是變量的地址。存放變量地址的變量是指針變量,用來指向另一個(gè)變量。 指針變量和它所指向的變量之間,用“ * ” 表示“ 指向”。 例如 i_pointer代表指針變量,* i_pointer 是i_pointer所指向的變量。,8.2 變量的指針和指向變量的指針變量,可以看到,* i_pointer也代表一個(gè)變量,它和變量i 是同一回事。下面兩個(gè)語(yǔ)句作用

5、相同: i=3; * i_pointer=3; 第個(gè)語(yǔ)句的含義是將3 賦給指針變量i_pointer所指向的變量。,8.2.1 定義一個(gè)指針變量,指針變量是專門用來存放地址的,因此必須定義為“ 指針類型”。 指針變量定義的一般形式: 基類型 * 指針變量名 指針變量的基類型 用來指定該指針變量可以指向的變量的類型。 例如: int *pointer_1,*pointer_2 ;(指向整型變量的指針變量) float *pointer_3;(指向?qū)嵭妥兞康闹羔樧兞浚?char *pointer_4;(指向字符型變量的指針變量),注意: 1. 指針變量前面的“ * ” 表示該變量是指針變量。 指針

6、變量名是 pointer_1、pointer_2 ,而不是*pointer_1、*pointer_2 . 2. 在定義指針變量時(shí)必須指定基類型。 不同類型的數(shù)據(jù)在內(nèi)存中所占的字節(jié)數(shù)是不同的。 指針變量的類型說明 是為了告訴系統(tǒng)按變量中的地址從內(nèi)存選取幾個(gè)字節(jié)的數(shù)據(jù)進(jìn)行操作,便于 指針的移動(dòng)和指針的運(yùn)算操作。 3. 一個(gè)指針變量只能 指向同一類型的變量,即存放同一類型變量的地址。,怎樣使一個(gè)指針變量指向另一個(gè)變量呢? 可以使用賦值語(yǔ)句。 例如: float x ; char ch ; float * pointer_3 ; char * pointer_4 ; pointer_3 = ,例: i

7、nt k, i=5; int *pointer; pointer=,輸出變量 i 的值5,k的值為5,8.2.2 指針變量的引用,指針變量中只能存放地址(指針),不能將一個(gè)整型量或任何其它非地址類型的數(shù)據(jù)賦給一個(gè)指針變量。 例如賦值語(yǔ)句:pointer_1=2000; (不合法),有關(guān)地址的運(yùn)算符: 1. int *pointer_1 ,*pointer_2; /*定義指針變量,指向整型變量*/ a=100; b=10; pointer_1= ,例8.1 通過指針變量訪問整型變量。,運(yùn)行結(jié)果: 100,10 100,10,pointer_1 指向a,*pointer_1 就是變量a 。 poi

8、nter_2 指向b, *pointer_2就是變量b 。, scanf(%d,%d, ,例8.2 輸入整數(shù)a和b,按先大后小的順序輸出a和b 。,運(yùn)行結(jié)果: a=5 , b=9 max=9 , min=5,實(shí)際上并沒有交換a 和b。算法不交換整型變量的值(變量a和 b中的值沒有改變),而是交換兩個(gè)指針變量的值(即變量a和 b的地址),使p1指向大的數(shù),p2指向小的數(shù)。,8.2.3 指針變量作為函數(shù)參數(shù),例:對(duì)輸入的兩個(gè)整數(shù)按大小順序輸出。,#include void main() void swap(int *,int *); int ,; int *pointer_,*pointer_;

9、scanf(,); pointer_ ; pointer_2 ; if() swap( pointer_ , pointer_2 ); printf(,); ,void swap(int *,int *) int temp; temp*1; *; *temp; ,例:對(duì)輸入的三個(gè)整數(shù)按大小順序輸出。,#include void main() int a,b,c,*p1,*p2,*p3; scanf(%d,%d,%d, ,void exchange(int *q1,int *q2,int *q3) if(*q1*q2)s); if(*q1*q3)s); if(*q2*q3)s); ,void s

10、 *pt1,int *pt2) int temp; temp=*pt1; *pt1=*pt2; *pt2=temp; ,一個(gè)變量有地址,一個(gè)數(shù)組包含若干元素,每個(gè)元素在內(nèi)存中占用存儲(chǔ)單元,它們也應(yīng)該有相應(yīng)的地址。一個(gè)變量既然可以指向變量,當(dāng)然也可以指向數(shù)組和數(shù)組元素。 所謂數(shù)組的指針是指 數(shù)組的起始地址。數(shù)組元素的指針是數(shù)組元素的地址 。 例如:int a10 , i , *p, *p1; p= a; 或 p=,8.3 數(shù)組的指針和指向數(shù)組的指針變量,引用數(shù)組元素可以用下標(biāo)法(如a3),也可以用指針法,即通過指向數(shù)組元素的指針找到所需的元素。使用指針法能使目標(biāo)程序質(zhì)量高(占用內(nèi)存少,運(yùn)行速度快

11、)。,8.3.1 指向數(shù)組元素的指針,例如: int a10; int *p; . p=,指向數(shù)組元素的指針變量,其定義與普通指針變量的定義相同。,把元素a0 的地址賦給 p, 即p指向 數(shù)組a 的第0個(gè)元素。 因?yàn)閿?shù)組名表示數(shù)組的首地址,所以它 等價(jià)于 p=a ; 應(yīng)注意數(shù)組a 并不代表整個(gè)數(shù)組,而是把數(shù)組a 的首地址賦給指針變量p,不是把數(shù)組a 的各個(gè)元素賦給p。,假設(shè)已經(jīng)定義了數(shù)組和一個(gè)指針變量 int a10; int *p=a; . *p=1;,數(shù)組元素的引用可以用 1. 下標(biāo)法: ai 2. 指針法: *(a+i) 或 *(p+i) 其中p 為指向數(shù)組a 的指針變量,初值 p=a;

12、 下標(biāo)法比較直觀,程序容易閱讀,指針表示,8.3.2 通過指針引用數(shù)組元素,對(duì)p 當(dāng)前所指的元素 賦整數(shù)值1,注意: C規(guī)定 :p+1 (或p+) 指向同一數(shù)組的下一個(gè)元素 (不是地址值簡(jiǎn)單加1)。p+1代表的實(shí)際地址是 p+1d(d是一個(gè)數(shù)組元素所占的字節(jié)數(shù))。 當(dāng) p 的初值為 a 的首地址時(shí), p+i 或 a+i 就是ai 的地址,因?yàn)?a 代表了數(shù)組的首地址。 *(p+i) 或*(a+i) 所指的數(shù)組元素就是ai 的內(nèi)容。 實(shí)際上, 是變址運(yùn)算符,對(duì)ai 的處理,是將ai 按a+i 計(jì)算地址,然后找出此地址單元中的值。 指向數(shù)組的指針變量也可以帶下標(biāo), 如: pi 等價(jià)于*(p+i)

13、,即ai 。,例8.5 輸出數(shù)組中全部元素 :四種方法。,main( ) int a10=1,2,3,4,5,6,7,8,9,10; int *p, i ; printf(n下標(biāo)法:n) ; for(i=0 ; i10 ; i+) printf(%d, ai) ; printf(n指針法(數(shù)組名):n); for(i=0 ; i10 ; i+) printf(%d, *(a+i) ; printf(n指針法(指針變量):n) ; p=a; for(i=0 ; i10 ; i+) printf(%d, *(p+i) ; printf(n指針法(指針變量):n) ; for(p=a ; pa+10

14、 ; p+) printf(%d ,*p) ; printf(n) ; ,否!a+的操作是非法的,因 a是常量。,能否改成如下形式? for(p=a;ap+10; a+) printf(%d,*a),幾種方法的比較: 下標(biāo)法和指針法(數(shù)組名)執(zhí)行效果是相同的。編譯系統(tǒng)先將ai 轉(zhuǎn)換為*(a+i),即先計(jì)算元素地址,因此這兩種方法找數(shù)組元素比較費(fèi)時(shí)。 指針變量法是直接指向數(shù)組元素,p+的自加操作比較快。 用下標(biāo)法比較直觀。,例 8.6 通過指針變量輸入輸出數(shù)組 a 的10個(gè)元素 main( ) int *p , i , a10 ; p=a ; for(i=0 ; i10 ; i+ ) scanf

15、(%d, ,如果輸出時(shí)沒有語(yǔ)句 p=a; 程序?qū)??,P是地址,不要加 則:,一、 多維數(shù)組的地址 例. 二維數(shù)組 int a34=1,3,5,7,9,11,13,15,17,19,21,23; 分析二維數(shù)組的性質(zhì): a 是一個(gè)數(shù)組名,包含3個(gè)元素: a0,a1,a2。 每個(gè)元素又是一個(gè)一維數(shù)組,包含4個(gè)元素。,8.3.4 指向多維數(shù)組的指針和指針變量, 從二維數(shù)組的角度看,a 代表整個(gè)二維數(shù)組的首地址,也就是第0行的首地址。 若a 的首地址為2000,因?yàn)槊恳恍?個(gè)元素,占用8個(gè)字節(jié),所以則 a+1的首地址為2008,a+2的首地址為2016。 故a+1 代表第1行的首地址,即a1的地址;a

16、+2 代表第2行的首地址,即a2的地址。, 由于a0 與 *(a+0) 等價(jià),a1 與 *(a+1) 等價(jià),ai 與 *(a+i) 等價(jià),因此ai+j 與*(a+i)+j 等價(jià),它們都是元素aij 的地址。 故:元素aij 的地址表示是: ai+j 或 *(a+i)+j 而 *(*(a+i)+j) 或 *(ai+j) 是元素 aij的值。, a0、a1、a2既然是一維數(shù)組名,則它們應(yīng)代表一維數(shù)組的首地址。 a0代表第0行一維數(shù)組中第0列元素的地址,即 printf(FORMAT, a , *a) ;1 printf(FORMAT, a0 , *(a+0) ;2 printf(FORMAT, 8

17、 ,(假設(shè)系統(tǒng)給數(shù)組 a 分配的首地址為 2000) 則運(yùn)行結(jié)果是:,注意: a 是二維數(shù)組名,代表數(shù)組首地址,不能企圖用*a來得到a00的值。 *a 相當(dāng)于*(a+0) ,即a0,它是第0行地址。 a是行指針,*a是列指針,指向0行0列元素。*a是0行0列元素的值。 a+1指向第一行首地址,不能企圖用*(a+1)得到a10的值,而應(yīng)該用*(a+1) 求a10元素的值。,2000, 2000 2000, 2000 2000, 2000 2008, 2008 2008, 2008 2016, 2016 2016, 2016 9, 9,例 8.12 用指針變量輸出數(shù)組元素的值。 main( ) i

18、nt a34=1,3,5,7,9,11,13,15,17,19,21,23 ; int *p ; for(p=a0 ; pa0+12 ; p+) printf(%4d , *p) ; ,運(yùn)行結(jié)果: 1 3 5 7 9 11 13 15 17 19 21 23,p-a0:為相距的單元個(gè)數(shù),不是字節(jié)數(shù) 若: a0 2000 p 2008 則: p-a0 = 4,1. 指向數(shù)組元素的指針變量,二、指向多維數(shù)組的指針變量,if(p-a0)%4 = = 0) printf(n) ;,數(shù)組元素在數(shù)組中的位置: 計(jì)算某個(gè)指定的數(shù)組元素在數(shù)組中的位置(即相對(duì)于數(shù)組起始位置的相對(duì)位移量): 設(shè)a是大小為 nm

19、的二維數(shù)組,則 元素 aij 在數(shù)組中的相對(duì)位置的計(jì)算公式為: i*m+j 若 p 是一個(gè)指針變量,指向二維數(shù)組 a 的首地址: p=,若定義: int a34; p= /*p指向 a0*/ 則p+1 不是指向a01,而是a1,p的增值以一維數(shù)組的長(zhǎng)度為單位。故aij可表示為:*(*(p+i)+j)。,例 8.13 輸出二維數(shù)組任一行任一列元素的值。,main( ) int a34=1,3,5,7,9,11,13,15,17,19,21,23 ; int (*p)4 , i , j ; p=a ; scanf(%d,%d , ,運(yùn)行結(jié)果: 輸入: 1, 2 輸出: a12=13,說明: aij

20、 的地址可以表示為: *(p+i) + j 。注意*(p+i) + j 不能寫成 p+ i+j。 對(duì)于數(shù)組指針p, p=a; 則p 指向二維數(shù)組 a 的第一行首地址 。 對(duì)于指針變量 p,p=a0;則 p 指向二維數(shù)組 a 的第一行第一列元素首地址, 而 p=a ; 是不合法 的。,void average(float *p, int n) float *p_end; float sum=0 , aver; p_end=p+n-1; for( ; p=p_end; p+ ) sum=sum + (*p); aver=sum/n; printf(average=%6.2n,aver); void

21、 search( float (*p)4 , int n) int j ; printf(the score of No. %d are:n, n); for (j=0 ; j4 ; j+) printf(%5.2f , *(*(p+n)+j) ); ,由于 p 指向一維數(shù)組,因此,*(p+n) 是第 n 行的首地址, *(p+n)+j 是 第 n 行第 j 列元素的地址。,運(yùn)行結(jié)果: average=82.25 the score of No.2 are: 90.00 99.00 100.00 98.00,最后一個(gè)元素的地址,從指向第一個(gè)元素起, 依次指向下一個(gè)元素,例 8.15 在上例中,

22、找出有一門以上不及袼的學(xué)生,輸出其全部成績(jī)。,void search( float (*p)4 , int n) int i , j , flag; for(j=0 ; jn ; j+) flag=0 ; for (i=0 ; i4 ; i+) if(*(*(p+j)+i)60) flag=1 ; if(flag= = 1) printf(No. %d fails , his scores are :n , j+1); for(i=0 ; i4 ; i+) printf(%5.1f , *(*(p+j)+i) ); ,程序運(yùn)行結(jié)果: No.1 fails,his scores are: 65.

23、0 57.0 70.0 60.0 No.2 fails,his scores are : 58.0 87.0 90.0 81.0,8. 4. 1 字符串表示形式 在C程序中,可以用兩種方法訪問一個(gè)字符串。 1. 用字符數(shù)組存放一個(gè)字符串 例 8.16,main( ) char string = I love China! ; printf(%sn , string) ; 運(yùn)行結(jié)果: I love China!,8.4 字符串的指針和指向字符串的指針變量,字符串常量按字符數(shù)組處理,在內(nèi)存中開辟了一個(gè)字符數(shù)組來存放字符串常量,這里 string 是數(shù)組名,代表這個(gè)字符數(shù)組的首地址。 stringi

24、就是 *(string+i) 。,2. 用字符指針指向一個(gè)字符串 例 8.17 main( ) char *string = I love China! ; printf(%sn , string) ; ,注意: 不能認(rèn)為string是一個(gè)字符串變量,以為是在定義時(shí)把“I love China!” 賦給該字符串變量。 通過字符數(shù)組名或字符指針變量可以輸出一個(gè)字符串( %s 的格式),但是不能企圖用數(shù)組名輸出它的全部元素(%d 只能輸出一個(gè)元素值)。 由于可以用數(shù)組或指針來表示字符串,因此對(duì)字符串中字符的存取可以用下標(biāo)法,也可以用指針法。,等價(jià)于: char *string; string=I

25、love China!; 定義一個(gè)指向字符數(shù)據(jù)的指針,把該字符串的首地址賦給 string,定義一個(gè)指針變量 string ,指向字符串的首地址。,例 8.18 復(fù)制字符串 a 到字符串 b。用下標(biāo)方法:,main( ) char a =I am a boy.; char b20; int i; for(i=0 ; *(a+i)!=0 ; i+) *(b+i)=*(a+i); *(b+i)=0; /* 復(fù)制0 */ printf(string a is :%sn,a); printf(string b is :); for(i=0 ; bi!=0 ; i+) printf(%c,bi); pr

26、intf(n); ,運(yùn)行結(jié)果: string a is :I am a boy. string b is :I am a boy.,字符指針作函數(shù)參數(shù),用函數(shù)調(diào)用實(shí)現(xiàn)字符串的復(fù)制,(1) 用字符數(shù)組作參數(shù),#include void main() void copy_string(char from , char to ); char a = am a teacher; char =you are a student; printf(“string a= string ,); printf(“copy string a to string b:n ”); copy_string (,); pr

27、intf(nstring a=%snstring b=%sn,a,b); ,void copy_string(char from , char to ) int ; while(from?。?tofrom; to; ,(2) 形參用字符指針變量,#include void main() void copy_string(char * from, char *); char * am a teacher .; char *you are a student ; printf(string a=string ,); printf(copy string a to string b:n ); _(,

28、); printf(nstring a=%snstring b=%sn,a,b); ,void copy_string(char *r,char *) for(;*from!;from,to) *tofrom; *to; ,(3) 對(duì)copy string 函數(shù)還可作簡(jiǎn)化,將copy_string函數(shù)改寫為 void copy_string (char *from,char *) while(*from)?。?to;from; , copy_string函數(shù)的函數(shù)體還可改為 while(*to*from)?。?,copy_string函數(shù)的函數(shù)體還可寫成 while(*from?。?*to*

29、from; *to; ,上面的while語(yǔ)句還可以進(jìn)一步簡(jiǎn)化為下面的while語(yǔ)句: while(*to*from); 它與下面語(yǔ)句等價(jià): while(*to*from)!); 將*from賦給*to,如果賦值后的*to值等于則循環(huán)終止(已賦給*to),函數(shù)體中while語(yǔ)句也可以改用for語(yǔ)句: for(;(*to*from)!;); 或 for(;*to*from;);,也可用指針變量,函數(shù)copy_string可寫為 void copy_string (char from ,char ) char*,*; from; while(*p2*p1)?。?,2. 初始化與賦值方式。 字符指針

30、變量可以在定義時(shí)初始化,也可以用賦值語(yǔ)句賦值。 如,char *a =I love China! ; 與char *a ; a=I love China! ; 等價(jià)。,8.4.3 字符指針變量與字符數(shù)組的討論,將字符串的首地址 賦給該指針變量。,兩者都能用于字符串的存儲(chǔ)和運(yùn)算,但是兩者是有區(qū)別的: 字符數(shù)組由若干元素組成,每個(gè)元素中存放一個(gè)字符;字符指針變量中存放的是字符串的首地址,決不是將字符串放到字符指針變量中。,3. 數(shù)組一經(jīng)定義,就有了確定的內(nèi)存單元。 字符指針變量定義后,雖然也分配了內(nèi)存單元,在沒有對(duì)指針變量賦初值之前,這個(gè)單元中沒有一個(gè)確定的地址值,因此該指針并未具體指向某個(gè)字符數(shù)

31、據(jù)。,4. 數(shù)組名代表該數(shù)組的起始地址,它的值不能改變;指針變量的值可以改變 例8.21,main( ) char str =I love China! ; str=str+7 ; printf(%s , str) ; ,main( ) char *a=I love China! ; int j ; printf(The sixth character is %cn , a5) ; for(j=0 ; aj!= 0 ; j+) printf(%c , aj) ; ,運(yùn)行結(jié)果: The sixth character is e I love China!,若定義了一個(gè)指針變量,并使它指向一個(gè)字符

32、串,就可用下標(biāo)形式引用指針變量所指的字符串中的字符。 例 8.22,*(a+j),運(yùn)行結(jié)果:China!,不合法,5. 可以用指針變量指向一個(gè)格式字符串,用于代替printf 函數(shù)中的格式字符串。 例如:,char *format ; format=a=%d,b=%fn ; printf(format , a , b) ;,char format =a=%d,b=%fn ; printf(format , a , b) ;,它相當(dāng)于 printf(a=%d,b=%fn , a , b) ; 因此,只要改變指針變量format 所指向的字符串,就可以改變輸入輸出的格式。這種printf 函數(shù)稱為

33、可變格式輸出函數(shù)。 也可以用字符數(shù)組實(shí)現(xiàn)。如,由于不能用賦值語(yǔ)句對(duì)數(shù)組整體賦值,所以使用指針變量的方式較方便。,指向函數(shù)的指針變量定義的一般形式: 數(shù)據(jù)類型標(biāo)識(shí)符 (*指針變量名) ( ) ;,例如: int (*p)( );,p 所指向的函數(shù)的返回值的類型 (即函數(shù)值的類型),(*p) 表示 p 先與 * 結(jié)合,即說明 p 是指針變量,然后再與后面的 ( ) 結(jié)合,表示指針 p 指向函數(shù)。,c= max(a , b);,注意: 1. 這里 (*p)( ) 只表示定義了一個(gè)存放函數(shù)入口地址的指針變量,在把某個(gè)函數(shù)的地址賦給它之前,并不指向哪個(gè)函數(shù),在程序中把某個(gè)函數(shù)的地址賦給它后才指向這個(gè)函數(shù)

34、,因此,一個(gè)函數(shù)指針變量可以先后指向不同的函數(shù)。 2. 函數(shù)指針變量賦初值:只需給出函數(shù)名而不必給出參數(shù) 如: p=max; 3. 用指針變量調(diào)用函數(shù)時(shí),只用 (*p) 代替函數(shù)名即可。 如: c=(*p) (a , b) ; 4. 指向函數(shù)的指針變量的算術(shù)運(yùn)算沒有意義,例如:p+ , p+n , p- -,這里 *p 外面的 ( ) 不能省,int max(x,y) int x,y; return(xy?x:y); ,調(diào)用 p 所指向的函數(shù),8.7.1 指針數(shù)組 指針數(shù)組 數(shù)組元素均為指針類型數(shù)據(jù), 即每個(gè)元素都是指針變量。 指針數(shù)組的定義形式: 類型標(biāo)識(shí) *數(shù)組名 數(shù)組長(zhǎng)度 例如: int

35、 *p4,例如: 若干個(gè)字符串的排序和查找。 由于字符串本身就是一個(gè)字符數(shù)組,而各個(gè)字符串的長(zhǎng)度又不同,因此用二維數(shù)組處理不太方便。 如果用指針數(shù)組,使各元素分別指向各個(gè)字符串,那么只要改變指針數(shù)組中各元素的指向,就可對(duì)所指的字符串進(jìn)行排序。,注意與 int (*p)4 的區(qū)別!,8.7 指針數(shù)組和指向指針的指針,由于 的優(yōu)先級(jí)高于* , p 先與 結(jié)合表示數(shù)組,然后 p 再與 * 結(jié)合,表示數(shù)組是指針類型,int 表示每個(gè)數(shù)組元素指向一個(gè)整型變量.,例如:有若干字符串,長(zhǎng)短不一,可以分別定義一些字符串,然后用指針數(shù)組中的元素分別指向各字符串。如果想對(duì)字符串排序,不必改動(dòng)字符串的位置,只需改動(dòng)

36、指針數(shù)組中各元素的指向。這樣,各字符串的長(zhǎng)度可以不同,且移動(dòng)指針要比移動(dòng)字符串所花的時(shí)間少得多。,void print(char *name , int n) int i; for(i=0 ; in ; i+) printf(%sn, namei) ; ,#include main( ) void sort(char *name , int n ); void print(char *name , int n); char *name =Follow me, BASIC, Great Wall, FORTRAN, Computer design; int n=5; /* 字符串個(gè)數(shù) */ so

37、rt(name , n) ; print(name ,n) ; ,void sort(char *name , int n) char *temp; int i , j , k ; for(i=0 ; i0) k=j; if (k != i) temp=namei; namei=namek; namek=temp; ,例8.27 將n 個(gè)字符串按字母順序(由小到大)排序輸出( 設(shè) n=5 ),運(yùn)行結(jié)果: BASIC Computer design FORTRAN Follow me Great Wall,定義形式: 類型標(biāo)識(shí) * 變量名 例如: char *p,由于*是從右到左結(jié)合,因此 *p

38、 相當(dāng)于 *(*p),8.7.2 指向指針的指針,例如: char *name5; char *p ; p=name +2; printf(%on, *p) ; printf(%sn , *p) ;,例8.28 使用指向指針的指針,main( ) char *name =Follow me, BASIC, Great Wall, FORTRAN, Computer design ; char *p ; int j ; p=name ; for(j=0 ; j5 ; j+) printf(%sn , *(p+j) ; ,以%o 輸出name2的值(地址),以%s 輸出name2的字符串Great

39、 Wall,運(yùn)行結(jié)果: Follow me BASIC FORTRAN Great Wall Computer design,main( ) int a5=1,3,5,7,9 ; int *num5= ,例 8.29,運(yùn)行結(jié)果: 13579,8.8.1 指針類型的小結(jié),8.8 指針類型和指針運(yùn)算的小結(jié),指針運(yùn)算有如下幾種: 1. 指針變量 可以和整數(shù)進(jìn)行加(減),例如: p+ , p- - , p+i , p-i , p+=i , p-=i ; 注意:p+ 1 指的是加 1 個(gè)單位,即 p 所指向的變量占用的內(nèi)存字節(jié)數(shù),如 p是指向 整型變量的指針,則加 2個(gè)字節(jié)。 2. 指針變量可以賦值(賦

40、地址),例如: p= ( NULL 表示整數(shù) 0 ),在 stdio.h 中有定義:#define NULL 0 任何指針變量或地址都可以與NULL作相等或不相等的比較,如 if(p=NULL) 4. 兩個(gè)指針變量可以相減,即 p2 - p1 ,表示兩個(gè)指針之間的元素個(gè)數(shù)。 但p1+p2 無意義。 5. 若兩個(gè)指針指向同一個(gè)數(shù)組的元素,則可以進(jìn)行比較, 例如: p1p2 , p1=p2 .,8.8.2 指針運(yùn)算小結(jié),它可以用來表示指向一個(gè)抽象的數(shù)據(jù)類型。例如: char *p1 ; void *p2 ; p1=(char *) p2 ; 把 p2 強(qiáng)制轉(zhuǎn)換為指向字符變量的指針。 也可以將一個(gè)函

41、數(shù)定義為 (void *)類型,例如: void *fun(char ch1 , char ch2),指針是C語(yǔ)言中重要的概念。使用指針的優(yōu)點(diǎn)是: (1) 提高效率 ; (2) 被調(diào)函數(shù)可以改變主調(diào)函數(shù)的值,即可以返回多個(gè)值; (3) 可以實(shí)現(xiàn)動(dòng)態(tài)存儲(chǔ)分配。,8.8.3 void 指針類型,指針變量如何定義,指針和地址的關(guān)系,如何對(duì)指針進(jìn)行運(yùn)算? 如何定義和使用以下對(duì)象:指針數(shù)組、數(shù)組指針、指針的指針、函數(shù)指針、返回值為指針的函數(shù)。 如何使用字符指針? 如何通過指針來改變函數(shù)實(shí)在參數(shù)的值? 什么是命令行參數(shù)?如何正確使用?,本 章 要 點(diǎn),習(xí) 題 八 (一),(一)填空 (1) 寫出建立圖一所

42、示的存儲(chǔ)結(jié)構(gòu)所需的定義語(yǔ)句: char_. (2) 寫出圖一所示的存儲(chǔ)結(jié)構(gòu)所需的賦值語(yǔ)句: _=B ; p=_. (3) 寫出用指針變量 p 輸出字符變量的語(yǔ)句: printf(%cn ,); (二)填空 (1) 寫出建立圖二所示的存儲(chǔ)結(jié)構(gòu)所需的定義語(yǔ)句: int _ , _ ; (2) 寫出圖二所示的存儲(chǔ)結(jié)構(gòu)所需的賦值語(yǔ)句: p=_ ; (3) 寫出用指針變量 p 輸出數(shù)組 s 每一個(gè)元素值的語(yǔ)句: for(j=0 ; j6 ; j+) printf(%dt , _) ; (4) 要使 p指向數(shù)組的最后一個(gè)元素 ,改變 p的表達(dá)式是。,(三)填空 (1) 寫出建立圖三所示的存儲(chǔ)結(jié)構(gòu)所需的定義

43、語(yǔ)句: float _ , _ , _ ; (2) 寫出圖三所示的存儲(chǔ)結(jié)構(gòu)所需的賦值語(yǔ)句: k =_ ; s =_ ; p=_ ; (3) 用指針變量 s 輸出 k 的值語(yǔ)句: ; (4) 用指針變量 p 輸出 k 的值的語(yǔ)句: ;,(四)寫出以下程序運(yùn)行結(jié)果。,(1) #include main( ) int a , *ap ; a=100 ; ap= ,(4) main( ) int c =1,7,12 , *p ; p=c ; printf(%d , *+p) ; (5) #include main( ) char *ap , *s ; int j , n ; s=Happy New Y

44、ear ; ap=s ; for(n=0 ; *s ! = 0 ; +s , +n) ; for(j=0 ; jn ; +j) putchar(*ap+) ; ,習(xí) 題 八(二),(一 ) 寫出以下程序運(yùn)行結(jié)果,(1) #include main( int argc , char *argv ) printf(%d %s , argc , argv1+1) ; 若執(zhí)行命令為 test hello worl d (2) #include main( ) int a=10 , b=80 ; int *p1= ,(3) int x =1 , 2 ; int y =4 , 5 , 6 ; int z

45、=7 , 8 , 9 ; int *a =x , y , z ; main( ) int *t ; printf(%dt , *a0) ; t=a0+1 ; printf(%dt , *t) ; t=a1 ; printf(%dt , *t) ; printf(%dt , *(t+1) ; printf(%dn , *(a+2) ; ,(4) main( ) char *p ; int m ; p=abcdef ghijk! ; m=len (p) ; printf(length of = %dn , p , m) ; len (char *ptr) int j ; for(j=0 ;* pt

46、r+ != 0 ; j+) ; return( j ) ; ,例1. 查12個(gè)月英文單詞。,main( ) int n ; char *month_name( ) ; scanf(%d , ,3、 int a10 ; void input( ) int j ; for(j=0 ; j=max) max=*(a+j) ; n=j ; if(m0) temp=*(a+0) ; *(a+0)=*(a+m) ; *(a+m)=temp ; if(n9) temp=*(a+9) ; *(a+9)=*(a+n) ; *(a+n)=temp ; ,void print( ) int j ; for(j=0

47、; j10 ; j+) printf(%4d , *(a+j) ; main( ) input( ) ; change( ) ; print( ) ; ,指針習(xí)題解答,6、 #include main( ) int len(char *ptr) ; char s80 , *p ; int m ; gets(s) ; p=s ; m=len(p) ; printf(%d , m) ; int len(char *ptr) int n ; for( n=0 ; *ptr!=0 ; ptr+) n+ ; return( n ) ; ,7、 #include #include main( ) void copystr(char *p1 , char *p2 , int n) ; int m ; char str180 , str280 ; printf(Input a string:n) ; gets(str2) ; printf(Input m:

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝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ù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 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)論