C語言教程課件Ch10指針_第1頁
C語言教程課件Ch10指針_第2頁
C語言教程課件Ch10指針_第3頁
C語言教程課件Ch10指針_第4頁
C語言教程課件Ch10指針_第5頁
已閱讀5頁,還剩34頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、第十章指 針本章主要內(nèi)容指針和地址的概念指針變量指向數(shù)組/字符串時的操作指針變量做函數(shù)參數(shù)幾種指針類型返回指針值的函數(shù)重點(diǎn)、難點(diǎn)如何理解指針和地址的概念靈活使用指向一位數(shù)組/字符串的指針靈活使用指針變量/數(shù)組名做函數(shù)參數(shù)掌握幾種指針的概念與函數(shù)一章的例題結(jié)合,掌握參數(shù)單向傳遞的實(shí)質(zhì)10.1 指針的概念10.2 變量的指針和指向變量的指針變量10.3 數(shù)組的指針和指向數(shù)組的指針變量10.4 字符串的指針和指向字符串的指針變量10.5 函數(shù)的指針和指向函數(shù)的指針變量10.6 返回指針的函數(shù)10.7 指針數(shù)組和指向指針的指針10.8 有關(guān)指針的數(shù)據(jù)類型和指針運(yùn)算的小結(jié)1地址的概念 程序中每一個變量在

2、編譯或運(yùn)行時系統(tǒng)都為其分配內(nèi)存單元,每一個內(nèi)存單元(字節(jié))都有一個相應(yīng)的編號,這個編號稱為該內(nèi)存單元的“地址”,而內(nèi)存單元中存入的內(nèi)容則是該變量的值。內(nèi)存用戶數(shù)據(jù)區(qū)36920002000200220043010變量 i變量 j變量 k變量 i_pt10.1 指針的概念int i=3, j=6, k=9;int *i_pt;i_pt=&i;指針是c語言中比較靈活的數(shù)據(jù)結(jié)構(gòu),靈活地運(yùn)用指針可以: (1) 有效地表示復(fù)雜的數(shù)據(jù)結(jié)構(gòu). (2) 動態(tài)分配內(nèi)存. (3) 更方便地使用字符串和數(shù)組. (4) 直接處理內(nèi)存地址.2對內(nèi)存單元的存取有兩種方式 (1)直接訪問 按變量地址存取變量的值。 (2)間接

3、訪問 將變量i的地址存放在另一個內(nèi)存單元j中,要訪問i, 則先按j的地址取出i的地址,再按i的地址取出i的值。直接訪問和間接訪問示意圖3i20003ii_pt 20003指針變量的概念 一個變量的地址稱為該變量的“指針”。 如果有一個變量專門用來存放另一個變量的地址(即指針),則它稱為“指針變量”。指針變量的值是指針。一、指針變量的定義 指針變量必須在使用之前先定義,它是用來存放地址的。必須將它定義為“指針類型”。 定義的一般形式為: 類型標(biāo)識符 *標(biāo)識符注:(1) 標(biāo)識符前面的“*”,表示該變量為指針變量。但指針變 量名是pt_1、pt_2、pt_3,而不是*pt_1、*pt_2、*pt_3

4、。(2) * 表示指向, 故*pt_1,*pt_2, *pt_3表示指針變量 pt_1, pt_2, pt_3所指向的變量。(3) 一個指針變量只能指向同一個類型的變量。10.2 變量的指針和指向變量的指針變量例: int *pt_1 ; char *pt_2 ; float *pt_3 ;二、指針變量的引用 有兩個有關(guān)的運(yùn)算符 (1) & 取地址運(yùn)算符 (2) * 指針運(yùn)算符(或稱“間接訪問”運(yùn)算符)。例: int a, *pt; &a為變量a的地址, *pt為指針變量pt所指向的變量. 則: &*pt=&a=pt 則: *&a=*pt=a 則: (*pt)+相當(dāng)于a+apt *pt若: p

5、t=&ab=(*pt)+;c=*pt+;b與c值是否相等? void main( ) int a,b,*p1,*p2; a=100; b=10; p1=&a; p2=&b; printf(%d,%dn,a,b); printf(%d,%dn,*p1,*p2); 例:1100,10100,10運(yùn)行結(jié)果*p1ap1bp2&b*p210010&a例2: void main( ) int a,b,*p1,*p2,*p; scanf(%d %d,&a,&b); p1=&a; p2=&b; if(ab) p=p1;p1=p2;p2=p; printf(%d,%dn,a,b); printf(%d,%dn,

6、*p1,*p2); 輸入:5 9*p1ap1bp2&b*p2 5 9&ap&b&a輸出: 5,99,5void main( )int a,b,*p1,*p2,t; scanf(%d %d,&a,&b); p1=&a; p2=&b; if(ab) t=*p1;*p1=*p2;*p2=t; printf(%d,%dn,a,b); &a*p1*p2三、指針變量作為函數(shù)參數(shù)。 例1:輸入a和b兩個整數(shù),按先大后小的順序輸出a和b。 void main ( ) int a,b; int *point_1,*point_2; scanf(%d%d,&a,&b); point_1=&a;point_2=&b

7、; if(ab) swap(point_1,point_2); printf(n%d,%dn,a,b); printf(n%d,%dn,*point_1,*point_2); 輸入數(shù)據(jù): 4 8輸出結(jié)果: 8 , 4 8 , 4void swap(int *p1,int *p2)int p; p=*p1;*p1=*p2; *p2=p;abpoint_1point_2&a&b48p1p284point_1point_2&a&bvoid swap(int *p1,int *p2)int *p; p=p1;p1=p2; p2=p;void main ( ) int a,b; int *point_1

8、,*point_2; scanf(%d%d,&a,&b); point_1=&a;point_2=&b; if(ab) swap(point_1,point_2); printf(n%d,%dn,a,b); printf(n%d,%dn,*point_1,*point_2); a b point_1point_2輸入數(shù)據(jù): 4 84 8p1p2 point_1point_2輸出結(jié)果:4,84,8注:1.不能企圖通過改變形參地址而使實(shí)參地址也改變, 也就是說調(diào)用函數(shù)不能改變實(shí)參指針變量的值。 2.調(diào)用函數(shù)可以改變實(shí)參指針變量所指變量的值。ap1bp2cp3例2:輸入a,b,c 三個整數(shù),按大小順

9、序輸出。void swap(int *pt1,int *pt2)int *pt1,*pt2;int p; p=*pt1; *pt1=*pt2; *pt2=p; void exchange(q1,q2,q3)int *q1,*q2,*q3; if(*q1*q2) swap(q1,q2); if(*q1*q3) swap(q1,q3); if(*q2*q3) swap(q2,q3); void main() int a,b,c,*p1,*p2,*p3; scanf(%d%d%d,&a,&b,&c); p1=&a;p2=&b;p3=&c; exchange(p1,p2,p3); printf(n%d

10、,%d,%dn,a,b,c); 5103&b&a&cq1q2q3pt1pt210 5q1q2q3 10.3 數(shù)組的指針和指向數(shù)組的指針變量一、指向數(shù)組元素的指針變量 與前面介紹的指向變量的指針變量相同。若: int a10,*p; p=&a0;則: (1) p+i和a+i就是ai的地址,或者說它們指向數(shù)組的第i個 元素。 (2) *(p+i)或*(a+i)是p+i或a+i所指向的數(shù)組元素,即ai。 (3) 指向數(shù)組的指針變量可以帶下標(biāo),如pi與*(p+i)等價。 數(shù)組的指針是指數(shù)組的起始地址,數(shù)組元素的指針是數(shù)組元素 的地址。指針法:main( )int *p,i,a10; p=&a0; fo

11、r(i=0;i10;i+) scanf(%d, p+); printf(n); p=&a0; for (i=0;i10;i+) printf(%3d,*p+); pa0a1a2a9例1:輸出數(shù)組全部元素。(設(shè)a數(shù)組,整型,10個元素)3p5pp-4p12pp*(p+i);p+i); p=a; p=a;(2)下標(biāo)法main ( )int a10; int i; for (i=0;i10;i+) scanf(%d,&ai); printf(n); for (i=0;i10;i+) printf(%3d,ai); (3)地址法main ( )int a10; int i; for (i=0;i10;

12、i+) scanf(%d,a+i); printf(n); for (i=0;i10;i+) printf(%3d,*(a+i); 在使用指針變量時應(yīng)注意的幾個問題: 1. 數(shù)組名是數(shù)組的首地址,因此 p=&a0 與 p=a 等價。 2指針變量可以實(shí)現(xiàn)使本身的值改變,數(shù)組名不可以。 例: p+正確 a+不正確 3要注意指針變量的當(dāng)前值。 4指針變量可以指到數(shù)組后的內(nèi)存單元。 5注意指針變量的運(yùn)算,若先使p指向數(shù)組a(即p=a),則 (1) p+ (或p+=1) 指向下一個元素。 (2) *p+等價于*(p+)先得到p指向的變量的值,p再 加1。 (3) *(p+)與*(+p)作用不同,前者先取

13、*p,后使p加 1;后者相反。 (4) (*p)+表示p所指向的元素值加1。 (5) 若p當(dāng)前指向a數(shù)組第i個元素,則: *(p-)相當(dāng)于ai-,先取p值作*運(yùn)算,再使p自減; *(+p)相當(dāng)于a+i,先使p自加,再作*運(yùn)算; *(-p)相當(dāng)于a-i,先使p自減,再作*運(yùn)算。二、數(shù)組名作函數(shù)參數(shù) 用數(shù)組名作參數(shù),在調(diào)用函數(shù)時實(shí)際上是把數(shù)組的首地址傳給形參,這樣實(shí)參與形參共同指向同一段內(nèi)存。因而調(diào)用過程中,如形參數(shù)組元素值發(fā)生變化也就使實(shí)參數(shù)組的元素發(fā)生了變化,但這種變化并不是從形參傳回實(shí)參的,而是由于形參與實(shí)參共享同一段內(nèi)存而造成的。 例2:將數(shù)組a中n個整數(shù)按相反順序存放。245760119

14、7337911067542imjvoid inv(int x,int n)int i,j,t,m=n/2; for (i=0;im;i+) j=n-1- i; t=xi; xi=xj; xj=t; void main ( )int i ,a10=3,7,9,11,0,6,7,5,4,2; printf(The original array:n); for (i=0;i10;i+); printf(%3d,ai); printf(n); inv(a,10); printf(The array has been inverted:n); for (i=0;i10;i+) printf(%3d,ai

15、); printf(n); void inv(int *x, int n) int t,*i,*j; j=x+n-1; for (i=x;ij;i+,j-) t=*i; *i=*j; *j=t; a0a1a2a3a937911067542a4a5a6a7a8a 數(shù)組i, xp=x+mj若將形參改為指針,則inv函數(shù)可改為:27911067543ji24911067573ij 如果有一個實(shí)參數(shù)組,想在函數(shù)中改變此數(shù)組的元素的值,實(shí)參與形參的對應(yīng)關(guān)系有以下幾類情況: (1) 形參和實(shí)參都用數(shù)組名 傳遞的是實(shí)參數(shù)組首地址,形參與實(shí)參共用同一段內(nèi)存單元。 (2) 實(shí)參用數(shù)組名,形參用指針變量 通過指針

16、變量值的改變可以指向?qū)崊?shù)組的任一元素。 (3) 實(shí)參和形參都用指針變量 先使實(shí)參指針變量指向數(shù)組的首地址,然后將實(shí)參的值 傳給形參,通過指針變量值的改變可以使其指向數(shù)組的每個元素。 (4) 實(shí)參為指針變量,形參為數(shù)組名 設(shè)p為指針變量,令p=&a0,p為實(shí)參,對應(yīng)的形參x為數(shù)組名,則函數(shù)調(diào)用時將 p的值傳給形參數(shù)組名x,也就是使其取得 a數(shù)組的首地址,使 x數(shù)組和 a數(shù)組共用同一段內(nèi)存單元.例3:用選擇法對10個整數(shù)排序。void sort(int x ,int n)int i,j,k,t; for (i=0;in-1;i+) k=i; for (j=i+1;jxk) k=j; if (k!

17、=i) t=xi;xi=xk;xk=t; void main ( ) int *p,i,a10; p=a; for (i=0;i10;i+) scanf(%d,p+); p=a; sort(p,10); for (p=a,i=0;i10;i+) printf(%d,*p+); (1) 實(shí)參用指針變量,形參用數(shù)組名(2) 實(shí)參用數(shù)組名,形參用指針變量void sort(int *x,int n)int i,j,k,t; for (i=0;in-1;i+) k=i; for (j=i+1;j*(x+k) k=j; if (k!=i) t=*(x+i); *(x+i)=*(x+k); *(x+k)=

18、t; void main ( ) int i,a10; for (i=0;i10;i+) scanf(%d,&ai); sort(a,10); for (i=0;i10;i+) printf(%3d,ai); (3) 實(shí)參用指針變量,形參也用指針變量void main ( ) int *p,i,a10; p=a; for (i=0;i10;i+) scanf(%d,p+); p=a; sort(p,10); for (p=a,i=0;i10;i+) printf(%d,*p+); void sort(int *x,int n)int i,j,k,t; for (i=0;in-1;i+) k=i

19、; for (j=i+1;j*(x+k) k=j; if (k!=i) t=*(x+i); *(x+i)=*(x+k); *(x+k)=t; 例4:從10個數(shù)中找出其中最大值和最小值。int max,min;void main ( )int i,number10; void max_min_value( ); printf(enter 10 datan); for (i=0;i10;i+) scanf(%d,&numberi); max_min_value(number,10); printf(n max=%d,min=%d,max,min); 方法1:外部變量void max_min_val

20、ue(int array , int n) int *p,*array_end; array_end=array+n; max=min=*array; for (p=array+1;pmax) max=*p; else if (*pmin) min=*p; number 2 32 -12 4 56 7 28 -67 39 41arrayarray_endp22maxmin32p-12pp 56ppp-67ppp*array void main( ) int i,number10; int amax,amin,*amax_p,*amin_p; void max_min_value( ) ; pr

21、intf(enter 10 datan); for (i=0;i10;i+) scanf(%d,&numberi); amax=amin=number0; amax_p=&amax;amin_p=&amin; max_min_value(number,10,amax_p,amin_p); printf(max=%d,min=%dn,*amax_p,*amin_p); 方法2:amaxaminamax_pamin_p12 -23 5 78 27 6 9 36 3 41212 void max_min_value(int array,int n,int *a1,int *b1) int i; fo

22、r (i=1;i*a1) *a1=arrayi; else if (arrayi*b1) *b1=arrayi; amaxaminamax_pamin_p12 -23 5 78 27 6 9 36 3 41212max_min_value(number,10,amax_p,amin_p);array10na1b1三、指向多維數(shù)組的指針和指針變量int a34= 6,9,0,16,8,-1,2,7,3,48,-5,12;(1) a+i=ai=*(a+i) a=a0=*(a+0)=*a=&a00aa+0a+1a+2a0a1a2 (2) ai+j是aij的地址 *(a+i)+j也是aij的地址(3)

23、 &ai或a+i指向行,*(a+i)或ai指向列(4) aij的值可以表示為: *(ai+j) *(*(a+i)+j) aij690168-127348-5121多維數(shù)組的地址對于一維數(shù)組ai=*(a+i)=*(p+i)=pi#define FORMAT %d,%dnvoid main ( )static int a34=1,3,5,7,9,11,13,15,17,19,21,23; printf (FORMAT,a,*a); printf (FORMAT,a0,*(a+0); printf (FORMAT,&a0,&a00); printf (FORMAT,a1,a+1); printf (

24、FORMAT,&a10,*(a+1)+0); printf (FORMAT,a2,*(a+2); printf (FORMAT,&a2,a+2); printf (FORMAT,a10,*(*(a+1)+0);運(yùn)行結(jié)果:158,158158,158158,158166,166166,166174,174174,1749, 9 2多維數(shù)組的指針可以用指針變量指向多維數(shù)組及其元素 (1) 指向數(shù)組元素的指針變量。例5:用指針變量輸出數(shù)組元素的值。 void main( ) static int a23=2,3,6,7,8,5; int i,j,*p; p=&a00; /* p=a0; 或 p=*a

25、;*/ for(i=0;i2;i+) for(j=0;j3;j+,p+) printf(%3d,*p); printf(n); 2 3 6 7 8 5aa0a1p23 2 3 6pp6p7p8p5p例6:用指針變量輸出數(shù)組元素aij的值。 void main( ) static int a23=2,3,6,7,8,5; int i,j,*p; p=a; scanf(%d %d,&i,&j); printf(%3d,*(p+i*3)+j); void main() static int a45=1,4,2,3,7,6,9,10,8,-1, -2,-6,-4,4,2,7,6,9,11,14; in

26、t i,j; for(i=0;i4;i+) for(j=0;j5;j+) printf(%4d,aij); printf(n); sort(a,4*5); printf(=n); for(i=0;i4;i+) for(j=0;j5;j+) printf(%4d,aij); printf(n); 例7: 將一個二維數(shù)組a45進(jìn)行按行全排序 void sort(int *p,int n) int i,j,t; for(i=0;in-1;i+) for(j=i+1;j=n-1;j+) if(*(p+i)*(p+j) t=*(p+i); *(p+i)=*(p+j); *(p+j)=t; a00a01a

27、02a03a04a10a11a12a13a14 . . .a32a33a34.sort(a,4*5);p(2) 指向由m個整數(shù)組成的一維數(shù)組的指針變量。例7:輸出二維數(shù)組任一行任一列的元素的值。 void main ( )static int a34=1,3,5,7,9,11,13,15,17,19,21,23; int (*p)4,i,j; p=a; scanf(i=%d,j=%d,&i,&j); printf(a%d,%d=%dn,i,j,*(*(p+i)+j); 說明: (1) int (*p)4 表示p指向一個包含4個元素的一維數(shù)組. (2) p+1使指針移動2*4個字節(jié), *(p+1

28、)使指針的指向由橫 向轉(zhuǎn)向縱向. (3) *(p+i)+j使指針移動2*4*i+2*j.(3) 多維數(shù)組的指針作函數(shù)參數(shù)。 例9: 求二維數(shù)組a45每列最大值 void colum_max(a,b) int (*a)5,*b; int i,j; for(j=0;j5;j+) for(i=1;i4;i+) if (*(b+j)*(*(a+i)+j) *(b+j)=*(*(a+i)+j); int a45,b5;colum_max(a,b);a+0a+1a+2a+3b 2 12 3 27 -4 3 7 33 2 5 1 6 12 3 15 4 8 10 9 14 2 12 3 27 -4.34123327515 void main( ) int a45,b5; int i,j; for(i=0

溫馨提示

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

評論

0/150

提交評論