C語(yǔ)言程序設(shè)計(jì)項(xiàng)目化教程課件-模塊6_第1頁(yè)
C語(yǔ)言程序設(shè)計(jì)項(xiàng)目化教程課件-模塊6_第2頁(yè)
C語(yǔ)言程序設(shè)計(jì)項(xiàng)目化教程課件-模塊6_第3頁(yè)
C語(yǔ)言程序設(shè)計(jì)項(xiàng)目化教程課件-模塊6_第4頁(yè)
C語(yǔ)言程序設(shè)計(jì)項(xiàng)目化教程課件-模塊6_第5頁(yè)
已閱讀5頁(yè),還剩72頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

模塊六

使用指針實(shí)現(xiàn)學(xué)生成績(jī)操作模塊學(xué)習(xí)目標(biāo)1.理解和掌握指針的含義;2.掌握指針的定義、初始化和使用方法;3.了解指針和數(shù)組的關(guān)系。指針的相關(guān)概念指針與一維數(shù)組指針與二維數(shù)組指針與字符串指針與函數(shù)指向指針的指針和指針數(shù)組使用指針實(shí)現(xiàn)學(xué)生成績(jī)操作6.1指針的相關(guān)概念一、地址和指針系統(tǒng)的內(nèi)存就好比是帶有編號(hào)的房間,如果想使用內(nèi)存就需要得到房間編號(hào)。定義一個(gè)整型變量i,一個(gè)整型變量需要4個(gè)字節(jié),如果該變量的起始編號(hào)為1000,那么編譯器為該變量分配的編號(hào)為1000~1003。地址就是內(nèi)存區(qū)中對(duì)每個(gè)字節(jié)的編號(hào),如1000、1001、1002和1003就是地址。C程序中所定義的每一個(gè)變量都會(huì)被分配若干個(gè)連續(xù)的內(nèi)存單元,變量的值就存放在這些內(nèi)存單元中;變量被分配的內(nèi)存單元數(shù)量由變量的類型決定,除了共用體外,不同的變量使用不同的內(nèi)存單元。6.1指針的相關(guān)概念下圖中所示的1000、1004等就是內(nèi)存單元的地址,而0、1就是內(nèi)存單元的內(nèi)容,也就是基本整型變量i在內(nèi)存中的地址從1000開始,因基本整型占4個(gè)字節(jié),所以變量j在內(nèi)存中的起始地址為1004。6.1指針的相關(guān)概念二、指針與指針變量指針就是某個(gè)對(duì)象所占用的內(nèi)存單元的首地址。例如,變量i的首地址1000就是變量i的指針。變量的地址就是變量和指針二者之間連接的紐帶,如果一個(gè)變量包含了另一個(gè)變量的地址,則可以理解成第一個(gè)變量指向第二個(gè)變量。存放變量地址的變量稱為指針變量,指針變量是指向一個(gè)變量的地址。指針變量與變量在內(nèi)存中的關(guān)系右圖所示:

通過(guò)1000這個(gè)地址能訪問(wèn)2000的存儲(chǔ)單元,再通過(guò)2000找到對(duì)應(yīng)的數(shù)據(jù)。6.1指針的相關(guān)概念1.指針變量的一般形式指針變量的一般形式為:

類型說(shuō)明*指針變量名其中“*”表示該變量是一個(gè)指針變量,類型說(shuō)明表示該指針變量所指向的變量的數(shù)據(jù)類型,例如int*q6.1指針的相關(guān)概念2.指針變量的賦值指針變量同普通變量一樣,使用之前不僅需要定義,而且必須賦予具體的值,未經(jīng)賦值的指針變量不能使用,同時(shí),指針變量賦值只能賦予地址,而不能賦予任何其他數(shù)據(jù),賦值的一般形式為:

指針變量名=&變量名;6.1指針的相關(guān)概念例如,&a表示變量a的地址,&b表示變量b的地址。給一個(gè)指針變量賦值可以有以下兩種方法:(1)在定義指針變量的同時(shí)進(jìn)行賦值,例如:

inta;

int*p=&a;(2)先定義指針變量,然后再賦值,例如:

inta;

int*p;

p=&a;注意:這兩種賦值語(yǔ)句的區(qū)別在于如果在定義完指針變量之后再賦值不能加“*”。6.1指針的相關(guān)概念實(shí)例6-1-1:輸出變量地址。本實(shí)例定義一個(gè)變量,之后以十六進(jìn)制格式輸出變量的地址。具體代碼如下:#include<stdio.h>intmain(){inta;int*ipointer1;/*聲明指針變量*/printf("請(qǐng)輸入數(shù)據(jù):\n");scanf("%d",&a);ipointer1=&a;/*將地址賦給指針變量*/

printf("轉(zhuǎn)化十六進(jìn)制為:%x\n",ipointer1);/*以十六進(jìn)制輸出*/return0;}6.1指針的相關(guān)概念3.指針變量的引用引用指針變量是對(duì)變量進(jìn)行間接訪問(wèn)的一種形式。指針變量的引用形式為:

*指針變量6.1指針的相關(guān)概念實(shí)例6-1-2:利用指針編寫程序,將兩個(gè)數(shù)予以交換。本實(shí)例定義一個(gè)swap函數(shù),要求它的參數(shù)是指針類型,所要實(shí)現(xiàn)的功能是將兩個(gè)數(shù)進(jìn)行交換。具體代碼如下:

#include<stdio.h>voidswap(int*a,int*b)/*自定義交換函數(shù)*/{

intt=*a;/*實(shí)現(xiàn)兩數(shù)交換*/

*a=*b;

*b=t;}

intmain()/*主函數(shù)main*/{

intx=10,y=5;

swap(&x,&y);/*調(diào)用函數(shù)實(shí)現(xiàn)兩數(shù)交換值*/

printf("交換數(shù)據(jù)是:x=%d,y=%d\n",x,y);

return0;}6.1指針的相關(guān)概念4.運(yùn)算符“&”和“*”運(yùn)算符&是一個(gè)返回操作數(shù)地址的單目運(yùn)算符,也叫取地址運(yùn)算符,例如:p=&i;就是將i的內(nèi)存地址賦值給p,這個(gè)地址是該變量在計(jì)算機(jī)內(nèi)部的存儲(chǔ)位置。運(yùn)算符*是單目運(yùn)算符,也叫指針運(yùn)算符,作用是返回指定的地址內(nèi)的變量的值。例如:q=*p;如果p中裝有變量i的內(nèi)存地址,則變量i的值賦給q,假設(shè)變量i的值是5,則q的值也是5。6.1指針的相關(guān)概念5.“&*”和“*&”區(qū)別“&”和“*”運(yùn)算符優(yōu)先級(jí)別相同,按自右而左的方向結(jié)合。

inta;

p=&a;“&*p”先進(jìn)行“*”運(yùn)算,“*p”相當(dāng)于變量a,再進(jìn)行“&”運(yùn)算,“&*p”相當(dāng)于取變量a的地址?!?&a”先進(jìn)行“&”運(yùn)算,“&a”就是取變量a的地址,然后執(zhí)行“*”運(yùn)算,“*&a”相當(dāng)于取變量a所在地址的值,實(shí)際就是變量a。6.1指針的相關(guān)概念實(shí)例6-1-3:輸出i、j、c的地址。本實(shí)例定義了3個(gè)指針變量i、j、c,計(jì)算“c=i+j”,計(jì)算后使用“&*”分別輸出i、j、c的地址值,具體代碼如下:#include<stdio.h>intmain(){longi,j,c;long*p,*q,*n;/*定義指針變量*/printf("pleaseinputthenumbers:\n");scanf("%ld,ld",&i,&j);c=i+j;p=&i;/*將地址賦給指針變量*/q=&j;n=&c;printf("%ld\n",&*p);/*輸出變量i的地址*/printf("%ld\n",&*q);/*輸出變量j的地址*/printf("%ld\n",&*n);/*輸出變量c的地址*/return0;}6.1指針的相關(guān)概念拓展訓(xùn)練一:某工程隊(duì)修一條公路,第一天修600米,第二天修全長(zhǎng)的20%,第三天修全長(zhǎng)的25%,這三天共修全長(zhǎng)的75%,求這條公路全長(zhǎng)為多少米?編寫程序計(jì)算并輸出此公路總長(zhǎng)變量的內(nèi)存地址。6.1指針的相關(guān)概念三、指針的自增自減運(yùn)算指針的自增自減運(yùn)算不同于普通變量的自增自減運(yùn)算,也就是說(shuō)并非簡(jiǎn)單地加1或減1。例如:基本整型變量i在內(nèi)存中占4個(gè)字符,假設(shè)指針p是指向變量i的地址,那么p++不是簡(jiǎn)單地在地址上加1,而是指向下一個(gè)存放基本整型變量的地址。6.1指針的相關(guān)概念實(shí)例6-1-4:指針自增。本實(shí)例定義一個(gè)指針變量,將這個(gè)指針進(jìn)行自增運(yùn)算,利用printf函數(shù)輸出該指針變量的值,具體代碼如下:

#include<stdio.h>voidmain(){inti;int*p;printf("pleaseinputthenumber:\n");scanf("%d",&i);p=&i;/*將變量i的地址賦給指針變量*/printf("theresult1is:%d\n",p);p++;/*地址加1,這里的1并不代表一個(gè)字節(jié)*/printf("theresult2is:%d\n",p);}6.1指針的相關(guān)概念指針是按照它所指向的數(shù)據(jù)類型的直接長(zhǎng)度進(jìn)行增或減??梢詫?shí)例6-1-4用下圖表示6.1指針的相關(guān)概念拓展訓(xùn)練二:

利用指針統(tǒng)計(jì)“IdeeplyloveChina.”的單詞個(gè)數(shù)。6.2指針與一維數(shù)組一、指針與一維數(shù)組的關(guān)系數(shù)組是最基本的構(gòu)造類型,是相同類型數(shù)據(jù)的有序集合。數(shù)組中的元素按順序存放在地址連續(xù)的內(nèi)存單元中,每一個(gè)數(shù)組元素都有各自的地址,數(shù)組名是數(shù)組首元素的地址。對(duì)數(shù)組元素的訪問(wèn),可以使用下標(biāo),也可以使用指針變量,移動(dòng)指針可以指向數(shù)組中的任意一個(gè)元素。6.2指針與一維數(shù)組實(shí)例6-2-1:訪問(wèn)數(shù)組元素的四種等價(jià)方式。#include<stdio.h>intmain(){inti,a[5]={1,2,3,4,5},*p=&a[0];printf("\na[i]:");for(i=0;i<5;i++)/*常規(guī)下標(biāo)法訪問(wèn)數(shù)組元素*/printf("%3d",a[i]);printf("\n*(a+i):");for(i=0;i<5;i++)/*數(shù)組名作為指針訪問(wèn)數(shù)組元素*/printf("%3d",*(a+i));printf("\np[i]:");for(i=0;i<5;i++)/*指針變量下標(biāo)法訪問(wèn)數(shù)組元素*/printf("%3d",p[i]);printf("\n*(p+i):");for(i=0;i<5;i++)/*使用指針變量訪問(wèn)數(shù)組元素*/printf("%3d",*(p+i));return0;}6.2指針與一維數(shù)組二、一維數(shù)組與指針的定義當(dāng)定義一個(gè)一維數(shù)組時(shí),系統(tǒng)會(huì)在內(nèi)存中為該數(shù)組分配一個(gè)存儲(chǔ)空間,其數(shù)組的名稱就是數(shù)組在內(nèi)存中的首地址,若再定義一個(gè)指針變量,并將數(shù)組的首地址傳遞給指針變量,則該指針就指向了這個(gè)一維數(shù)組。例如:int*p,a[10];p=a;這里a是數(shù)組名,也就是數(shù)組的首地址,將它賦給指針變量p,也就是將數(shù)組a的首地址賦給p。也可以寫成如下形式:int*p,a[10];p=&a[0];上面的語(yǔ)句是將數(shù)組a中的首個(gè)元素的地址賦給指針變量p,由于a[0]的地址就是數(shù)組的首地址,因此兩條賦值操作效果完全相同。6.2指針與一維數(shù)組實(shí)例6-2-2:輸出數(shù)組中的元素。本實(shí)例是使用指針變量輸出數(shù)組中的每個(gè)元素,具體代碼如下:

#include<stdio.h>voidmain(){int*p,*q,a[5],b[5],i;p=&a[0];

q=b;printf("pleaseinputarraya:\n");for(i=0;i<5;i++)scanf("%d",&a[i]);/*為數(shù)組a中的元素賦初值*/printf("pleaseinputarrayb:\n");for(i=0;i<5;i++)scanf("%d",&b[i]);/*為數(shù)組b中的元素賦初值*/printf("arrayais:\n");for(i=0;i<5;i++)printf("%5d",*(p+i));/*輸出數(shù)組a中的元素*/printf("\n");printf("arraybis:\n");for(i=0;i<5;i++)printf("%5d",*(q+i));/*輸出數(shù)組b中的元素*/printf("\n");}6.2指針與一維數(shù)組說(shuō)明:(1)本實(shí)例中第5行和第6行的語(yǔ)句為:05p=&a[0];06q=b;以上這兩種表示方法都是將數(shù)組首地址賦給指針變量。(2)p+n與a+n表示數(shù)組元素a[n]的地址,即&a[n]。對(duì)數(shù)組a來(lái)說(shuō),共有5個(gè)元素,n的取值為0~4,則數(shù)組元素的地址就可以表示為p+0~p+4或a+0~a+4。(3)表示數(shù)組中的元素用到了前面介紹的數(shù)組元素的地址,用*(p+n)和*(a+n)來(lái)表示數(shù)組中的各元素。6.2指針與一維數(shù)組實(shí)例6-2-2中第15行的語(yǔ)句為:

15printf("%5d",*(p+i));實(shí)例6-2-2中第19行語(yǔ)句為:

19printf("%5d",*(q+i));上述兩條語(yǔ)句分別表示輸出數(shù)組a和數(shù)組b中對(duì)應(yīng)的元素。實(shí)例6-2-2中使用指針指向一維數(shù)組及通過(guò)指針引用數(shù)組元素的過(guò)程可以通過(guò)左圖和右圖來(lái)表示。6.2指針與一維數(shù)組在C語(yǔ)言中,可以用a+n表示數(shù)組元素的地址。*(a+n)表示數(shù)組元素,這樣就可以將實(shí)例6-2-2中的程序第13行到第20行代碼改成下列形式1:13printf("arrayais:\n");14for(i=0;i<5;i++)15printf("%5d",*(a+i));16printf("\n");17printf("arraybis:\n");18for(i=0;i<5;i++)19printf("%5d",*(b+i));20printf("\n");程序運(yùn)行的結(jié)果與實(shí)例6-2-2的運(yùn)行結(jié)果相同。6.2指針與一維數(shù)組表示指針的移動(dòng)可以使用“++”和“--”兩個(gè)運(yùn)算符,利用“++”運(yùn)算符可將程序的第13行到第20行的代碼改寫成下列形式2:13printf("arrayais:\n");14for(i=0;i<5;i++)15printf("%5d",*p++);16printf("\n");17printf("arraybis:\n");18for(i=0;i<5;i++)19printf("%5d",*q++);20printf("\n");6.2指針與一維數(shù)組還可將實(shí)例6-2-2代碼再進(jìn)一步改寫,運(yùn)行結(jié)果仍相同,在上面修改后的基礎(chǔ)上修改實(shí)例6-2-2程序的第7行到第12行代碼,修改后的程序代碼如下列形式3:7printf("pleaseinputarraya:\n");8for(i=0;i<5;i++)9scanf("%d",p++);10printf("pleaseinputarrayb:\n");11for(i=0;i<5;i++)12scanf("%d",q++);

p=a;

q=b;6.2指針與一維數(shù)組將上述形式3中的程序與實(shí)例6-2-2程序?qū)Ρ?,可以看出,如果在輸出?shù)組元素時(shí)需要使用指針變量,則需加上如下兩條語(yǔ)句:p=a;q=b;這兩條語(yǔ)句的作用是將指針變量p和q重新指向數(shù)組a和數(shù)組b在內(nèi)存中的起始位置。若沒(méi)有這兩條語(yǔ)句,而直接使用*p++的方法進(jìn)行輸出,就會(huì)產(chǎn)生錯(cuò)誤。拓展訓(xùn)練三:使用指針尋找字符串“howareyou,andiamfine,doyouknow?”中“,”的位置。6.3指針與二維數(shù)組一、指針與二維數(shù)組的關(guān)系與一維數(shù)組相同,二維數(shù)組在內(nèi)存中也是連續(xù)存儲(chǔ)的。設(shè)有定義inta[3][3],假設(shè)a[0][0]的地址為2000,數(shù)組中各元素的首地址下圖所示??梢詮纳蠄D中看出,a數(shù)組中的元素從地址2000開始按照行的順序連續(xù)存放在內(nèi)存中。6.3指針與二維數(shù)組一、指針與二維數(shù)組的關(guān)系在C語(yǔ)言中,二維數(shù)組被看成一維數(shù)組的一維數(shù)組,二維數(shù)組的每一行都被看作是一個(gè)一維數(shù)組,其數(shù)組名分別為a[0]、a[1]和a[2],如下圖所示。6.3指針與二維數(shù)組二維數(shù)組名代表二維數(shù)組首元素的地址,由于二維數(shù)組的元素被看作為一維數(shù)組的一維數(shù)組,故數(shù)組a[3][3]可分解為3個(gè)一維數(shù)組,分別是a[0]、a[1]、a[2]。每一個(gè)一維數(shù)組又含有3個(gè)元素,如a[0]數(shù)組含有a[0][0]、a[0][1]、a[0][2]3個(gè)元素。數(shù)組及數(shù)組元素的地址表示如下:a是二維數(shù)組名,也是二維數(shù)組0行的首地址,等于2000。a[0]是第一個(gè)一維數(shù)組的數(shù)組名和首地址,因此也為2000。*(a+0)或*a是與a[0]等效的,它表示一維數(shù)組a[0]的0號(hào)元素的首地址,也為2000。&a[0][0]是二維數(shù)組a的0行0列元素的首地址,同樣是2000。因此a、a[0]、*(a+0)、*a、&a[0][0]都是相等的。同理a+i、a[i]、*(a+i)、&a[i][0]也都是相等的,此外&a[i]和a[i]也是相等的,因?yàn)樵诙S數(shù)組中不能把&a[i]理解為元素a[i]的地址,所以不存在元素a[i]。另外,a[0]也可以看成是a[0]+0,是一維數(shù)組a[0]的0號(hào)元素的首地址,而a[0]+1則是a[0]的1號(hào)元素首地址,由此得出a[i]+j是一維數(shù)組a[i]的j號(hào)元素首地址,它等于&a[i][j]。6.3指針與二維數(shù)組實(shí)例6-3-1:用二維數(shù)組名的方式訪問(wèn)a[1][2]的常見方式的具體實(shí)現(xiàn)代碼如下:#include<stdio.h>intmain(){inta[3][3]={1,2,3,4,5,6,7,8,9};printf("a[1][2]=%d\n",a[1][2]);printf("*(a[1]+2)=%d\n",*(a[1]+2));printf("*(*(a+1)+2)=%d\n",*(*(a+1)+2));return0;}6.3指針與二維數(shù)組二、指向二維數(shù)組元素的指針二維數(shù)組的各個(gè)元素在內(nèi)存中是連續(xù)存放的,存放方式與一維數(shù)組并無(wú)區(qū)別,可以將二維數(shù)組當(dāng)做一維數(shù)組進(jìn)行處理,指針變量指向二維數(shù)組某元素的格式如下:指針變量名=&二維數(shù)組[行下標(biāo)][列下標(biāo)]指針變量名=*二維數(shù)組名指針變量名=二維數(shù)組[行下標(biāo)]當(dāng)行下標(biāo)和列下標(biāo)均為0時(shí),指針變量指向二維數(shù)組首元素的地址,引用該數(shù)組元素的方法是:

*指針變量6.3指針與二維數(shù)組實(shí)例6-3-2:將輸入的數(shù)以二維數(shù)組顯示。輸入15個(gè)整型數(shù)據(jù),將這些數(shù)據(jù)以3行5列的二維數(shù)組的形式顯示。具體代碼如下:

#include<stdio.h>voidmain(){inta[3][5],*p,i,j;printf("pleaseinput:\n");for(i=0;i<3;i++)/*控制二維數(shù)組的行數(shù)*/for(j=0;j<5;j++)/*控制二維數(shù)組的列數(shù)*/scanf("%d",&a[i][j]);/*給二維數(shù)組元素賦初值*/p=&a[0][0];printf("thearrayis:\n");for(i=0;i<15;i++){printf("%5d",*(p+i));/*輸出二維數(shù)組中元素*/if((i+1)%5==0)printf("\n");}}6.3指針與二維數(shù)組拓展訓(xùn)練四:某校班級(jí)有5×5個(gè)座位,輸出位置最好的一行座位號(hào)。(提示:第2行最受歡迎)6.3指針與二維數(shù)組三、指向二維數(shù)組的行指針變量由于二維數(shù)組的每一行都被視為一個(gè)一維數(shù)組,所以可以定義一個(gè)指針來(lái)指向每一行的一維數(shù)組,則行指針變量是指向一行數(shù)組元素的起始地址。聲明行指針變量的一般格式為:類型名(*指針變量名)[n]其中:類型名為指針變量名所指向數(shù)組的數(shù)據(jù)類型。n表示由一個(gè)二維數(shù)組分解為多個(gè)一維數(shù)組的長(zhǎng)度,也就是所指向的二維數(shù)組的列數(shù)。格式中,()、*和[n]都不可省略。注意:行指針變量用于指向一行數(shù)組元素的起始地址,而非數(shù)組中的元素。定義行指針變量以后,只要將二維數(shù)組的首地址賦給行指針變量,則行指針變量就與二維數(shù)組建立了聯(lián)系,二維數(shù)組也就成為行指針變量指向的對(duì)象。此時(shí),就可以用指針?lè)ㄔL問(wèn)該二維數(shù)組的元素了。6.3指針與二維數(shù)組實(shí)例6-3-3:行指針變量訪問(wèn)二維數(shù)組示例。

#include<stdio.h>#definerow3#definecol4intmain(){inta[row][col]={1,2,3,4,5,6,7,8,9,10,11,12};int(*p)[col]=a;/*定義行指針p,并指向數(shù)組a*/inti,j;for(i=0;i<row;i++)for(j=0;j<col;j++)printf("%3d",*(*(p+i)+j));/*可以在此處替換訪問(wèn)a[i][j]的方式*/printf("\n");return0;}6.3指針與二維數(shù)組實(shí)例6-3-4:將停車場(chǎng)的第2行停車號(hào)輸出。某停車場(chǎng)有3×3個(gè)停車位,利用指針將第2行的停車號(hào)輸出,具體代碼如下:

#include<stdio.h>voidmain(){inta[3][3],i,j;printf("pleaseinput:\n");for(i=0;i<3;i++)/*控制二維數(shù)組的行數(shù)*/for(j=0;j<3;j++)/*控制二維數(shù)組的列數(shù)*/scanf("%d",*(a+i)+j);/*為二維數(shù)組中的元素賦值*/printf("thesecondlineis:\n");for(j=0;j<3;j++)printf("%5d",*(*(a+1)+j));/*輸出二維數(shù)組中的元素*/printf("\n");}6.3指針與二維數(shù)組實(shí)例6-3-5:求每個(gè)學(xué)生的總分與平均成績(jī)。有5名學(xué)生,每人有3門考試成績(jī),計(jì)算每個(gè)學(xué)生的總分與平均成績(jī)。查找有1門及1門以上課程不及格的學(xué)生,并輸出這些學(xué)生的全部課程成績(jī)。#include<stdio.h>average(intstudent[5][6]){inti,j;printf("學(xué)號(hào)數(shù)學(xué)英語(yǔ)計(jì)算機(jī)總分平均分\n");for(i=0;i<5;i++){student[i][4]=student[i][1]+student[i][2]+student[i][3];/*總分*/student[i][5]=student[i][4]/3;/*平均分*/}for(i=0;i<5;i++){for(j=0;j<6;j++)printf("%-12d",student[i][j]);/*打印數(shù)組的元素*/printf("\n");}}

search(int(*p1)[6],intn)/*查找成績(jī)不及格學(xué)生函數(shù)*/{inti,j,flag;printf("\n有一門以上課程成績(jī)不及格的學(xué)生如下:\n");for(i=0;i<n;i++)/*n=5,對(duì)5個(gè)學(xué)生3門課程進(jìn)行查找*/{flag=0;/*用flag標(biāo)記,若成績(jī)<60,flag=1*/for(j=1;j<4;j++)if(*(*(p1+i)+j)<60)flag=1;/**(*(p1+i)+j就是score[i][j]*/if(flag==1)for(j=0;j<6;j++)/*用循環(huán)輸出該行6個(gè)數(shù)*/printf("%-12d",*(*(p1+i)+j));printf("\n");}}

intmain(){intscore[5][6]={{201101,78,93,82},{201102,67,83,72},{201103,55,83,62},{201104,65,59,70},{201105,80,78,90}};average(score);/*調(diào)用求平均分函數(shù)*/search(score,5);/*調(diào)用查找并輸出有成績(jī)不及格學(xué)生的函數(shù)*/return0;}6.4指針與字符串一、字符串與字符指針字符串操作是數(shù)據(jù)處理中常見的操作。在C語(yǔ)言中,可以使用字符指針來(lái)操作字符串,相比使用字符數(shù)組操作字符串,前者更加便利。在C語(yǔ)言中,字符串有兩種表示方式:字符數(shù)組或字符指針。字符數(shù)組的表示方式如下:

charstr[]="VisualC++2010";

puts(str);在這種表示方式中,str是數(shù)組名,也是指向字符串的指針。除了在定義字符數(shù)組時(shí)可以將字符串整體以賦值的形式存儲(chǔ)到數(shù)組中之外,在其他位置的代碼中使用“str="VisualC++2010";”語(yǔ)句都是錯(cuò)誤的。6.4指針與字符串字符指針的表示方式如下:

char*str="hello";

puts(str);字符串“hello”在內(nèi)存中以字符數(shù)組形式存儲(chǔ),語(yǔ)句“char*str="hello";”的含義是指針str指向字符串“hello”的首字符,這里的“=”號(hào)表示將字符串“hello”的第一個(gè)字符的地址賦給str。6.4指針與字符串實(shí)例6-4-1:利用指針實(shí)現(xiàn)字符串復(fù)制。本實(shí)例中,在不使用strcpy函數(shù)的情況下,利用指針實(shí)現(xiàn)字符串復(fù)制功能,具體代碼如下:#include<stdio.h>

voidmain(){charstr1[]="youarebeautiful",str2[30],*p1,*p2;p1=str1;p2=str2;while(*p1!='\0'){*p2=*p1;p1++;/*指針移動(dòng)*/p2++;}*p2='\0';/*在字符串的末尾加結(jié)束符*/printf("Nowthestring2is:\n");puts(str2);/*輸出字符串*/}從實(shí)例6-4-1代碼和運(yùn)行結(jié)果可以看出:該實(shí)例中定義了兩個(gè)指向字符型數(shù)據(jù)的指針變量。首先使指針變量p1和p2分別指向字符串str1和字符串str2的第一個(gè)字符的地址。再將p1所指向的內(nèi)容賦給p2所指向的元素,然后使p1和p2分別加1,即指向下一個(gè)元素,如此反復(fù)循環(huán),直到*p1的值為“\0”為止。6.4指針與字符串二、使用字符數(shù)組與字符指針處理字符串的區(qū)別雖然字符數(shù)組和字符指針都可以用于處理字符串,但二者之間還是有區(qū)別的。(1)賦值方法不同。如下面給字符指針賦值的方法是正確的:

char*str;

str="hello";其含義是字符指針指向字符串“hello”的首地址。而下面字符數(shù)組的賦值方法是錯(cuò)誤的:

charstr[10];

str="hello";因?yàn)樽址麛?shù)組名str為一常量地址,不能被賦值。6.4指針與字符串(2)系統(tǒng)為其分配內(nèi)存單元的方法不同。字符數(shù)組被定義以后,系統(tǒng)為其分配一段連續(xù)的內(nèi)存單元,字符數(shù)組名為這段連續(xù)內(nèi)存單元的首地址;而字符指針變量被定義以后,系統(tǒng)為其分配一個(gè)存放指針值(地址)的內(nèi)存單元,其指向的對(duì)象并不明確,即下面的用法是錯(cuò)誤的:

char*str;

scanf("%s",str);而下面的字符數(shù)組的用法是正確的:

charstr[10];

scanf("%s",str);但字符指針一旦指向某個(gè)具體對(duì)象,就可以用于輸入了,下面的用法是正確的:

chara[10],*str=a;

scanf("%s",str);6.4指針與字符串(3)修改(地址)的方法不同。字符指針的值(地址)可以被反復(fù)修改,也就是可以通過(guò)修改其值使其可以指向字符串中的任意位置;但字符數(shù)組名只能被引用,而不能被修改。例如:

chara[25]=chara[25]="clanguageprogramming!",*str=a;

str=a+2;

puts(str);

str=str+9;

puts(str);

printf("%c",*str);6.4指針與字符串三、字符串?dāng)?shù)組字符數(shù)組是一個(gè)一維數(shù)組,而字符串?dāng)?shù)組是一個(gè)將字符串作為數(shù)組元素的數(shù)組,可視其為一個(gè)二維字符數(shù)組。例如下面定義一個(gè)簡(jiǎn)單的字符串?dāng)?shù)組,代碼如下:charcountry[5][20]={"China","Japan","Ruassia","Germany","Switzerland"}

字符串?dāng)?shù)組變量country被定義為含有5個(gè)字符串的數(shù)組,每個(gè)字符串的長(zhǎng)度要小于20(這里要考慮字符串最后的'\0')。6.4指針與字符串

通過(guò)觀察上面定義的字符串?dāng)?shù)組可以發(fā)現(xiàn),像“China”和“Japan”這樣的字符串的長(zhǎng)度僅為5,加上字符串結(jié)束符其長(zhǎng)度也僅為6,而內(nèi)存中卻要給它們分別分配一個(gè)20字節(jié)的空間,這樣就會(huì)造成資源浪費(fèi)。為了解決這個(gè)問(wèn)題,可以使用指針數(shù)組,使每個(gè)指針指向所需要的字符常量。這種方法雖然需要在數(shù)組中保存字符指針,而且也占用空間,但要遠(yuǎn)少于字符串?dāng)?shù)組需要的空間。一維指針數(shù)組的定義形式如下:

類型名*數(shù)組名[數(shù)組長(zhǎng)度]6.4指針與字符串實(shí)例6-4-2:輸出12個(gè)月的月份。本實(shí)例定義了一個(gè)指針數(shù)組,并且為這個(gè)指針數(shù)組賦初值,將12個(gè)月份輸出,具體代碼如下:

#include<stdio.h>voidmain(){inti;char*month[]={"January","February","March","April","May","June","July","August","September","October","November","December"};for(i=0;i<12;i++)printf("%s\n",month[i]);}6.4指針與字符串拓展訓(xùn)練五:小學(xué)六年級(jí)英語(yǔ)期末考試,有一題是根據(jù)漢語(yǔ)填寫英語(yǔ),漢語(yǔ)題目是語(yǔ)文、數(shù)學(xué)、英語(yǔ)、化學(xué)、生物、物理,填寫的英語(yǔ)分別為Chinese、Math、English、Chemistry、Biology、Physics,請(qǐng)用字符串?dāng)?shù)組輸出填寫的英文。6.5指針與函數(shù)一、指針作函數(shù)的參數(shù)指針作為函數(shù)的形參時(shí),在形參說(shuō)明時(shí)需要使用格式“類型名*指針名”。*號(hào)不能省略,而在函數(shù)定義的說(shuō)明部分,*號(hào)的作用是類型說(shuō)明符。實(shí)例6-5-1:指針作為形參的函數(shù)調(diào)用。#include<stdio.h>voidchangeA(int*);/*函數(shù)聲明*/intmain(){inta=10,*pa=&a;printf("調(diào)用前:pa=%x,a=%d\n",pa,a);changeA(pa);/*函數(shù)調(diào)用*/printf("調(diào)用后:pa=%x,a=%d\n",pa,a);return0;}

voidchangeA(int*p)/*函數(shù)定義*/{intb;*p=*p+*p;/*操作p所指向的變量*/p=&b;/*p指向b*/printf("在函數(shù)中:p=%x\n",p);}6.5指針與函數(shù)說(shuō)明:在main函數(shù)中調(diào)用函數(shù)changeA時(shí),將實(shí)參pa的值傳遞給形參p,p和pa都指向變量a,*p=*p+*p等價(jià)于a=a+a,結(jié)果是將a的值修改為20,然后p指向b。分析程序運(yùn)行結(jié)果的第一行和第三行可以知道,在函數(shù)內(nèi)通過(guò)p訪問(wèn)a的操作改變了函數(shù)外變量a的值;分析程序運(yùn)行結(jié)果的第二行和第三行可以知道,函數(shù)內(nèi)對(duì)p的操作,與函數(shù)外的變量pa無(wú)關(guān)。運(yùn)行結(jié)果中的pa和p的值在不同的C語(yǔ)言編譯器中可能會(huì)有所不同。第二行代碼“voidchangeA(int*)”的作用是函數(shù)聲明,其中*號(hào)不能省略,它的作用是說(shuō)明changeA函數(shù)的形參為int類型的指針變量。指針作為函數(shù)參數(shù),在被定義、聲明和調(diào)用時(shí),數(shù)據(jù)類型都必須一致,如果不一致,編譯就會(huì)報(bào)錯(cuò)。指針作為函數(shù)的形參時(shí),函數(shù)中可以修改指針?biāo)赶虻膶?duì)象,利用這個(gè)特性,一個(gè)函數(shù)可以獲得多個(gè)返回值,只要在定義這個(gè)函數(shù)時(shí)使用多個(gè)指針變量作為形參即可。6.5指針與函數(shù)實(shí)例6-5-2:將輸入的3個(gè)數(shù)從大到小輸出。本實(shí)例使用嵌套函數(shù)實(shí)現(xiàn)相關(guān)功能,在定義的排序函數(shù)中嵌套了自定義交換函數(shù),實(shí)現(xiàn)了數(shù)據(jù)按從大到小進(jìn)行排序的功能,具體代碼如下:#include<stdio.h>voidswap(int*p1,int*p2)/*自定義交換函數(shù)*/{inttemp;temp=*p1;*p1=*p2;*p2=temp;}voidexchange(int*pt1,int*pt2,int*pt3)/*3個(gè)數(shù)由大到小排序*/{if(*pt1<*pt2)swap(pt1,pt2);/*調(diào)用swap函數(shù)*/if(*pt1<*pt3)swap(pt1,pt3);if(*pt2<*pt3)swap(pt2,pt3);}

voidmain(){inta,b,c,*q1,*q2,*q3;puts("Pleaseinputthreekeynumbersyouwanttorank:");scanf("%d,%d,%d",&a,&b,&c);q1=&a;/*將變量a地址賦給指針變量q1*/q2=&b;q3=&c;exchange(q1,q2,q3);/*調(diào)用exchange函數(shù)*/printf("\n%d,%d,%d\n",a,b,c);}6.5指針與函數(shù)從該實(shí)例代碼和運(yùn)行結(jié)果可以看出:(1)程序創(chuàng)建了一個(gè)自定義函數(shù)swap,用于實(shí)現(xiàn)交換兩個(gè)變量的值;還創(chuàng)建了一個(gè)exchange函數(shù),其作用是將3個(gè)數(shù)由大到小排序,在exchange函數(shù)中還調(diào)用了前面自定義的swap函數(shù),這里的swap和exchange函數(shù)都是以指針變量作為形式參數(shù)的。(2)程序運(yùn)行時(shí),通過(guò)鍵盤輸入3個(gè)數(shù)并保存在變量a、b、c中,分別將a、b、c的地址賦予q1、q2、q3,調(diào)用exchange函數(shù),將指針變量作為實(shí)際參數(shù),將實(shí)際參數(shù)變量的值傳遞給形式參數(shù)變量,此時(shí)q1和pt1都指向變量a,q2和pt2都指向變量b,q3和pt3都指向變量c,在exchange函數(shù)中又調(diào)用了swap函數(shù),當(dāng)執(zhí)行swap(pt1,pt2)時(shí),pt1也指向了變量a,pt2也指向了變量b。6.5指針與函數(shù)實(shí)例6-5-3:使用指針實(shí)現(xiàn)冒泡排序。#include<stdio.h>voidorder(int*p,intn){inti,t,j;for(i=0;i<n-1;i++)for(j=0;j<n-1-i;j++)if(*(p+j)>*(p+j+1))/*判斷相鄰兩個(gè)元素的大小*/{t=*(p+j);*(p+j)=*(p+j+1);*(p+j+1)=t;/*借助中間變量t進(jìn)行值互換*/}printf("排序后的數(shù)組:");for(i=0;i<n;i++){if(i%5==0)/*以每行5個(gè)元素的形式輸出*/printf("\n");printf("%5d",*(p+i));/*輸出數(shù)組中排序后的元素*/}printf("\n");}voidmain(){inta[20],i,n;printf("請(qǐng)輸入數(shù)組元素的個(gè)數(shù):\n");scanf("%d",&n);/*輸入數(shù)組元素的個(gè)數(shù)*/printf("請(qǐng)輸入各個(gè)元素:\n");for(i=0;i<n;i++)scanf("%d",a+i);/*給數(shù)組元素賦初值*/order(a,n);}/*調(diào)用order函數(shù)*6.5指針與函數(shù)拓展訓(xùn)練六:大福源超市的員工重新擺放水果區(qū)的水果,店長(zhǎng)要求按照水果名稱的升序進(jìn)行擺放,水果名稱及其單價(jià)如下:蘋果(apple)3.50元、橘子(tangerine)2.50元、柚子(grapefriu)3.00元、橙子(orange)2.99元、菠蘿(pineapple)4.99元、葡萄(grape)5.00元。編寫程序,按照水果英文名稱的首字母升序?qū)⑺敵觥?.5指針與函數(shù)二、返回指針值的函數(shù)一個(gè)函數(shù)可以返回一個(gè)整型值、字符值、實(shí)型值等,也可以返回指針型的數(shù)據(jù)(指針值),即地址,返回指針值的函數(shù)簡(jiǎn)稱為指針函數(shù)。定義指針函數(shù)的一般形式為:

類型名*函數(shù)名(參數(shù)列表)如:

int*max(intn)其中max是函數(shù)名,n是函數(shù)max的形參,函數(shù)名前面的*表示調(diào)用該函數(shù)后返回一個(gè)指向整型數(shù)據(jù)的指針(地址)。6.5指針與函數(shù)實(shí)例6-5-4:求長(zhǎng)方形的周長(zhǎng)。在本實(shí)例中輸入長(zhǎng)方形的長(zhǎng)、寬,計(jì)算長(zhǎng)方形的周長(zhǎng)。具體代碼如下:#include<stdio.h>intper(inta,intb);voidmain(){intiWidth,iLength,iResult;printf("請(qǐng)輸入長(zhǎng)方形的長(zhǎng):\n");scanf("%d",&iLength);printf("請(qǐng)輸入長(zhǎng)方形的寬:\n");scanf("%d",&iWidth);iResult=per(iWidth,iLength);printf("長(zhǎng)方形的周長(zhǎng)是:");printf("%d\n",iResult);}intper(inta,intb){

return(a+b)*2;}6.5指針與函數(shù)實(shí)例6-5-4中自定義了一個(gè)per函數(shù),用來(lái)求長(zhǎng)方形的面積。下面來(lái)看一下在實(shí)例6-5-4的基礎(chǔ)上如何使用返回值為指針的函數(shù)。#include<stdio.h>int*per(inta,intb);intperimeter;voidmain(){intiWidth,iLength;int*iresult;printf("請(qǐng)輸入長(zhǎng)方形的長(zhǎng):\n");scanf("%d",&iLength);printf("請(qǐng)輸入長(zhǎng)方形的寬:\n");scanf("%d",&iWidth);iresult=per(iWidth,iLength);printf("長(zhǎng)方形的周長(zhǎng)是:");printf("%d\n",*iresult);}int*per(inta,intb){int*p;p=&perimeter;perimeter=(a+b)*2;returnp;}程序中自定義了一個(gè)返回指針值的函數(shù):

int*per(intx,inty)該函數(shù)將指向存放著所求長(zhǎng)方形周長(zhǎng)的變量的指針值予以返回。注意:這個(gè)程序本身并不需要寫成這種形式,因?yàn)閷?duì)該問(wèn)題使用這種方式編寫程序并不簡(jiǎn)便。這樣寫只是為了講解如何使用返回值為指針的函數(shù)。6.5指針與函數(shù)實(shí)例6-5-5:求一維數(shù)組各元素中的最大值。#include<stdio.h>intmain(){int*p;

int*max(intn);/*聲明指針函數(shù)*/p=max(8);/*max函數(shù)返回最大值的地址*/

printf("最大值是:%d\n",*p);/*輸出最大值*/return0;}int*max(intn){/*定義指針函數(shù)*/staticinta[]={13,24,38,27,11,9,36,18};inti,m=0;for(i=1;i<n;i++)/*找最大值*/if(a[m]<a[i])m=i;/*m為最大值元素的下標(biāo)*/return&a[m];/*返回最大值元素的地址*/}6.5指針與函數(shù)拓展訓(xùn)練七:師徒二人合作生產(chǎn)一批零件,徒弟生產(chǎn)了9個(gè)零件,比師傅少生產(chǎn)21個(gè),計(jì)算這批零件一共有多少個(gè)?將求得的零件個(gè)數(shù)利用指針?lè)祷亍?.5指針與函數(shù)三、指向函數(shù)的指針函數(shù)和數(shù)組一樣,經(jīng)系統(tǒng)編譯后,其目標(biāo)代碼在內(nèi)存中連續(xù)存放,其名字本身就是一個(gè)地址,是函數(shù)的入口地址。C語(yǔ)言中,指針可以指向變量,也可以指向函數(shù)。指向函數(shù)的指針的定義格式為:類型名(*指針變量名)(參數(shù)表);其中,類型名是函數(shù)返回值的類型,參數(shù)表是函數(shù)指針?biāo)赶蚝瘮?shù)的所有形參。例如:int(*pc)(int,int);其中,pc為指向函數(shù)的指針,所指函數(shù)有兩個(gè)整型參數(shù),其返回值為整型,如果目標(biāo)函數(shù)沒(méi)有返回值,則定義格式為void(*pc)()。6.5指針與函數(shù)三、指向函數(shù)的指針定義了指向函數(shù)的指針以后,必須將一個(gè)函數(shù)名(函數(shù)的入口地址)賦給函數(shù)指針,然后才能用函數(shù)指針間接調(diào)用該函數(shù)。如:int(*pc)(int,int);/*定義指向函數(shù)的指針pc,限定pc所指函數(shù)有兩個(gè)整型參數(shù)*/intave(inta,intb);/*聲明有兩個(gè)整型參數(shù)的函數(shù)*/pc=ave;/*指針pc指向函數(shù)ave*/指向函數(shù)的指針對(duì)函數(shù)的調(diào)用格式如下:(*指針變量名)(實(shí)參表);如:(*pc)(a,b);/*調(diào)用pc所指函數(shù),a、b為實(shí)參*/6.5指針與函數(shù)實(shí)例6-5-6:指向函數(shù)的指針和指向函數(shù)的指針數(shù)組。#include<stdio.h>intmax(inta,intb)/*定義求最大值函數(shù)*/{returna>b?a:b;}intmin(inta,intb)/*定義求最小值函數(shù)*/{returna>b?b:a;}

intave(inta,intb)/*定義求平均值函數(shù)*/

{return(a+b)/2;}

voidmain()

{inta=10,b=15,c;int(*pc)(int,int);/*定義指向函數(shù)的指針pc,限定pc所指函數(shù)有兩個(gè)整型參數(shù)*/int(*p[2])();/*定義指向函數(shù)的指針數(shù)組p,不限定所指函數(shù)的參數(shù)*/pc=ave;/*pc指向ave函數(shù)*/p[0]=max;/*p[0]指向max函數(shù)*/p[1]=min;/*p[1]指向min函數(shù)*/c=(*pc)(a,b);/*調(diào)用pc所指函數(shù),需要給出實(shí)參*/printf("平均值是:%d\n",c);

c=(*p[0])(a,b);/*調(diào)用p[0]所指函數(shù),需要給出實(shí)參*/printf("最大值是:%d\n",c);

c=(*p[1])(a,b);/*調(diào)用p[1]所指函數(shù),需要給出實(shí)參*/printf("最小值是:%d\n",c);}6.5指針與函數(shù)提示:使用指向函數(shù)的指針調(diào)用函數(shù)與直接調(diào)用函數(shù)在效果上是相同的,只是多了一種調(diào)用函數(shù)的手段。指向函數(shù)的指針可以作為函數(shù)的形參。例如,下面root函數(shù)聲明的第三個(gè)形參即為指向函數(shù)的指針:doubleroot(doublea,doubleb,double(*f)(double))這樣就可以在調(diào)用root函數(shù)時(shí),把不同函數(shù)的入口地址傳遞給形參,從而在被調(diào)用的函數(shù)中使用實(shí)參函數(shù)。拓展訓(xùn)練八:利用指向函數(shù)的指針編寫程序,求出兩個(gè)數(shù)x、y中的最大值。6.6指向指針的指針和指針數(shù)組一、指向指針的指針一個(gè)指針變量可以指向整型變量、實(shí)型變量和字符類型變量,當(dāng)然也可以指向指針類型變量。當(dāng)指針變量用于指向指針類型變量時(shí),則稱之為指向指針的指針變量。這種雙重指針下圖所示。整型變量i的地址是&i,將其值傳遞給指針變量p1,則p1指向i;同時(shí),將p1的地址&p1傳遞給p2,則p2指向p1。這里的p2就是前面講到的指向指針變量的指針變量,即指針的指針。6.6指向指針的指針和指針數(shù)組指向指針的指針變量定義如下:

類型標(biāo)識(shí)符**指針變量名;例如:

int**p;其含義為定義一個(gè)指針變量p,它指向另一個(gè)指針變量,該指針變量又指向一個(gè)基本整型變量。由于指針運(yùn)算符*是自右至左結(jié)合的,所以上述定義相當(dāng)于:int*(*p);6.6指向指針的指針和指針數(shù)組實(shí)例6-6-1:輸出化學(xué)元素周期表中的前7個(gè)金屬元素。在本實(shí)例中,定義了一個(gè)指向指針的指針,利用這個(gè)指針將指針數(shù)組的元素輸出,具體代碼如下:#include<stdio.h>intmain(){inti;char

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論