版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、第12章指針的深入研究——指針進(jìn)階,指針與數(shù)組 指針與字符串 綜合應(yīng)用——報(bào)數(shù)游戲 跟我上機(jī),第12章指針的深入研究——指針進(jìn)階,指針與數(shù)組 指針與字符串 綜合應(yīng)用——報(bào)數(shù)游戲 跟我上機(jī),第12章指針的深入研究——指針進(jìn)階,指針與數(shù)組 指針與字符串 綜合應(yīng)用——報(bào)數(shù)游戲 跟我上機(jī),第12章指針的深入研究——指針進(jìn)階,指針與數(shù)組 指針與字符串 綜合應(yīng)用——報(bào)數(shù)游戲 跟我上機(jī),第12章
2、指針的深入研究——指針進(jìn)階,指針與數(shù)組 指針與字符串 綜合應(yīng)用——報(bào)數(shù)游戲 跟我上機(jī),12.1 指針與數(shù)組,12.1.1 指針與數(shù)組12.1.2 數(shù)組名作為指針12.1.3 指針與多維數(shù)組12.1.4 指針與數(shù)組參數(shù),12.1.1 指針與數(shù)組,指針用于存儲(chǔ)地址,他和數(shù)組名緊密的聯(lián)系在一起。下圖就顯示了一個(gè)數(shù)組名稱為grade,包含5個(gè)整型數(shù)據(jù)的一維數(shù)組,這里每個(gè)整型元素占用4個(gè)字節(jié)。,,12.1.1
3、指針與數(shù)組,訪問數(shù)組元素,我們可以使用下標(biāo)來實(shí)現(xiàn),比如我們要訪問數(shù)組元素grade[3],在之前的章節(jié)里我們詳細(xì)的講解過,但是那時(shí)使用的方法其實(shí)隱藏了數(shù)組每一個(gè)元素的地址。根據(jù)之前講過的地址的概念,加之我們已知的數(shù)組的特點(diǎn),這個(gè)特點(diǎn)就是數(shù)組在內(nèi)存總占用一塊連續(xù)的存儲(chǔ)區(qū)域,這樣的話,如果我們知道數(shù)組的首地址,針對grade這個(gè)數(shù)組,就是已知grade[0]的地址,我們就可以通過增減偏移量,得到garde[3]的地址,從而訪問到garde[
4、3]的元素值,12.1.1 指針與數(shù)組,&grade[3]=&grade[0] + 3 * 4上面表達(dá)式的含義是gradep[3]的地址等于grade[0]地址加上12。寫成以下的通式:數(shù)組中下標(biāo)為N元素的地址 = 數(shù)組的首地址 + N * sizeof(DataType)例如:int grade[5]; /*定義array為包含5個(gè)整型數(shù)據(jù)的數(shù)組*/int *p; /*定義p為指向整型變量的指針變量*/
5、p=&grade[0];,,12.1.1 指針與數(shù)組,【范例12-1】 使用指針訪問數(shù)組元素,分別使用下標(biāo)和指針訪問數(shù)組元素01 #include 02 int main(void)03 {04 int i;05 int grade[]={2,5,9,4,6};06 int *p;07 p=&grade[0]; /*指針指向*/08 print
6、f("使用下標(biāo)訪問數(shù)組元素:\n");09 for(i=0;i<5;i++) /*下標(biāo)訪問*/10 printf("數(shù)組grade的第%d個(gè)元素是%d\n",i,grade[i]);11 printf("使用數(shù)組指針訪問數(shù)組元素:\n");12 for(i=0;i<5;i++) /*指針訪問*/13
7、printf("數(shù)組grade的第%d個(gè)元素是%d\n",i,*(p+i));14 return 0;15 },12.1.1 指針與數(shù)組,需要注意的是*(p+i)表達(dá)式中的括號(hào)是必須有的,不能省略,如果我們遺漏了小括號(hào),將變成這樣的表達(dá)式*p+i,它的含義之前在指針變量處已經(jīng)進(jìn)行了講解,是在p所指向的存儲(chǔ)單元的數(shù)值基礎(chǔ)上在i,因?yàn)槲覀兪冀K沒有改變指針p的指向。,12.1.2 數(shù)組名作為指針,每個(gè)創(chuàng)
8、建的數(shù)組,數(shù)組名就成為編譯器為這個(gè)數(shù)組所創(chuàng)建的指針常量名稱,存儲(chǔ)的是數(shù)組第一個(gè)元素的起始地址,也是我們所說的數(shù)組首地址。這樣,我們就有多了一種獲取數(shù)組元素地址的手段。如【范例12-1】中代碼“p=&grade[0];”就可以改寫為“p=grade;”。,12.1.2 數(shù)組名作為指針,【范例12-2】 使用數(shù)組名作為指針訪問數(shù)組元素。01 #include 02 int main(void)03 {04
9、 int i;05 int grade[]={2,5,9,4,6};06 int *p;07 p=grade; /*指針賦值*/08 printf("使用數(shù)組名訪問數(shù)組元素:\n");09 for(i=0;i<5;i++) /*使用數(shù)組名*/10 printf("數(shù)組grade的第%d個(gè)元素是%d\n",i,*(gr
10、ade+i));11 printf("使用數(shù)組指針訪問數(shù)組元素:\n");12 for(i=0;i<5;i++) /*使用指針變量*/13 printf("數(shù)組grade的第%d個(gè)元素是%d\n",i,*(p+i));14 return 0;15 },12.1.2 數(shù)組名作為指針,面的代碼大家一起來分析一下,看看錯(cuò)了嗎?grade =
11、 grade+3;結(jié)果是有誤。原因是,grade是數(shù)組名,它是編譯器為這個(gè)數(shù)組創(chuàng)建的指針常量,常量當(dāng)然是不能夠再賦值的。再看下面的代碼,是否有問題?p = grade;p = p+3;結(jié)果是正確的。原因是,p是指針變量,它初始值是grade數(shù)組的首地址,之后根據(jù)需要修改了p的值,也就是改變了指針變量p的指向。,12.1.2 數(shù)組名作為指針,【范例12-3】 已知一個(gè)含有10整型元素的一維數(shù)組array,使用指針,求出該數(shù)組的
12、最大值,最小值和平均值,并輸出。,12.1.2 數(shù)組名作為指針,【范例12-4】有n個(gè)整數(shù),存儲(chǔ)在數(shù)組array中,使其前面各數(shù)順序向后移m個(gè)位置,最后m個(gè)數(shù)變成最前面的m個(gè)數(shù),并輸出。,12.1.3 指針與多維數(shù)組,我們知道數(shù)組在內(nèi)存中用連續(xù)的存儲(chǔ)區(qū)域,這一點(diǎn)已經(jīng)反復(fù)提到,我們以二維數(shù)組為例,數(shù)據(jù)是怎么存儲(chǔ)的呢?假設(shè)存在二維數(shù)組array[2][3],那么這6個(gè)數(shù)據(jù)在內(nèi)存中按照行走Z形排列,在內(nèi)存儲(chǔ)中存儲(chǔ)形式如下圖所示。,,12.
13、1.3 指針與多維數(shù)組,多維數(shù)組的數(shù)組名也被編譯器創(chuàng)建為常量,用來存儲(chǔ)該數(shù)組的首地址。數(shù)組名array存儲(chǔ)的是array[0][0]元素的地址,也就是存儲(chǔ)的值是&array[0][0]。我們也可以按照首地址加偏移量的形式,從而使指針指向該數(shù)組中任何一個(gè)元素,實(shí)現(xiàn)多維數(shù)組和指針的關(guān)聯(lián)。,12.1.3 指針與多維數(shù)組,下面我們逐步細(xì)分,讓大家掌握。第一步,我們寫出最容易理解的形式:array[1][2]/*指的是一個(gè)元素*
14、/&array[1][2]/*指的是array[1][2]元素的地址*/然后,我們深入一步:array/*指的是數(shù)組下標(biāo)為0的那一行的首地址*/array+1/*指的是數(shù)組下標(biāo)1的那一行的首地址*/&array[1]/*指的也是數(shù)組下標(biāo)1的那一行的首地址*/,12.1.3 指針與多維數(shù)組,接下來,我們進(jìn)一步深入:array[1]/*等價(jià)array[1]+0,于指的也是array[1][0]元素的地址
15、*/array[1]+2/*指的也是array[1][2]元素的地址*/*(array+1)+2/*指的也是array[1][2]元素的地址*/最后:*(*(array+1)+2)/*指的是元素array[1][2]值*/*( array[1]+2)/*指的是元素array[1][2]值*/,12.1.3 指針與多維數(shù)組,【范例12-5】 使用指針訪問二維數(shù)組,12.1.4 指針與數(shù)組參數(shù),1. 第一種情況:實(shí)參
16、是數(shù)組,形參也是數(shù)組主調(diào)函數(shù):int arr[10];function(arr);被調(diào)函數(shù):function(int arr[]) {...},12.1.4 指針與數(shù)組參數(shù),2. 第二種情況:實(shí)參是數(shù)組,形參是數(shù)組指針主調(diào)函數(shù):int arr[10];function(arr);被調(diào)函數(shù):function(int *p) {...},12.1.4 指針與數(shù)組參數(shù),3. 第三種情況:實(shí)參是數(shù)組指針,形參是數(shù)組指針。
17、主調(diào)函數(shù):int arr[10];int *p=arr;function(p);被調(diào)函數(shù):function(int *q) {...},12.1.4 指針與數(shù)組參數(shù),4. 第四種情況:實(shí)參是數(shù)組指針,形參是數(shù)組。主調(diào)函數(shù):int arr[10];int *p=arr;function(p);被調(diào)函數(shù):function(int arr[]) {...},12.1.4 指針與數(shù)組參數(shù),【范例12-6】 統(tǒng)計(jì)在a
18、rray字符串中從'a'到'z'的26個(gè)小寫字母各自現(xiàn)的次數(shù)。例如:輸入字符串“abcdefgabcdeabc”,輸出的結(jié)果應(yīng)該是“3 3 3 2 2 2 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0”,12.2 指針與字符串,12.2.1 使用指針創(chuàng)建字符串12.2.2 使用指針處理字符串12.2.3 指針的指針12.2.4 指針數(shù)組和數(shù)組指針,1
19、2.2.1 使用指針創(chuàng)建字符串,字符串的定義自動(dòng)就包含指針,例如,我們定義message1[100];為100個(gè)字符聲明存儲(chǔ)空間,并自動(dòng)的創(chuàng)建一個(gè)包含指針常量message1,是存儲(chǔ)的是message1[0]的地址。跟一般的常量一樣,指針常量指向是明確的,不能被修改。對于字符串,我們可以不按照聲明一般數(shù)組的方式,定義數(shù)組維數(shù)和每一維的個(gè)數(shù),還可以使用新的方法,也就是我們要講解的用指針創(chuàng)建字符串。例如下面的代碼:char *mes
20、sage2="how are you?";這個(gè)message1和message2是不同的,message1是按照數(shù)組定義方式定義的,如:char message1[100]= "how are you?";,12.2.1 使用指針創(chuàng)建字符串,這種形式要求,message1有固定的存儲(chǔ)該數(shù)組的空間,而且,因?yàn)閙essage1本身是數(shù)組名稱,一旦被初始化后,再執(zhí)行下面的語句就是錯(cuò)誤的,如
21、message1= "fine,and you?";message2本身就是一個(gè)指針變量,它通過顯式的方式明確了一個(gè)指針變量,對于message2執(zhí)行了初始化后,再執(zhí)行下面的代碼是正確的,message2= "fine,and you?";從分配空間的角度來分析,二者也是不同的。message1指定了一個(gè)存儲(chǔ)100個(gè)字符位置的空間,而對于message2就不同了,它只能存儲(chǔ)一個(gè)地
22、址,它只能保存指定字符串的第一個(gè)字符的地址。,12.2.1 使用指針創(chuàng)建字符串,【范例12-7】 八進(jìn)制轉(zhuǎn)十進(jìn)制。01 #include 02 int main(void)03 {04 char *p,s[6];05 int n;06 n=0;07 p=s;/*字符指針p指向字符數(shù)組s*/08 printf("輸入你要轉(zhuǎn)換的八進(jìn)制數(shù):\n");
23、09 gets(p);/*輸入字符串*/10 while(*(p)!='\0')/*檢查指針是否都字符數(shù)組結(jié)尾*/11 {12 n=n*8+*p-'0';/*八進(jìn)制轉(zhuǎn)十進(jìn)制計(jì)算公式*/13 p++;/*指針后移*/14 }15 printf("轉(zhuǎn)換的十進(jìn)制是:\n%d\n",n);16 re
24、turn 0;17 },12.2.2 使用指針處理字符串,【范例12-8】 字符串復(fù)制01 #include 02 int main(void)03 { 04 char str1[10],str2[10];05 char *p1,*p2;06 p1=str1;07 p2=str2;08 printf("請輸入原字符串:\n");09
25、 gets(p2);10 for (; *p2!='\0';p1++,p2++) /*循環(huán)復(fù)制str2中的字符到str1*/11 *p1=*p2;12 *p1='\0'; /*str1結(jié)尾補(bǔ)\0*/13 printf("原字符串是 :%s\n復(fù)制后字符串是:%s\n",str2,str1);14 return 0;15
26、 },12.2.2 使用指針處理字符串,這道題目聲明了兩個(gè)字符串的指針,通過指針移動(dòng),賦值字符串str2中的字符到str1,并且在str1結(jié)尾添加了字符串結(jié)束標(biāo)志。需要說明以下兩點(diǎn):⑴ 如果題目中沒有使用指針變量,而是直接在for循序中使用了str1++這樣的表達(dá)式,程序就會(huì)出錯(cuò),因?yàn)閟tr1是字符串的名字,是常量;⑵ 如果沒有寫*p1='\0';這行代碼,輸出的目標(biāo)字符串長度是9位,而且很可能后面的字符是
27、亂碼,因?yàn)閟tr1沒有結(jié)束標(biāo)志,直至遇見了聲明該字符串時(shí)設(shè)置好的結(jié)束標(biāo)志“\0”。,12.2.2 使用指針處理字符串,【范例12-9】 字符串連接。,12.2.2 使用指針處理字符串,【范例12-10】 已知一個(gè)字符串,使用返回指針的函數(shù),實(shí)現(xiàn)這樣的功能,把該字符串中的“#”號(hào)刪除,同時(shí)把后面連接的字符串前移。,12.2.3 指針的指針,【范例12-11】 使用指針的指針訪問字符串?dāng)?shù)組。01 #include 02
28、 int main(void)03 {04 char *array[]={"Winter","Spring","Summer","Fall"};05 char **p; /*指針的指針*/06 int i;07 for(i=0;i<4;i++)08 {09 p=array+i;
29、/*指針的指針p指向array+i所指向的字符串的首地址*/10 printf("%s\n",*p); /*輸出數(shù)組中的每一個(gè)字符串*/11 }12 return 0;13 },12.2.3 指針的指針,,,12.2.4 指針數(shù)組和數(shù)組指針,什么是指針數(shù)組呢?指針數(shù)組是指數(shù)組由指針類型的元素組成。比如:int *p[10]。這里數(shù)組p是由10個(gè)指向整型元素的指針組成的
30、,比如p[0]就是一個(gè)指針變量,它的使用跟一般的指針用法一樣,無非是這些指針有同一個(gè)名字需要使用下標(biāo)來區(qū)分。例如我們有下面的定義:char *p[2];char array[2][20];p[0]=array[0];p[1]=array[1];如下圖所示。,,12.2.4 指針數(shù)組和數(shù)組指針,數(shù)組指針,比如:int (*p)[10]。指針p用來指向含有10個(gè)元素的整型數(shù)組。【范例12-12】 使用數(shù)組指針。01
31、#include 02 int main(void)03 {04 int array[2][3]={1,2,3,4,5,6};05 int i,j;06 int (*p)[3];07 p=array; /*p指向array下標(biāo)為0那行的首地址*/08 for(i=0;i<2;i++)09 {10 for(j=0;j<3;j++)11
32、 printf("array[%d][%d]=%d\n",i,j,p[i][j]);12 }13 return 0;14 },12.3 綜合應(yīng)用——報(bào)數(shù)游戲,【范例12-13】 有n個(gè)人圍成一圈,順序排號(hào)。從第一個(gè)人開始報(bào)數(shù)(從1到3報(bào)數(shù)),凡報(bào)到3的人退出圈子,問最后留下的那位是原來的第幾號(hào)。,12.5 跟我上機(jī),1. 編寫C程序,使用指針,實(shí)現(xiàn)以下功能:編一個(gè)函數(shù)f
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫僅提供信息存儲(chǔ)空間,僅對用戶上傳內(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
提交評論