




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、第十章指 針本章主要內容指針和地址的概念指針變量指向數組/字符串時的操作指針變量做函數參數幾種指針類型返回指針值的函數重點、難點如何理解指針和地址的概念靈活使用指向一位數組/字符串的指針靈活使用指針變量/數組名做函數參數掌握幾種指針的概念與函數一章的例題結合,掌握參數單向傳遞的實質10.1 指針的概念10.2 變量的指針和指向變量的指針變量10.3 數組的指針和指向數組的指針變量10.4 字符串的指針和指向字符串的指針變量10.5 函數的指針和指向函數的指針變量10.6 返回指針的函數10.7 指針數組和指向指針的指針10.8 有關指針的數據類型和指針運算的小結1地址的概念 程序中每一個變量在
2、編譯或運行時系統都為其分配內存單元,每一個內存單元(字節)都有一個相應的編號,這個編號稱為該內存單元的“地址”,而內存單元中存入的內容則是該變量的值。內存用戶數據區36920002000200220043010變量 i變量 j變量 k變量 i_pt10.1 指針的概念int i=3, j=6, k=9;int *i_pt;i_pt=&i;指針是c語言中比較靈活的數據結構,靈活地運用指針可以: (1) 有效地表示復雜的數據結構. (2) 動態分配內存. (3) 更方便地使用字符串和數組. (4) 直接處理內存地址.2對內存單元的存取有兩種方式 (1)直接訪問 按變量地址存取變量的值。 (2)間接
3、訪問 將變量i的地址存放在另一個內存單元j中,要訪問i, 則先按j的地址取出i的地址,再按i的地址取出i的值。直接訪問和間接訪問示意圖3i20003ii_pt 20003指針變量的概念 一個變量的地址稱為該變量的“指針”。 如果有一個變量專門用來存放另一個變量的地址(即指針),則它稱為“指針變量”。指針變量的值是指針。一、指針變量的定義 指針變量必須在使用之前先定義,它是用來存放地址的。必須將它定義為“指針類型”。 定義的一般形式為: 類型標識符 *標識符注:(1) 標識符前面的“*”,表示該變量為指針變量。但指針變 量名是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 ;二、指針變量的引用 有兩個有關的運算符 (1) & 取地址運算符 (2) * 指針運算符(或稱“間接訪問”運算符)。例: int a, *pt; &a為變量a的地址, *pt為指針變量pt所指向的變量. 則: &*pt=&a=pt 則: *&a=*pt=a 則: (*pt)+相當于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運行結果*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三、指針變量作為函數參數。 例1:輸入a和b兩個整數,按先大后小的順序輸出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); 輸入數據: 4 8輸出結果: 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輸入數據: 4 84 8p1p2 point_1point_2輸出結果:4,84,8注:1.不能企圖通過改變形參地址而使實參地址也改變, 也就是說調用函數不能改變實參指針變量的值。 2.調用函數可以改變實參指針變量所指變量的值。ap1bp2cp3例2:輸入a,b,c 三個整數,按大小順
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 數組的指針和指向數組的指針變量一、指向數組元素的指針變量 與前面介紹的指向變量的指針變量相同。若: int a10,*p; p=&a0;則: (1) p+i和a+i就是ai的地址,或者說它們指向數組的第i個 元素。 (2) *(p+i)或*(a+i)是p+i或a+i所指向的數組元素,即ai。 (3) 指向數組的指針變量可以帶下標,如pi與*(p+i)等價。 數組的指針是指數組的起始地址,數組元素的指針是數組元素 的地址。指針法: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:輸出數組全部元素。(設a數組,整型,10個元素)3p5pp-4p12pp*(p+i);p+i); p=a; p=a;(2)下標法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); 在使用指針變量時應注意的幾個問題: 1. 數組名是數組的首地址,因此 p=&a0 與 p=a 等價。 2指針變量可以實現使本身的值改變,數組名不可以。 例: p+正確 a+不正確 3要注意指針變量的當前值。 4指針變量可以指到數組后的內存單元。 5注意指針變量的運算,若先使p指向數組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當前指向a數組第i個元素,則: *(p-)相當于ai-,先取p值作*運算,再使p自減; *(+p)相當于a+i,先使p自加,再作*運算; *(-p)相當于a-i,先使p自減,再作*運算。二、數組名作函數參數 用數組名作參數,在調用函數時實際上是把數組的首地址傳給形參,這樣實參與形參共同指向同一段內存。因而調用過程中,如形參數組元素值發生變化也就使實參數組的元素發生了變化,但這種變化并不是從形參傳回實參的,而是由于形參與實參共享同一段內存而造成的。 例2:將數組a中n個整數按相反順序存放。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 數組i, xp=x+mj若將形參改為指針,則inv函數可改為:27911067543ji24911067573ij 如果有一個實參數組,想在函數中改變此數組的元素的值,實參與形參的對應關系有以下幾類情況: (1) 形參和實參都用數組名 傳遞的是實參數組首地址,形參與實參共用同一段內存單元。 (2) 實參用數組名,形參用指針變量 通過指針
16、變量值的改變可以指向實參數組的任一元素。 (3) 實參和形參都用指針變量 先使實參指針變量指向數組的首地址,然后將實參的值 傳給形參,通過指針變量值的改變可以使其指向數組的每個元素。 (4) 實參為指針變量,形參為數組名 設p為指針變量,令p=&a0,p為實參,對應的形參x為數組名,則函數調用時將 p的值傳給形參數組名x,也就是使其取得 a數組的首地址,使 x數組和 a數組共用同一段內存單元.例3:用選擇法對10個整數排序。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) 實參用指針變量,形參用數組名(2) 實參用數組名,形參用指針變量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) 實參用指針變量,形參也用指針變量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個數中找出其中最大值和最小值。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三、指向多維數組的指針和指針變量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多維數組的地址對于一維數組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);運行結果:158,158158,158158,158166,166166,166174,174174,1749, 9 2多維數組的指針可以用指針變量指向多維數組及其元素 (1) 指向數組元素的指針變量。例5:用指針變量輸出數組元素的值。 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:用指針變量輸出數組元素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: 將一個二維數組a45進行按行全排序 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個整數組成的一維數組的指針變量。例7:輸出二維數組任一行任一列的元素的值。 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個元素的一維數組. (2) p+1使指針移動2*4個字節, *(p+1
28、)使指針的指向由橫 向轉向縱向. (3) *(p+i)+j使指針移動2*4*i+2*j.(3) 多維數組的指針作函數參數。 例9: 求二維數組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. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 公共交通標線施工與維護服務合同
- 汽車抵押貸款合同范本:全程貸款跟蹤
- 財務合同信息化安全評估與整改合同
- 基礎工程三校合編教學課件
- 課件的制作與應用
- 小學生學習方法指導課件
- 小學生學習委員競選課件
- 診所勞動合同協議書
- 床墊購銷合同協議書范本
- 基層衛生適宜技術課件
- 專利代理師考試題庫含答案2024
- 贛州城投招聘試題及答案
- 2024北京海淀區四年級(下)期末語文試題及答案
- 2025屆海南中考地理高頻考點模擬檢測試題(一模)含解析
- 輸血流程培訓試題
- 企業安全生產知識題庫
- 2025-2030方塊地毯行業市場現狀供需分析及重點企業投資評估規劃分析研究報告
- 鋼筋混凝土蓄水池施工方案
- 四川省樂山市市中區嘉州學校2024-2025學年數學五年級第二學期期末監測模擬試題含答案
- 管廊安全培訓課件圖片
- 《新能源材料概論》 課件 第4章 力電轉換新能源材料
評論
0/150
提交評論