C語言課件教學PPT-第10章-指針-_第1頁
C語言課件教學PPT-第10章-指針-_第2頁
C語言課件教學PPT-第10章-指針-_第3頁
C語言課件教學PPT-第10章-指針-_第4頁
C語言課件教學PPT-第10章-指針-_第5頁
已閱讀5頁,還剩139頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、第十章 主要內(nèi)容 10.1地址和指針的概念 10.變量的指針和指向變量的 指針變量 10.數(shù)組與指針 10.字符串與指針 10.指向函數(shù)的指針 10.返回指針值的函數(shù) 10.指針數(shù)組和指向指針的指針 10.8有關(guān)指針的數(shù)據(jù)類型和指針運算的小結(jié) 10.1地址和指針的概念(1)計算機硬件系統(tǒng)的內(nèi)存儲器中,擁有大量的存儲單元(容量為字節(jié))。為了方便管理,必須為每一個存儲單元編號,這個編號就是存儲單元的“地址”。每個存儲單元都有一個惟一的地址。 1.內(nèi)存地址內(nèi)存中存儲單元的編號(2)在地址所標識的存儲單元中存放數(shù)據(jù)。注意:內(nèi)存單元的地址與內(nèi)存單元中的數(shù)據(jù)是兩個完全不同的概念。2.變量地址系統(tǒng)分配給變量

2、的內(nèi)存單元的起始地址假設(shè)有這樣一個程序: main() int num; scanf(%d,&num); printf(num=%dn, num); C編譯程序編譯到該變量定義語句時,將變量num 登錄到“符號表”中。符號表的關(guān)鍵屬性有兩個:一是“標識符名(id)” ,二是該標識符在內(nèi)存空間中的“地址(addr)” 。為描述方便,假設(shè)系統(tǒng)分配給變量num的2字節(jié)存儲單元為 2000 和2001,則起始地址2000就是變量num在內(nèi)存中的地址。 3.變量值的存取通過變量在內(nèi)存中的地址進行系統(tǒng)執(zhí)行“scanf(”%d“,&num);”和“printf(”num=%dn“, num);”時,存取變量

3、num值的方式可以有兩種: (1)直接訪問直接利用變量的地址進行存取 1)上例中scanf(“%d”,&num)的執(zhí)行過程是這樣的: 用變量名num作為索引值,檢索符號表,找到變量num的起始地址2000;然后將鍵盤輸入的值(假設(shè)為)送到內(nèi)存單元2000和2001中。此時,變量num在內(nèi)存中的地址和值 2)printf(num=%dn,num)的執(zhí)行過程,與scanf()很相似: 首先找到變量num的起始地址2000,然后從2000和2001中取出其值,最后將它輸出。 (2)間接訪問通過另一變量訪問該變量的值 語言規(guī)定:在程序中可以定義一種特殊的變量(稱為指針變量),用來存放其它變量的地址。例

4、如,假設(shè)定義了這樣一個指針變量num_pointer,它被分配到4000、4001單元,其值可通過賦值語句“num_pointer=num;”得到。此時,指針變量num_pointer的值就是變量num在內(nèi)存中的起始地址2000.通過指針變量num_pointer存取變量num值的過程如下:首先找到指針變量num_pointer的地址(4000),取出其值2000(正好是變量num 的起始地址); 然后從2000、2001中取出變量num的值(3)。 在語言中,指針是一種特殊的變量,它是存放地址的。(3)兩種訪問方式的比較 兩種訪問方式之間的關(guān)系,可以用某人甲(系統(tǒng))要找某人乙(變量)來類比。

5、一種情況是,甲知道乙在何處,直接去找就是(即直接訪問)。另一種情況是,甲不知道乙在哪,但丙(指針變量)知道,此時甲可以這么做:先找丙,從丙處獲得乙的去向,然后再找乙(即間接訪問)。指針和指針變量的定義:一個變量的地址稱為該變量的“指針”。例如,地址2000是變量的指針。如果有一個變量專門用來存放另一變量的地址(即指針),則它稱為“指針變量”。上述的i_pointer就是一個指針變量。為表示指針變量和它指向的變量之間的關(guān)系,用指針運算符“*”表示。 例如,指針變量num_pointer與它所指向的變量num的關(guān)系,表示為:*num_pointer,即*num_pointer等價于變量num。因此

6、,下面兩個語句的作用相同:num=3; /*將3直接賦給變量num*/num_pointer=# /*使num_pointer指向num */*num_pointer=3; /*將3賦給指針變量num_pointer所指向的變量*/ 10.2 變量的指針和指向變量的指 針變量10.1 定義一個指針變量定義指針變量的一般形式為基類型 *指針變量名;下面都是合法的定義:float *pointer_; char *pointer_; 可以用賦值語句使一個指針變量得到另一個變量的地址,從而使它指向一個該變量。例如:pointer_;pointer_;在定義指針變量時要注意兩點:指針變量前面的

7、“*”,表示該變量的類型為指針型變量。例: float *pointer_1;指針變量名是pointer_1 ,而不是* pointer_1 。 (2) 在定義指針變量時必須指定基類型。需要特別注意的是,只有整型變量的地址才能放到指向整型變量的指針變量中。下面的賦值是錯誤的 float a; int * pointer_1; pointer_1=&a; 10.2.2 指針變量的引用 注意:指針變量中只能存放地址(指針),不要將一個整數(shù)(或任何其他非地址類型的數(shù)據(jù))賦給一個指針變量。 例10. 通過指針變量訪問整型變量#include voidmain ( ) int ,; int*pointe

8、r_, *pointer_; ; pointer_; /*把變量的地址賦給 pointer_1 */ pointer_; /*把變量的地址賦給 pointer_ */printf(%,%,);printf(%,%,*pointer_, *pointer_); 對“”和“*”運算符說明:如果已執(zhí)行了語句 pointer_;(1)* pointer_的含義是什么? “”和“*”兩個運算符的優(yōu)先級別相同,但按自右而左方向結(jié)合。因此,* pointer_與相同,即變量a的地址。 如果有pointer_2 * pointer_ ;它的作用是將(的地址)賦給pointer_2 ,如果pointer_2原來

9、指向,經(jīng)過重新賦值后它已不再指向了,而指向了。(2) *的含義是什么? 先進行運算,得的地址,再進行*運算。*和*pointer_的作用是一樣的,它們都等價于變量。即*與等價。(3) (*pointer_)相當于。例10 . 2 輸入和兩個整數(shù),按先大后小的順序輸出 和。#include void main() int *1,*2,*,; scanf(,);1; if();printf(=,=,); printf(max=,min=,*1,*2); 運行情況如下:,當輸入,時,由于,將和交換。交換前的情況見圖(),交換后見圖()。注意:此例中a和b并未交換,而p1和p2的值改變。10.3 指針

10、變量作為函數(shù)參數(shù)例10 . 3 對輸入的兩個整數(shù)按大小順序輸出 #include void main()void swap(int *,int *);int ,;int *pointer_,*pointer_; scanf(,);pointer_ ; pointer_2 ; if()swap( pointer_ , pointer_2 );printf(,); void swap(int *,int *) int temp; temp*1; *; *temp; 注意:此例中a和b已經(jīng)交換,而pointer_ , pointer_2的值未改變。被調(diào)用函數(shù)不能改變實參指針變量的值,但可以改變它們所

11、指向的變量的值。為了利用被調(diào)用函數(shù)改變的變量值,應該使用指針(或指針變量)作函數(shù)實參。其機制為:在執(zhí)行被調(diào)用函數(shù)時,使形參指針變量所指向的變量的值發(fā)生變化;函數(shù)調(diào)用結(jié)束后,通過不變的實參指針(或?qū)崊⒅羔樧兞浚⒆兓闹当A粝聛?。?0. 輸入、 3個整數(shù),按大小順序輸出。#include void main() void exchange(int *1, int *2, int *3); int ,*,*,*; scanf(%,%,%,&, &, &); exchange (,); printf(,); void exchange(int *, int *, int *) void swap(

12、int *, int *); if(*) swap(,); if(*) swap(,); if(* swap(,); void swap(int *, int *) int temp; temp*; *; *temp; 10.3 數(shù)組與指針 一個變量有地址,一個數(shù)組包含若干元素,每個數(shù)組元素都在內(nèi)存中占用存儲單元,它們都有相應的地址。指針變量既然可以指向變量,當然也可以指向數(shù)組元素(把某一元素的地址放到一個指針變量中)。所謂數(shù)組元素的指針就是數(shù)組元素的地址。 10.3.1 指向數(shù)組元素的指針數(shù)組的指針數(shù)組在內(nèi)存中的起始地址,數(shù)組元素的指針數(shù)組元素在內(nèi)存中的起始地址。2.指向數(shù)組的指針變量的定義

13、指向數(shù)組的指針變量的定義,與指向普通變量的指針變量的定義方法一樣。例如: ; (定義為包含個整型數(shù)據(jù)的數(shù)組)*; (定義為指向整型變量的指針變量)應當注意,如果數(shù)組為型,則指針變量的基類型亦應為型。 對該指針變量賦值:;把元素的地址賦給指針變量。也就是使指向數(shù)組的第號元素,如圖:在C中,數(shù)組名代表數(shù)組的首地址。因此p=a ; 與p=&a0;是等價的。p = a ; 是將a 數(shù)組的首地址賦給指針變量p。但這里的a 并不代表整個數(shù)組。上面定義可寫成: int*p=a;作用是把a數(shù)組首元素地址賦給指針變量p(不是*p)10.通過指針引用數(shù)組元素 若p = a ; 是將整型數(shù)組a的首地址賦給整型指針變

14、量 p,則 *p=5; 是將整數(shù)5賦給a數(shù)組的第一個元素a0,等價于a0=5 。 p+1表示指針變量p當前所指的數(shù)組元素的下一個元素。但p+1 不是p的值加 1 。若有 p=&a0; 則 p+i (或a+i) 就是 a i 的地址 (因為a代表數(shù)組a的首地址)。 若有p=&a0; 則*(p+i)或*(a+i)就是p+i或a+i所指向的數(shù)組元素, 即ai。也就是說 *(p+i) = *(a+i) = ai。 指向數(shù)組的指針變量可以帶下標,如:pi 與 *( p+i)是等價的。引用一個數(shù)組元素,可以用:() 下標法,如形式;() 指針法,如*()或*()。其中是數(shù)組名,是指向數(shù)組元素的指針變量,其

15、初值。例10.5 輸出數(shù)組中的全部元素。 假設(shè)有一個數(shù)組,整型,有個元素。要輸出各元素的值有三種方法: (1)下標法。#include void main() int ; int;for(;)scanf(,); printf();for(;)printf(,); (2) 通過數(shù)組名計算數(shù)組元素地址,找出元素的值。#include voidmain() int ; int ;for(; )scanf(,);printf(); for(;) printf(,*(); (3) 用指針變量指向數(shù)組元素。#include void main() int ; int *,; for(;) scanf(,)

16、; printf(); for(;();) printf( ,*); 這三種方法比較:1.前兩種效率相同,每次都要計算元素地址,費時較多。2.第三種方法用指針變量直指元素,不必每次從新計算地址,像P+這樣的運算速度很快,所以能大量提高執(zhí)行效率。3.下標法比較直觀,能直接知道是第幾個元素,地址法或指針法不直觀,需要仔細分析地址和指針的指向。幾個注意的問題:指針變量可以實現(xiàn)本身的值的改變。如p+是合法的;而a+是錯誤的。因為a是數(shù)組名,它是數(shù)組的首地址,是常量。要注意指針變量的當前值。請看下面的程序:例10. 通過指針變量輸出數(shù)組的個元素。 #include void main() int*,;f

17、or(; )scanf(,); printf(); for(;, ) printf(,*);程序運行情況:1 2 3 4 5 6 7 8 9 022153 234 0 0 30036 25202 11631 8259 8237 28483顯然輸出的數(shù)值并不是數(shù)組中各元素的值 #include void main() int*,;for(;)scanf(,); printg(); p=a; for(;, ) printf(,*);從上例可以看出,雖然定義數(shù)組時指定它包含10個元素,但指針變量可以指到數(shù)組以后的內(nèi)存單元,系統(tǒng)并不認為非法。*p+,由于+和*同優(yōu)先級,結(jié)合方向自右而左,等價于*(p+

18、)。*(p+)與*(+p)作用不同。若p的初值為a,則*(p+)等價a0,*(+p)等價a1。(*p)+表示p所指向的元素值加1。如果p當前指向a數(shù)組中的第i個元素,則*(p-)相當于ai-;*(+p)相當于a+i;*(-p)相當于a-i。10.3 用數(shù)組名作函數(shù)參數(shù)在第8章8.7節(jié)中介紹過可以用數(shù)組名作函數(shù)的參數(shù)如: void main() i(int arr,int ); int array; (array,); void (int arr,int ) array為實參數(shù)組名,arr為形參數(shù)組名。在學習指針變量之后就更容易理解這個問題了。數(shù)組名就是數(shù)組的首地址,實參向形參傳送數(shù)組名實際上就

19、是傳送數(shù)組的地址,形參得到該地址后也指向同一數(shù)組。這就好象同一件物品有兩個彼此不同的名稱一樣。 同樣,指針變量的值也 是地址,數(shù)組指針變量 的值即為數(shù)組的首地址 ,當然也可作為函數(shù)的 參數(shù)使用。例10 將數(shù)組中個整數(shù)按相反順序存放。#include void main() void inv(int ,int ); int , ,;printf(The original array:);for(;)printf (,);printf(); inv (,); printf(The array has been in verted:); for(;) printf (,); printf ();vo

20、id inv(int ,int ) /*形參x是數(shù)組名*/ int temp,();for(;) ;temp; ; temp; return; 運行情況如下:The original array:,The array has been inverted:,如果有一個實參數(shù)組,想在函數(shù)中改變此數(shù)組中的元素的值,實參與形參的對應關(guān)系有以下種情況: (1) 形參和實參都用數(shù)組名,如:void main() void (int ,int ) int ; (,); (2) 實參用數(shù)組名,形參用指針變量。如:void () void (int *,int )int ; (,); (3)實參形參都用指針變量

21、。例如:void main() void (int *,int )int , *p=a; (p,); (4) 實參為指針變量,形參為數(shù)組名。如: void main() void (int x ,int ) ,*p=a; (p,); #include void main() void inv(int *,int ); int ,*; printf(The original array:n ); for(;,)scanf(,);printf(); ; inv(,); /* 實參為指針變量 ,一定 要有確定值*/ printf(The array has been inverted :); for

22、(; ) printf(,*); printf(); void inv(int *,int )int,temp,*,*;(); ;for(;,)emp*;*;*temp;return; 例109 用選擇法對個整數(shù)按由大到小順序排序。 #include void main() void sort(int ,int ); int*,10; ; for(;) scanf(,); ; sort(,); for(,;)(,*);void sort(int ,int )/*把x改為*x,下面不 int ,; 變,程序依然合法*/ for(;);for(;)() ; (?。?; ; ; 10.3.4 多維數(shù)組

23、與指針 用指針變量可以指向一維數(shù)組中的元素,也可以指向多維數(shù)組中的元素。但在概念上和使用上,多維數(shù)組的指針比一維數(shù)組的指針要復雜一些。 1. 多維數(shù)組元素的地址先回顧一下多維數(shù)組的性質(zhì),可以認為二維數(shù)組是“數(shù)組的數(shù)組”,例 :定義int a34=0,1,2,3,4,5,6,7,8,9,10,11則二維數(shù)組a是由3個一維數(shù)組所組成的。設(shè)二維數(shù)組的首行的首地址為1 ,則各下標變量的首地址及其值如圖所示。語言允許把一個二維數(shù)組分解為多個一維數(shù)組來處理。因此數(shù)組a可分解為三個一維數(shù)組,即a0,a1,a2。每一個一維數(shù)組又含有四個元素。數(shù)組及數(shù)組元素的地址表示如下:從二維數(shù)組的角度來看,a是二維數(shù)組名,

24、a代表整個二維數(shù)組的首地址,也是二維數(shù)組0行的首地址,等于1000。a+1代表第一行的首地址,等于1008。如圖:a0是第一個一維數(shù)組的數(shù)組名和首地址,因此也為1000。*(a+0)或*a是與a0等效的, 它表示一維數(shù)組a00 號元素的首地址,也為1000。&a00是二維數(shù)組a的0行0列元素首地址,同樣是1000。因此,a,a0,*(a+0),*a,&a00是相等的。同理,a+1是二維數(shù)組1行的首地址,等于1008。a1是第二個一維數(shù)組的數(shù)組名和首地址,因此也為1008。&a10是二維數(shù)組a的1行0列元素地址,也是1008。因此a+1,a1,*(a+1),&a10是等同的。由此可得出:a+i,

25、ai,*(a+i),&ai0是等同的。此外,&ai和ai也是相等的。因為在二維數(shù)組中不能把&ai理解為元素ai的地址,不存在元素ai。語言規(guī)定,它是一種地址計算方法,表示數(shù)組a第i行第0個元素的首地址。由此,我們得出:ai,&ai,*(a+i)和a+i也都是相等的。另外,a0也可以看成是a0+0,是一維數(shù)組a0的0號元素的首地址,而a0+1則是a0的1號元素首地址,由此可得出ai+j則是一維數(shù)組ai的j號元素首地址,它等于&aij。由ai=*(a+i)得ai+j=*(a+i)+j。由于*(a+i)+j是二維數(shù)組a的i行j列元素的首地址,所以,該元素的值等于*(*(a+i)+j)。定義int a

26、34=1,3,5,7,;則二維數(shù)組a是由3個一維數(shù)組所組成的。設(shè)二維數(shù)組的首行的首地址為 ,則表 示 形 式含義地 址a 二維數(shù)組名,指向一維數(shù)組a0,即0行首地址2000a0,*(a+0),*a0行0列元素地址2000a+1,&a11行首地址2008a1,*(a+1)1行0列元素a10的地址2008a1+2,*(a+1)+2,&a121行2列元素a12 的地址2012*(a1+2),*(*(a+1)+2),a121行2列元素a12的值元素值為13例10.0 輸出二維數(shù)組有關(guān)的值 #include define FROMAT,void main() int 341,3,5,7,9, ,; pr

27、intf(,*); printf(,0 , *();printf(,0,00);printf(,1,);printf(,10,*(+)+);printf(,*();printf(,); printf(,*(*( ); 某一次運行結(jié)果如下:, (0行首地址和0行0列元素地址), (0行0列元素地址), (0行0首地址和0行0列元素地址), (1行0列元素地址和1行首地址), (1行0列元素地址), (2行0列元素地址), (2行首地址), (1行0列元素的值)2 . 指向多維數(shù)組元素的指針變量(1) 指向數(shù)組元素的指針變量例10.11 用指針變量輸出二維數(shù)組元素的值 #include void

28、main() int 341,3,5,7,9,11,13,15,17,19,21,23; int*; for(;) () printf(); printf(,*); 運行結(jié)果如下:1 3 5 7 9 11 13 1519 21 23 把二維數(shù)組a分解為一維數(shù)組a0,a1,a2之后,設(shè)p為指向二維數(shù)組的指針變量。可定義為: int (*p)4它表示p是一個指針變量,它指向包含4個元素的一維數(shù)組。若指向第一個一維數(shù)組a0,其值等于a,a0,或&a00等。而p+i則指向一維數(shù)組ai。從前面的分析可得出*(p+i)+j是二維數(shù)組i行j 列的元素的地址,而*(*(p+i)+j)則是i行j列元素的值。(指

29、向數(shù)組元素的指針變量p求aij則需要用 i*m+j來求其位置。)二維數(shù)組指針變量說明的一般形式為:類型說明符 (*指針變量名)長度其中“類型說明符”為所指數(shù)組的數(shù)據(jù)類型。“*”表示其后的變量是指針類型?!伴L度”表示二維數(shù)組分解為多個一維數(shù)組時,一維數(shù)組的長度,也就是二維數(shù)組的列數(shù)。應注意“(*指針變量名)”兩邊的括號不可少,如缺少括號則表示是指針數(shù)組(本章后面介紹),意義就完全不同了。 (2) 指向由個元素組成的一維數(shù)組的指針變量例10.13 出二維數(shù)組任一行任一列元素的值#include void main ( ) int 1,3,5,7,9,11, 13,15,;int (*),; ;sc

30、anf( ,); printf(, ,*(*(); 運行情況如下:,(本行為鍵盤輸入),3. 用指向數(shù)組的指針作函數(shù)參數(shù)例10.13 有一個班,個學生,各學門課,計算總平均分數(shù)以及第個學生的成績。這個題目是很簡單的。只是為了說明用指向數(shù)組的指針作函數(shù)參數(shù)而舉的例子。用函數(shù)average求總平均成績,用函數(shù)search找出并輸出第個學生的成績。#include void main() void average(float *p,int n); void search(float (*p)4,int n); float score34=65,67,70,60,80, 87,90,81,90,99,

31、100,98; average(*score,12);*求12個分數(shù)的平均分*search(score,);*求序號為的學生的成績*void average(float *,int ) float*_; float sum,aver; p_end; for(;_;) sumsum(*); aversum; printf(average,aver);void search(float (*)4,int ) / * p是指向具有4個元素的一維數(shù)組的指針 */int ; printf(the score of No. % are:,); for(;) printf(5.2,*(*(); 程序運行結(jié)果

32、如下:averageThe score of No.2 are:.例10.4 在上題基礎(chǔ)上,查找有一門以上課程不及格的學生,打印出他們的全部課程的成績。 #include void main()void search(float (*p)4,int n);/*函數(shù)聲明*/ float score34=65,57,70,60,58,87, 90,81,90,99,100,98; search(score,);void search(float (*p)4,int )int ,; for(;) flag; for(;) if(*(*())flag; if() printf(No.%d fails,

33、his scores are:n,j+1); for(;) printf(%.,*(*(); printf(); 程序運行結(jié)果如下:No.1 fails, his scores are:. . . .No.2 fails, his scores are:. . . . 10. 字符串與指針10.4.字符串的表示形式 (1) 用字符數(shù)組存放一個字符串,然后輸出該字符串。例 10.5 定義一個字符數(shù)組,對它初始化, 然后輸出該字符串 #include void main()char stringI love China??; printf(,string); (2) 用字符指針指向一個字符串??梢圆?/p>

34、定義字符數(shù)組,而定義一個字符指針。用字符指針指向字符串中的字符。 例106 定義字符指針#include void main()char*string I love China??;printf(,);字符串指針變量的定義說明與指向字符變量的指針變量說明是相同的。只能按對指針變量的賦值不同來區(qū)別。對指向字符變量的指針變量應賦予該字符變量的地址。如: char c,*p=&c;表示p是一個指向字符變量c的指針變量。而: char *ps=C Language;則表示s是一個指向字符串的指針變量。把字符串的首地址賦予s。上例中,首先定義string是一個字符指針變量,然后把字符串的首地址賦予stri

35、ng(應寫出整個字符串,以便編譯系統(tǒng)把該串裝入連續(xù)的一塊內(nèi)存單元),并把首地址送入string。程序中的:char *ps=C Language;等效于:char *ps;ps=C Language;從以上兩個例子中,可以看到:1、字符數(shù)組和字符指針的概念不同。2、字符指針指向字符串,而C語言中,字符串按數(shù)組方式處理,因此,字符數(shù)組和字符指針的訪問方式相同。例如,均可以使用%s格式控制符進行整體輸入輸出。但應注意,如果不是字符數(shù)組,而是整型、實型等數(shù)字型數(shù)組,不能用%s,只能逐個元素處理。例10.7 將字符串復制為字符串。 #include void ()char am a boy,20; i

36、nt ; for(;*()!;) *()*(); *(); printf(string a is :,); printf(string b is:); for(;??;) printf(,); printf(); 也可以設(shè)指針變量,用它的值的改變來指向字符串中的不同的字符。 例10.8 用指針變量來處理例107問題。#include void main() char =I am a boy. ,20,*p1,*p2; int ; ; for(;*?。籶1,p2)*;*;printf(string is:,); printf( :);for(;??;) printf(,); printf();程序必

37、須保證使和同步移動 10.4.2 字符指針作函數(shù)參數(shù)將一個字符串從一個函數(shù)傳遞到另一個函數(shù),可以使用傳地址的方式,即用字符數(shù)組名或字符指針變量作參數(shù)。有以下四種情況: 實參 形參 數(shù)組名 數(shù)組名 數(shù)組名 字符指針變量 字符指針變量 字符指針變量 字符指針變量 數(shù)組名(1) 用字符數(shù)組作參數(shù)例10.19 用函數(shù)調(diào)用實現(xiàn)字符串的復制 #include void main() void copy_string(char from , char to ); char a = am a teacher; char =you are a student; printf(“string a= string

38、, ,); printf(“copy string a to string b:n ”); copy_string (,); printf(nstring a=%snstring b=%sn,a,b); void copy_string(char from , char to ) int ; while(from?。﹖ofrom;to; 程序運行結(jié)果如下: string aI am a teacher string b you are a student copy string a to string b:string a I am a teacherstringI am a teacher(

39、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 ); _(,);printf(nstring a=%snstring b=%sn,a,b); void copy_string(char *,char *) for(;*from!;from,to)*to*from;*to; (3)

40、 對copy string 函數(shù)還可作簡化 1、將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*from; *to; 上面的while語句還可以進一步簡化為下面的while語句:while(*to*from);它與下面語句等價:while(*to*from)?。粚?from賦給*to,如果賦值后的*to值等于則循環(huán)終止(已賦給*

41、to) 函數(shù)體中while語句也可以改用for語句:for(;(*to*from)!;);或for(;*to*from;);也可用指針變量,函數(shù)copy_string可寫為void copy_string (char from ,char )char*,*; from;while(*p2*p1)!);10.4.3 對使用字符指針變量和字符數(shù)組的討論字符數(shù)組和字符指針變量二者之間的區(qū)別:(1) 字符數(shù)組由若干個元素組成,每個元素中放一個字符,而字符指針變量中存放的是地址(字符串第1個字符的地址),決不是將字符串放到字符指針變量中。(2)賦值方式。對字符數(shù)組只能對各個元素賦值,不 能用以下辦法對字

42、符數(shù)組賦值。 char str; strI love China!; 而對字符指針變量,可以采用下面方法賦值: char*; I love China!; (3)對字符指針變量賦初值: char * love China??;等價于 char*; I love Chian?。?而對數(shù)組的初始化: char str love China!; 不能等價于 char str; str I love China??;(4) 定義了一個字符數(shù)組,在編譯時為它分配內(nèi)存單元,它有確定的地址。而定義一個字符指針變量時,給指針變量分配內(nèi)存單元,在其中可以放一個字符變量的地址。 例如: char str; scanf

43、(,str);(5) 指針變量的值是可以改變的,例如:例10.0改變指針變量的值#include void ()char*I love China?。?; printf(,); 若定義了一個指針變量,并使它指向一個字符串,就可以用下標形式引用指針變量所指的字符串中的字符。例如: #include voidmain()char* love hina!; int ; printf ( “ The sixth character is %cn,a5); for(;??;) printf(,); 10. 指向函數(shù)的指針10.5.1 用函數(shù)指針變量調(diào)用函數(shù)函數(shù)的指針:函數(shù)的入口地址(函數(shù)的首地址)。C語言

44、規(guī)定函數(shù)的首地址就是函數(shù)名,所以函數(shù)名就是函數(shù)的指針。指向函數(shù)的指針變量:存放函數(shù)入口地址(函數(shù)指針)的變量,稱為指向函數(shù)的指針變量。簡稱函數(shù)的指針變量。函數(shù)可以通過函數(shù)名調(diào)用,也可以通過函數(shù)指針調(diào)用。通過函數(shù)指針實現(xiàn)函數(shù)調(diào)用的步驟:1、指向函數(shù)的指針變量的定義: 類型 (* 函數(shù)指針變量名)(); 例如 int (*p)(); 注意:兩組括號()都不能少。int表示被指向的函數(shù)的類型,即被指向的函數(shù)的返回值的類型。2、指向函數(shù)的指針變量的賦值,指向某個函數(shù): 函數(shù)指針變量名=函數(shù)名;3、利用指向函數(shù)的指針變量調(diào)用函數(shù):(* 函數(shù)指針變量名)(實參表)例:輸入10個數(shù),求其中的最大值。/* 使

45、用函數(shù)名調(diào)用函數(shù) */main()int i,m,a10; for(i=0; i10; i+) scanf(%d,&ai); m=max(a); /* 函數(shù)調(diào)用格式:函數(shù)名(實參表) */ printf(max=%dn,m);int max(int *p) /* max在10個整數(shù)中選擇最大值 */ int i,t=*p; for(i=1; it)t=*(p+i); return t;結(jié)果:-52 87 29 79 -32 94 23 -112 46 67max=94聲明函數(shù)/* 使用函數(shù)指針變量調(diào)用函數(shù) */main()int i,m,a10,max(int *); /* declare f

46、unc */ int (*pf)(); /* define func pointer */for(i=0; imax() */ m=(*pf)(a); /* call max */ printf(max=%dn,m);聲明函數(shù)指針的定義:定義函數(shù)指針變量pf(返回整型數(shù))指針的初始化:函數(shù)指針pf指向max指針的引用:調(diào)用函數(shù)指針pf指向的函數(shù)maxint max(int *p) int i,t=*p; for(i=1; it)t=*(p+i); return t;說明:(1)定義函數(shù)指針變量時,兩組括號()都不能少。如果少了前面的一組括號=返回值類型 * 函數(shù)名();-返回值為地址值(指針)

47、的函數(shù)。(2)函數(shù)指針變量的類型是被指向的函數(shù)的類型,即返回值類型。(3)函數(shù)指針的賦值,只要給出函數(shù)名,不必給出參數(shù)。(不要給出實參或形參)。(4)用指針變量調(diào)用函數(shù)時,(* 函數(shù)指針)代替函數(shù)名。參數(shù)表與使用函數(shù)名調(diào)用函數(shù)一樣。(5)可以看出,定義的函數(shù)指針變量可以用于一類函數(shù),只要這些函數(shù)返回值類型(函數(shù)類型)相同。函數(shù)可以通過函數(shù)名調(diào)用,也可以通過函數(shù)指針調(diào)用。函數(shù)指針常常用在函數(shù)需要作為函數(shù)參數(shù)的情況。 10.5.2 用指向函數(shù)的指針作函數(shù)參數(shù) 函數(shù)指針變量常用的用途之一是把指針作為參數(shù)傳遞到其他函數(shù)。指向函數(shù)的指針也可以作為參數(shù),以實現(xiàn)函數(shù)地址的傳遞,這樣就能夠在被調(diào)用的函數(shù)中使用

48、實參函數(shù)。函數(shù)的參數(shù)除了可以是變量、指向變量的指針,數(shù)組(實際是指向數(shù)組的指針)、指向數(shù)組的指針以外,還可以是函數(shù)的指針。函數(shù)的指針可以作為函數(shù)參數(shù),在函數(shù)調(diào)用時可以將某個函數(shù)的首地址傳遞給被調(diào)用的函數(shù),使這個被傳遞的函數(shù)在被調(diào)用的函數(shù)中調(diào)用(看上去好象是將函數(shù)傳遞給一個函數(shù))。函數(shù)指針的使用在有些情況下可以增加函數(shù)的通用性,特別是在可能調(diào)用的函數(shù)可變的情況下。 實參函數(shù)名 f1 void (int (*x1)(int),int (*x2)(int,int)) int ,; (*)(); *調(diào)用函數(shù)* (*)(,);*調(diào)用函數(shù)* 例10.3 設(shè)一個函數(shù)process,在調(diào)用它的時候,每次實現(xiàn)不

49、同的功能。輸入和兩個數(shù),第一次調(diào)用process時找出和中大者,第二次找出其中小者,第三次求與之和。 #include void main() int max(int,int); /* 函數(shù)聲明 */ int min(int,int); /* 函數(shù)聲明 */ int add(int,int); /* 函數(shù)聲明 */ void process (int , int , int(*fun)(); /* 函數(shù)聲明 */ int ,; printf(enter a and b:); scanf(,);printf(max); process(,);printf(min);process(,);prin

50、tf(sum);process(,);int max(int ,int ) /* 函數(shù)定義 */int ; if(); else ; return();int min(int ,int ) /* 函數(shù)定義 */ int ; if();else ;return(); int (int ,int ) /* 函數(shù)定義 */ int; ; return();void process(int ,int ,int (*fun)(int,int) int result; result(*fun)(,); printf(, result);(1)函數(shù)process處理兩個整數(shù)數(shù),并輸出一個值。同時又要求pro

51、cess具有通用處理能力(處理求大數(shù)、小數(shù)、和),所以可以考慮在調(diào)用process時將相應的處理方法(“處理函數(shù)”)傳遞給process。(2)process函數(shù)要接受函數(shù)作為參數(shù),即process應該有一個函數(shù)指針作為形式參數(shù),以接受函數(shù)的地址。這樣process函數(shù)的函數(shù)原型應該是:int process(int x,int y,int (*f)();(3)“函數(shù)指針作為函數(shù)參數(shù)”的使用與前面介紹的步驟完全相同,即函數(shù)指針變量的定義-在通用函數(shù)process的形參定義部分實現(xiàn);函數(shù)指針變量的賦值-在通用函數(shù)的調(diào)用的虛實結(jié)合時實現(xiàn);用函數(shù)指針調(diào)用函數(shù)-在通用函數(shù)內(nèi)部實現(xiàn)。(4)main函數(shù)調(diào)

52、用通用函數(shù)process處理計算兩數(shù)中大數(shù)的過程是這樣的:l將函數(shù)名max(實際是函數(shù)max的地址)連同要處理的兩個整數(shù)a,b一起作為process函數(shù)的實參,調(diào)用process函數(shù)。lprocess函數(shù)接受來自主調(diào)函數(shù)main傳遞過來的參數(shù),包括兩個整數(shù)和函數(shù)max的地址,函數(shù)指針變量fun獲得了函數(shù)max的地址。l在process函數(shù)的適當位置調(diào)用函數(shù)指針變量fun指向的函數(shù),即調(diào)用max函數(shù)。這樣調(diào)用點就獲得了兩數(shù)大數(shù)的結(jié)果,由printf函數(shù)輸出結(jié)果。 同樣,main函數(shù)調(diào)用通用函數(shù)process處理計算兩數(shù)小數(shù)、和的過程基本一樣。(5)process函數(shù)頭部:函數(shù)指針定義中不需要指定

53、形參個數(shù)。但是一般情況函數(shù)指針指向的函數(shù)參數(shù)個數(shù)一般是數(shù)量類型相同的,以便用統(tǒng)一的格式如(*f)(x,y)去調(diào)用。process函數(shù)是一個“通用”整數(shù)處理函數(shù),它使用函數(shù)指針作為其中的一個參數(shù),以實現(xiàn)同一個函數(shù)中調(diào)用不同的處理函數(shù)。10. 返回指針值的函數(shù)一個函數(shù)可以帶回一個整型值、字符值、實型值等,也可以帶回指針型的數(shù)據(jù),即地址。其概念與以前類似,只是帶回的值的類型是指針類型而已。這種帶回指針值的函數(shù),一般定義形式為類型名 *函數(shù)名(參數(shù)表列);例如:int *(int ,int );例:返回兩個數(shù)中大數(shù)地址的函數(shù)。int *fun(int,int);main() int i,j,*p; p

54、rintf(enter two num to i,j:); scanf(%d%d,&i,&j); p=fun(i,j); /* 調(diào)用fun,返回大數(shù)地址,賦值給指針變量p */printf(max=%dn,*p); /* 打印p指向的數(shù)據(jù) */int *fun(int x,int y) /* fun函數(shù)返回形參x,y中較大數(shù)的地址(指針) */ int *z; if(xy)z=&x; else z=&y; return z;結(jié)果:enter two num to i,j:12 38max=38說明:(1)main函數(shù)從鍵盤獲得兩個整數(shù)i,j(本例12,38)。將i,j作為實參調(diào)用fun。(2)

55、通過虛實結(jié)合,fun函數(shù)的形參x,y獲得了這兩個整數(shù)(本例12,38),將大數(shù)的地址返回(本例是&y)。(3)返回的地址值賦值給main函數(shù)的指針變量p,main函數(shù)打印p指向的整型數(shù),即y的值。例104 有若干個學生的成績(每個學生有門課程),要求在用戶輸入學生序號以后,能輸出該學生的全部成績。用指針函數(shù)來實現(xiàn)。 #include void main()float *score 4=60,70,80,90, 56,89,67,88,34,78,90,66; float*search(float (*pointer)4,int n); float*; int ,; printf(enter t

56、he number of student:); scanf(,); printf(The scores of No are:,); search(,);for(;printf(,*(); float * search(float (*)4,int ) float *; *(); return(); 運行情況如下:enter the number of student:The scores of No. are:56.00 89.00 67.00 88.00例10.5 對上例中的學生,找出其中有不及格課程的學生及其學生號。#include void main()float score 4=60,

57、70,80,90,56, 89,67,88,34,78,90,66; float search(float (*pointer)4); float*; i ,; for(;)search(score );(*(score)printf(scores:,); for(;) printf(5.2,*(); printf(); float * search(float (*)4) float *; *(1); for(i=0;i4;i+) if(*(*pointer+i)60)pt=*pointer; return(); 10.7 指針數(shù)組和指向指針的指針10.7.1 指針數(shù)組的概念一個數(shù)組,若其元

58、素均為指針類型數(shù)據(jù),稱為指針數(shù)組,也就是說,指針數(shù)組中的每一個元素都相當于一個指針變量。一維指針數(shù)組的定義形式為:類型名*數(shù)組名數(shù)組長度;例如:*;定義一個4個元素的數(shù)組p,其中每個元素是一個整型指針,也即數(shù)組p是一個4元素整型指針數(shù)組。又如:char *p4;定義一個4個元素的字符指針數(shù)組p,其中每個數(shù)組元素是一個字符指針,可以指向一個字符串。也就是說利用此字符指針數(shù)組可以指向4個字符串。指針數(shù)組用得最多的是“字符型指針數(shù)組”,利用字符指針數(shù)組可以指向多個長度不等的字符串,使字符串處理更加方便、靈活,節(jié)省內(nèi)存空間。使用字符型指針數(shù)組指向多個字符串 (上頁下圖)使用字符型指針數(shù)組指向多個字符串

59、與使用兩維字符數(shù)組存儲多個字符串的比較:(1)節(jié)省存儲空間(二維數(shù)組要按最長的串開辟存儲空間)(2)便于對多個字符串進行處理,節(jié)省處理時間。(使用指針數(shù)組排序各個串不必移動字符數(shù)據(jù),只要改變指針指向的地址)例10.6 將若干字符串按字母順序(由小到大)輸出。#include #include void main()void sort(char *name ,int n); void printf(char *name ,int n); char *name =Follow me,BASIC,Great Wall,F(xiàn)ORTRAN,Computer design; int ;sort(,); pr

60、int(,);void sort(char * ,int )char *; int ,; for(; for(; if(strcmp(name,name)0)=; if(!) temp=namei; namei=namek; namek=temp; void print(char * ,int ) ; (;) printf(,); 運行結(jié)果為:Computer designFORTRANFollow meGreat Wall10.7.2 指向指針的指針指針的指針:指向指針變量的指針變量。指針的指針存放的是指針變量地址.指針變量的指針變量(指針的指針)的定義:類型 *指針變量名; P2 p1 i

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論