最全的C語言指針詳解_第1頁
最全的C語言指針詳解_第2頁
最全的C語言指針詳解_第3頁
最全的C語言指針詳解_第4頁
最全的C語言指針詳解_第5頁
已閱讀5頁,還剩42頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、第6章 指針,6.1 指針定義與使用 6.2 指針與函數(shù) 6.3 指針與數(shù)組 6.4 指針與字符串 6.5 指針數(shù)組與多級指針 6.6 指針與動態(tài)內(nèi)存分配 6.7 指針的深層應(yīng)用,6.1 指針的引出,一. 地址與指針 1. 地址與取地址運(yùn)算 C程序中的變量在內(nèi)存中占有一個可標(biāo)識的存儲區(qū), 每一個存儲區(qū)是由若干個字節(jié)組成, 每一個字節(jié)都有 自己的地址, 而一個存儲區(qū)的 地址是指該存儲區(qū)中 第一個字節(jié)的地址,C語言允許在程序中使用變量的地址 ( 通過地址運(yùn)算符 數(shù)組變量 a 的地址 - 數(shù)組名 a,2. 指針與指針變量 (1) 變量的訪問方式 直接訪問 : 通過變量名或地址訪問變量的存儲區(qū) 例 :

2、 scanf ( “%d” , , 間接訪問 : 將一個變量的地址存放在另一個變量中. 如將變量 x 的地址存放在 變量p 中, 訪問x 時(shí)先找到p, 再由p 中存放的地址找到 x,2012,1010,1010,(2) 指針: 一個變量的指針就是該變量的地址(指針就是地址) (3) 指針變量: 存放變量地址的變量, 它用來指向另一個變量,二、 指針變量的定義 1. 格式 : 數(shù)據(jù)類型 * 指針變量名 ; 例 int *p1 ; char *p2 ;,2. 說明 : (1) 在變量定義時(shí), * 號表示該變量是指針變量 ( 注意: 指針變量是p1 , p2 , 不是*p1 , *p2 ) (2)

3、定義指針變量后, 系統(tǒng)為其分配存儲空間, 用以存放 其他變量的地址, 但在對指針變量賦值前, 它并沒有 確定的值, 也不指向一個確定的變量,例: int x , *p ; x = 5 ;,2012,1010,5,1234,注: 指針變量p的值是隨機(jī)值, 此時(shí)p 和 x 并無關(guān)聯(lián),(3) 使指針變量指向一個確定的變量必須進(jìn)行賦值,int x , *p ; x = 5 ; p = ,2012,1010,5,1010,三、 指針變量的引用 1. 指針運(yùn)算符 * (1) p與*p不同, p是指針變量, p的值是p所指向的變量的地址 *p 是p 所指向的變量 , *p的值是p所指向的變量的值,*p 的值

4、為 5(*p 表示 x) , 而p 的值為 1010,(2) 引用指針變量時(shí)的 * 與 定義指針變量時(shí)的 * 不同 定義變量時(shí)的 * 只是表示其后的變量是指針變量,int a , *p ; p = ,2012,1010,5,1010,12,讓p指向a,對a 重新賦值 等價(jià)于 a=12,即,p 的值為a 的地址, *p 的值為2 p 的值不變 , *p 的值為 3,(2) c = *p+ ;,c = *(p+) ; c = *p ; p+ ; 執(zhí)行后 c 的值為 3 , *p 的值為 5,(3) d = *+p ;,d = *(+p) ; +p ; d = *p ; 執(zhí)行后 d 的值為 3 ,

5、*p 的值為 3,2012,1010,1010,(1) p = ,( 等價(jià)于 a+ ; ),1012,3,3,1014,3,例6. 2 #include void main( ) int *p1 , *p2 , *p , a , b ; scanf(“%d%d”, , temp = x ; x = y; y = temp; void main( ) int a , b ; scanf(“%d%d”, ,5,說明: 該程序不能實(shí)現(xiàn)a 和b 的交換因?yàn)閷?shí)參a , b 對形參 x , y 是“值傳遞”, x 和y 的變 化不影響a 和b 所以輸出為: a=5, b=9,9,main,swap,5,5

6、,9,9,5,6.2 指針與函數(shù),例 6. 3 #include void swap1(int *p1 , int *p2) int temp; temp = *p1 ; *p1 = *p2; *p2 = temp; void main( ) int a , b , *pt1 , *pt2 ; scanf(“%d%d”, , *temp = *p1 ; *p1 = *p2; *p2 = *temp; ,說明: 這種方法可能會破壞系統(tǒng)的正常 工作狀態(tài),因?yàn)閠emp是一個指針變量 但是在函數(shù)中并沒有給temp一個確定 的地址,這樣它所指向的內(nèi)存單元是 不可預(yù)見的,而對*temp的賦值可能 帶來危害

7、,main, p = p1 ; p1 = p2; p2 = p; , 例: int * fun ( int a , int b ) 函數(shù)體 ; 說明: 定義一個返回指針值的函數(shù)與以前定義函數(shù)格式 基本類似, 只是在函數(shù)名前加 * , 它表明該函數(shù)返回一個 指針值 , 而這個指針值是指向一個 int 型數(shù)據(jù),二、函數(shù)返回 指針,例: #include #include #define SIZE 100 char bufSIZE ; char *p=buf ; char *alloc( int n) char *begin ; if ( p+n = buf+SIZE ) begin=p ; p=p

8、+n; return(begin); else return(NULL); ,void main( ) char *p1,*p2 ; int i ; p1=alloc(10); strcpy(p1,”123456789”); p2=alloc(5); strcpy(p2,”abcd”); printf(“buf=%pn”, buf); printf(“p1=%pn”, p1); printf(“p2=%pn”, p2); puts(p1); puts(p2); for( i=0 ; i15 ; i+) printf(“%c”, bufi); ,buf0 buf1 : : buf9 buf10

9、: buf14 buf15 : : buf99,buf+10,buf,buf,buf+10,1 2 : 9 0,a : 0,10,buf+15,buf+10,5,函數(shù)的指針: 函數(shù)的入口地址 在程序執(zhí)行過程中調(diào)用函數(shù)時(shí), 計(jì)算機(jī)會轉(zhuǎn)去執(zhí)行 函數(shù)體內(nèi)的語句, 因此計(jì)算機(jī)必須知道函數(shù)在什么地方。 實(shí)際上函數(shù)在內(nèi)存中也要占據(jù)一片存儲單元, 這片存儲 單元一個起始地址, 我們稱其為函數(shù)的入口地址, 即函數(shù)的指針, 這個函數(shù)的入口地址是用函數(shù)名來表示。 因此我們可以定義一個指針變量, 讓它的值等于 函數(shù)的入口地址, 然后可以通過這個指針變量來調(diào)用 函數(shù), 該指針變量稱為指向函數(shù)的指針變量,三、指向函數(shù)的

10、 指針,指向函數(shù)的指針變量 1. 定義格式: 數(shù)據(jù)類型 ( *指針變量名) ( 形參表列) ; int ( *pt ) ( int arr , int n ) ; 說明: 數(shù)據(jù)類型: 指針變量所指向的函數(shù)的返回值類型 形參表列: 即指針變量所指向的函數(shù)的形參表列 格式中的小括號不能省略,2. 應(yīng)用 (1) 讓指針變量指向函數(shù) pt = add ; 因?yàn)楹瘮?shù)名為函數(shù)的入口地址, 所以直接將函數(shù)名 賦給指針變量即可 (2) 使用指針變量調(diào)用函數(shù) 格式 : (*指針變量名) ( 實(shí)參表列),例 求一維數(shù)組中全部元素的和 #include int add( int b , int n); void m

11、ain( ) int a6= 1, 3, 5, 7, 9, 11, total ; int (*pt) ( int b , int n ) ; pt = add ; total = (*pt) ( a , 6 ) ; printf( “total = %d n” ,total ) ; int add( int b , int n ) int i , sum = 0 ; for ( i = 0 ; in ; i+ ) sum = sum+bi; return(sum); ,定義指向函數(shù) 的指針變量,令指針變量pt 指向函數(shù)add,通過pt 調(diào)用 函數(shù)add,6.3 指針與數(shù)組,一. 一維數(shù)組與指

12、針 1. 一維數(shù)組及元素的地址表示 int a5 = 1, 2, 3, 4, 5 ; 數(shù)組的地址 : a,2. 用指針變量引用數(shù)組元素 (1) 定義指針變量 int *p , a5 = 1, 2, 3, 4, 5 ; p = a ;,(2) 引用數(shù)組元素,注意 : 指針變量也可以加下標(biāo) pk 等價(jià)于 ak 分別用三種方法輸出數(shù)組元素, 其效率不同, 下標(biāo)法與地址法的效率相同, 指針法的效率較快 用指針變量訪問數(shù)組元素時(shí)要注意下標(biāo)是否越界,例: 將數(shù)組a中全部元素加1, 再輸出a #include void main( ) int a5 = 1, 3, 5 ,7 ,9 , *p , j ; fo

13、r ( p=a ; pa+5 ; p+ ) printf(“%3d”, *p); printf(“n”) ; for ( j=0 ; j5 ; j+) aj=aj+1 ; for ( j=0 ; j5 ; j+) printf(“%3d”, *(p+j) ) ; printf(“n”) ; ,p=a ;,a a+1 a+2 a+3 a+4,2,4,6,8,10,可以用p+ , 但不能用a+ 因?yàn)閍 代表數(shù)組的起始地址 它是地址常量, 不能改變 而p 是一個指針變量,使用指針變量時(shí)要注意它的當(dāng)前值,3. 指向數(shù)組的指針變量作函數(shù)參數(shù),例6. 7 實(shí)參和形參都用數(shù)組名 #include void

14、inv1( int x , int n ) int temp, i , j , m=(n-1)/2; for( i=0 ; i=m ; i+) j=n-1-i ; temp=xi ; xi=xj ; xj=temp ; void main( ) int i , a6= 1, 3, 4, 6, 7, 9 ; inv1(a , 6 ); for( i=0; i6; i+ ) printf(“%3d”, ai ); printf(“n”); ,a0 a1 a2 a3 a4 a5,x0 x1 x2 x3 x4 x5,main,inv1,例6. 7 實(shí)參用數(shù)組名, 形參用指針變量 #include vo

15、id inv2(int *x , int n) int temp, m=(n-1)/2; int *p , *i , *j ; i=x ; j=x+n-1; p=x+m; for( ; i=p ; i+, j- ) temp=*i ; *i=*j ; *j=temp ; void main( ) int i , a6= 1, 3, 4, 6, 7, 9 ; inv2(a , 6 ); for( i=0; i6; i+ ) printf(“%3d”, ai ); printf(“n”); ,a0 a1 a2 a3 a4 a5,inv2,9,1,7,3,6,4,1,a+1,a+4,a+2,a+3,

16、3,4,i和j的指向會變化, p的指向保持不變,例6.7 實(shí)參和形參都用指針變量 #include void inv3(int *x , int n); void main( ) int *p , a6=1, 3, 4, 6, 7, 9; p = a ; inv3( p , 6 ); for( p=a ; pa+6 ; p+ ) printf(“%3d”, *p ); printf(“n”); void inv3(int *x , int n) int temp, m=(n-1)/2; int *p , *i , *j ; i=x ; j=x+n-1; p=x+m; for( ; i=p ;

17、i+, j- ) temp=*i ; *i=*j ; *j=temp ; ,例6.7 實(shí)參用指針變量, 形參用數(shù)組名 #include void inv4(int x , int n); void main( ) int *p, a6=1, 3, 4, 6, 7, 9; p = a ; inv4( p , 6 ) ; for( p=a ; pa+6 ; p+ ) printf(“%3d”, *p ); printf(“n”); void inv4(int x , int n) int temp, i , j , m=(n-1)/2; for( i=0 ; i=m ; i+) j=n-1-i ;

18、 temp=xi ; xi=xj ; xj=temp; ,例6.8 求數(shù)組中最大和最小元素 #include int max , min ; void m1(int arr , int n) int *p , *end ; end=arr+n ; max=min=*arr ; for(p=arr+1 ; pmax ) max=*p ; else if( *pmin ) min=*p ; void main( ) int i , a6; for(i=0 ; i6 ; i+) scanf(“%d”, ,a0 a1 a2 a3 a4 a5,4 7 1 9 0 5,4,4,7,9,1,0,二、二維數(shù)組

19、與指針,二維數(shù)組的定義,對于二維數(shù)組a,首先可以把它先理解為一個一維數(shù)組, 它有3個元素: a0, a1, a2,而每一個元素又是一個一維數(shù)組, 包含4個元素 如a0是一維數(shù)組, 它有4個元素: a00, a01, a02, a03,a34,a0, a1, a2只是一種地址表示方法, 并不真的二維數(shù)組元素,可以看作是第二重一維數(shù)組的名字。,二維數(shù)組的初始化,(1) 可以分行給二維數(shù)組賦初值,int a34=1,2,3,4,5,6,7,8,9,10,11,12;,1 2 3 4,5 6 7 8,910 11 12,(2) 可以將所有數(shù)據(jù)寫在一個花括號中,按順序?qū)Ω髟刭x初值,int a34=1,

20、2,3,4,5,6,7,8,9,10,11,12;,二維數(shù)組的初始化,(3) 可以對部分元素賦初值,其余元素補(bǔ)0,int a34=1,5,9;,int a34=1,0,6,0,0,11;,(4) 如果對全部數(shù)據(jù)都賦初值,則定義時(shí)第一維的長度可以不指定,但第二維的長度不能省,int a 4=1,2,3,4,5,6,7,8,9,10,11,12;,二維數(shù)組的初始化,如果只對部分?jǐn)?shù)據(jù)賦初值,第一維的長度也可以不指定,但元素必須分行賦初值,int a 4=0,0,3,0,10;,二維數(shù)組的地址,二維數(shù)組名a表示二維數(shù)組的首地址, 也是第0個元素(a0)的地址,a+1代表第1個元素(a1)的地址 a+1

21、 p=,#include void main( ) int a34=1,2,3,4,5,6,7,8,9,10,11,12; int *p; ,for( p=a0; pa0+12; p+) printf(“%d ”, *p); printf(“n ”);,指向二維數(shù)組元素的指針,int a34; int *p; p=a; 合法嗎?,int x=36, *q,*p; q=,2010,2026,p是二級指針, 它指向一個整型指針變量q, 而q指向一個整型變量,a是一種地址表示方法, a實(shí)際指向了第一重一維數(shù)組元素a0,而 a0是第二重一維數(shù)組,非法!,指向二維數(shù)組元素的指針,定義格式:類型名 (*指

22、針變量名)數(shù)組長度;,int a34; int (*p)4; p=a;,p指向一個包含有4個整型數(shù)據(jù)的一維數(shù)組,合法!,雖然在定義p的時(shí)候只用了一個*,但p實(shí)際上是一個二級指針變量,指向二維數(shù)組元素的指針,例2:輸出二維數(shù)組中的元素,#include void main( ) int a34=1,2,3,4,5,6,7,8,9,10,11,12; int (*p)4, i, j; p=a; for( i=0; i3; i+) for( j=0; j4; j+) printf(“%6d”, *(*(p+i)+j) ); printf(“n”); ,指向二維數(shù)組元素的指針,二維數(shù)組用得較多的是“字

23、符串?dāng)?shù)組”,配合字符串的操作,使字符串處理更加方便、靈活。,char a4256=Pascal,VC,Basic,Java;,P a s c a l,V c,B a s i c,J a v a,#include #include #define MAXLEN 256 #define N 4 void main( ) int i, j; char tempMAXLEN; char nameNMAXLEN=Pascal,VC,Basic,Java; for(i=0; iN; i+) puts(namei); ,/書的數(shù)量,for(i=0; i0) strcpy(temp, namei); strc

24、py(namei, namej); strcpy(namej, temp); ,選擇法排序,/書名的最大長度+1,指向二維數(shù)組元素的指針,比較兩個字符串大小,復(fù)制字符串,Quiz 選擇法排序,Assignment,1、將數(shù)組a23中的每個元素向右移一列, 最后一列換到最左一列(如右圖所示) 要求:必須用指針實(shí)現(xiàn),2、將數(shù)組aMN中的每個元素向右移一列, 最后一列換到最左一列 要求:必須用指針實(shí)現(xiàn),Experiment,實(shí)驗(yàn)題目:指向二維數(shù)組的指針編程 實(shí)驗(yàn)?zāi)康模荷钊肜斫馊绾斡弥羔樧兞勘硎径S數(shù)組的 元素和元素的地址,學(xué)會用指向二維數(shù)組 的指針變量作函數(shù)參數(shù) 實(shí)驗(yàn)內(nèi)容:編程找出二維數(shù)組中的鞍點(diǎn),

25、二維數(shù)組的 鞍點(diǎn)是指在該位置上的元素在該行上最大, 在該列上最小,也可能沒有鞍點(diǎn)。要求必 須用指針實(shí)現(xiàn)。 編寫一個找鞍點(diǎn)的函數(shù),用指向二維數(shù)組 的指針變量作函數(shù)參數(shù),6.4 指針與字符串,一、字符指針 1. 定義指向字符串的指針變量 char *p = “China”; 說明 : 這里沒有定義字符數(shù)組, 但字符串在內(nèi)存中還是以數(shù)組 形式存放的. 字符串在內(nèi)存中 占有一片連續(xù)的存儲單元, 以0結(jié)束,注意 : 賦值只是把字符串的首地址賦給p , 而不是把字符串賦給 p, p 是一個指針變量, 它不能存放一個字符串, 只能存放一個地址,2460 2461 2462 2463 2464 2465,將字符串的 首地址賦給p,2. 輸出字符串: printf(“%sn” , p ) ; 輸出字符串時(shí), 先輸出p 指向的 第一個字符, 然后系統(tǒng)自動執(zhí)行p+, 使p 指向下一個字符, 再輸出該字符, 直到遇到0 為止 也可以用循環(huán)逐個輸出字符串中的字符: for ( ; *p!=0; p+ ) printf(“%c”, *p ) ;,2460 2

溫馨提示

  • 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)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論