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

下載本文檔

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

文檔簡介

模塊六

使用指針實現(xiàn)學生成績操作模塊學習目標1.理解和掌握指針的含義;2.掌握指針的定義、初始化和使用方法;3.了解指針和數(shù)組的關(guān)系。指針的相關(guān)概念指針與一維數(shù)組指針與二維數(shù)組指針與字符串指針與函數(shù)指向指針的指針和指針數(shù)組使用指針實現(xiàn)學生成績操作6.1指針的相關(guān)概念一、地址和指針系統(tǒng)的內(nèi)存就好比是帶有編號的房間,如果想使用內(nèi)存就需要得到房間編號。定義一個整型變量i,一個整型變量需要4個字節(jié),如果該變量的起始編號為1000,那么編譯器為該變量分配的編號為1000~1003。地址就是內(nèi)存區(qū)中對每個字節(jié)的編號,如1000、1001、1002和1003就是地址。C程序中所定義的每一個變量都會被分配若干個連續(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個字節(jié),所以變量j在內(nèi)存中的起始地址為1004。6.1指針的相關(guān)概念二、指針與指針變量指針就是某個對象所占用的內(nèi)存單元的首地址。例如,變量i的首地址1000就是變量i的指針。變量的地址就是變量和指針二者之間連接的紐帶,如果一個變量包含了另一個變量的地址,則可以理解成第一個變量指向第二個變量。存放變量地址的變量稱為指針變量,指針變量是指向一個變量的地址。指針變量與變量在內(nèi)存中的關(guān)系右圖所示:

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

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

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

inta;

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

inta;

int*p;

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

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

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

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

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

*a=*b;

*b=t;}

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

intx=10,y=5;

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

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

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

inta;

p=&a;“&*p”先進行“*”運算,“*p”相當于變量a,再進行“&”運算,“&*p”相當于取變量a的地址。“*&a”先進行“&”運算,“&a”就是取變量a的地址,然后執(zhí)行“*”運算,“*&a”相當于取變量a所在地址的值,實際就是變量a。6.1指針的相關(guān)概念實例6-1-3:輸出i、j、c的地址。本實例定義了3個指針變量i、j、c,計算“c=i+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)概念拓展訓練一:某工程隊修一條公路,第一天修600米,第二天修全長的20%,第三天修全長的25%,這三天共修全長的75%,求這條公路全長為多少米?編寫程序計算并輸出此公路總長變量的內(nèi)存地址。6.1指針的相關(guān)概念三、指針的自增自減運算指針的自增自減運算不同于普通變量的自增自減運算,也就是說并非簡單地加1或減1。例如:基本整型變量i在內(nèi)存中占4個字符,假設(shè)指針p是指向變量i的地址,那么p++不是簡單地在地址上加1,而是指向下一個存放基本整型變量的地址。6.1指針的相關(guān)概念實例6-1-4:指針自增。本實例定義一個指針變量,將這個指針進行自增運算,利用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并不代表一個字節(jié)*/printf("theresult2is:%d\n",p);}6.1指針的相關(guān)概念指針是按照它所指向的數(shù)據(jù)類型的直接長度進行增或減??梢詫嵗?-1-4用下圖表示6.1指針的相關(guān)概念拓展訓練二:

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

#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ù)組說明:(1)本實例中第5行和第6行的語句為:05p=&a[0];06q=b;以上這兩種表示方法都是將數(shù)組首地址賦給指針變量。(2)p+n與a+n表示數(shù)組元素a[n]的地址,即&a[n]。對數(shù)組a來說,共有5個元素,n的取值為0~4,則數(shù)組元素的地址就可以表示為p+0~p+4或a+0~a+4。(3)表示數(shù)組中的元素用到了前面介紹的數(shù)組元素的地址,用*(p+n)和*(a+n)來表示數(shù)組中的各元素。6.2指針與一維數(shù)組實例6-2-2中第15行的語句為:

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

19printf("%5d",*(q+i));上述兩條語句分別表示輸出數(shù)組a和數(shù)組b中對應(yīng)的元素。實例6-2-2中使用指針指向一維數(shù)組及通過指針引用數(shù)組元素的過程可以通過左圖和右圖來表示。6.2指針與一維數(shù)組在C語言中,可以用a+n表示數(shù)組元素的地址。*(a+n)表示數(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");程序運行的結(jié)果與實例6-2-2的運行結(jié)果相同。6.2指針與一維數(shù)組表示指針的移動可以使用“++”和“--”兩個運算符,利用“++”運算符可將程序的第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ù)組還可將實例6-2-2代碼再進一步改寫,運行結(jié)果仍相同,在上面修改后的基礎(chǔ)上修改實例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中的程序與實例6-2-2程序?qū)Ρ?,可以看出,如果在輸出?shù)組元素時需要使用指針變量,則需加上如下兩條語句:p=a;q=b;這兩條語句的作用是將指針變量p和q重新指向數(shù)組a和數(shù)組b在內(nèi)存中的起始位置。若沒有這兩條語句,而直接使用*p++的方法進行輸出,就會產(chǎn)生錯誤。拓展訓練三:使用指針尋找字符串“howareyou,andiamfine,doyouknow?”中“,”的位置。6.3指針與二維數(shù)組一、指針與二維數(shù)組的關(guān)系與一維數(shù)組相同,二維數(shù)組在內(nèi)存中也是連續(xù)存儲的。設(shè)有定義inta[3][3],假設(shè)a[0][0]的地址為2000,數(shù)組中各元素的首地址下圖所示??梢詮纳蠄D中看出,a數(shù)組中的元素從地址2000開始按照行的順序連續(xù)存放在內(nèi)存中。6.3指針與二維數(shù)組一、指針與二維數(shù)組的關(guān)系在C語言中,二維數(shù)組被看成一維數(shù)組的一維數(shù)組,二維數(shù)組的每一行都被看作是一個一維數(shù)組,其數(shù)組名分別為a[0]、a[1]和a[2],如下圖所示。6.3指針與二維數(shù)組二維數(shù)組名代表二維數(shù)組首元素的地址,由于二維數(shù)組的元素被看作為一維數(shù)組的一維數(shù)組,故數(shù)組a[3][3]可分解為3個一維數(shù)組,分別是a[0]、a[1]、a[2]。每一個一維數(shù)組又含有3個元素,如a[0]數(shù)組含有a[0][0]、a[0][1]、a[0][2]3個元素。數(shù)組及數(shù)組元素的地址表示如下:a是二維數(shù)組名,也是二維數(shù)組0行的首地址,等于2000。a[0]是第一個一維數(shù)組的數(shù)組名和首地址,因此也為2000。*(a+0)或*a是與a[0]等效的,它表示一維數(shù)組a[0]的0號元素的首地址,也為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]也是相等的,因為在二維數(shù)組中不能把&a[i]理解為元素a[i]的地址,所以不存在元素a[i]。另外,a[0]也可以看成是a[0]+0,是一維數(shù)組a[0]的0號元素的首地址,而a[0]+1則是a[0]的1號元素首地址,由此得出a[i]+j是一維數(shù)組a[i]的j號元素首地址,它等于&a[i][j]。6.3指針與二維數(shù)組實例6-3-1:用二維數(shù)組名的方式訪問a[1][2]的常見方式的具體實現(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ù)組的各個元素在內(nèi)存中是連續(xù)存放的,存放方式與一維數(shù)組并無區(qū)別,可以將二維數(shù)組當做一維數(shù)組進行處理,指針變量指向二維數(shù)組某元素的格式如下:指針變量名=&二維數(shù)組[行下標][列下標]指針變量名=*二維數(shù)組名指針變量名=二維數(shù)組[行下標]當行下標和列下標均為0時,指針變量指向二維數(shù)組首元素的地址,引用該數(shù)組元素的方法是:

*指針變量6.3指針與二維數(shù)組實例6-3-2:將輸入的數(shù)以二維數(shù)組顯示。輸入15個整型數(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ù)組拓展訓練四:某校班級有5×5個座位,輸出位置最好的一行座位號。(提示:第2行最受歡迎)6.3指針與二維數(shù)組三、指向二維數(shù)組的行指針變量由于二維數(shù)組的每一行都被視為一個一維數(shù)組,所以可以定義一個指針來指向每一行的一維數(shù)組,則行指針變量是指向一行數(shù)組元素的起始地址。聲明行指針變量的一般格式為:類型名(*指針變量名)[n]其中:類型名為指針變量名所指向數(shù)組的數(shù)據(jù)類型。n表示由一個二維數(shù)組分解為多個一維數(shù)組的長度,也就是所指向的二維數(shù)組的列數(shù)。格式中,()、*和[n]都不可省略。注意:行指針變量用于指向一行數(shù)組元素的起始地址,而非數(shù)組中的元素。定義行指針變量以后,只要將二維數(shù)組的首地址賦給行指針變量,則行指針變量就與二維數(shù)組建立了聯(lián)系,二維數(shù)組也就成為行指針變量指向的對象。此時,就可以用指針法訪問該二維數(shù)組的元素了。6.3指針與二維數(shù)組實例6-3-3:行指針變量訪問二維數(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));/*可以在此處替換訪問a[i][j]的方式*/printf("\n");return0;}6.3指針與二維數(shù)組實例6-3-4:將停車場的第2行停車號輸出。某停車場有3×3個停車位,利用指針將第2行的停車號輸出,具體代碼如下:

#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ù)組實例6-3-5:求每個學生的總分與平均成績。有5名學生,每人有3門考試成績,計算每個學生的總分與平均成績。查找有1門及1門以上課程不及格的學生,并輸出這些學生的全部課程成績。#include<stdio.h>average(intstudent[5][6]){inti,j;printf("學號數(shù)學英語計算機總分平均分\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)/*查找成績不及格學生函數(shù)*/{inti,j,flag;printf("\n有一門以上課程成績不及格的學生如下:\n");for(i=0;i<n;i++)/*n=5,對5個學生3門課程進行查找*/{flag=0;/*用flag標記,若成績<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個數(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)用查找并輸出有成績不及格學生的函數(shù)*/return0;}6.4指針與字符串一、字符串與字符指針字符串操作是數(shù)據(jù)處理中常見的操作。在C語言中,可以使用字符指針來操作字符串,相比使用字符數(shù)組操作字符串,前者更加便利。在C語言中,字符串有兩種表示方式:字符數(shù)組或字符指針。字符數(shù)組的表示方式如下:

charstr[]="VisualC++2010";

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

char*str="hello";

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

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

char*str;

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

charstr[10];

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

char*str;

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

charstr[10];

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

chara[10],*str=a;

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

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

str=a+2;

puts(str);

str=str+9;

puts(str);

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

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

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

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

#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指針與字符串拓展訓練五:小學六年級英語期末考試,有一題是根據(jù)漢語填寫英語,漢語題目是語文、數(shù)學、英語、化學、生物、物理,填寫的英語分別為Chinese、Math、English、Chemistry、Biology、Physics,請用字符串數(shù)組輸出填寫的英文。6.5指針與函數(shù)一、指針作函數(shù)的參數(shù)指針作為函數(shù)的形參時,在形參說明時需要使用格式“類型名*指針名”。*號不能省略,而在函數(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ù)說明:在main函數(shù)中調(diào)用函數(shù)changeA時,將實參pa的值傳遞給形參p,p和pa都指向變量a,*p=*p+*p等價于a=a+a,結(jié)果是將a的值修改為20,然后p指向b。分析程序運行結(jié)果的第一行和第三行可以知道,在函數(shù)內(nèi)通過p訪問a的操作改變了函數(shù)外變量a的值;分析程序運行結(jié)果的第二行和第三行可以知道,函數(shù)內(nèi)對p的操作,與函數(shù)外的變量pa無關(guān)。運行結(jié)果中的pa和p的值在不同的C語言編譯器中可能會有所不同。第二行代碼“voidchangeA(int*)”的作用是函數(shù)聲明,其中*號不能省略,它的作用是說明changeA函數(shù)的形參為int類型的指針變量。指針作為函數(shù)參數(shù),在被定義、聲明和調(diào)用時,數(shù)據(jù)類型都必須一致,如果不一致,編譯就會報錯。指針作為函數(shù)的形參時,函數(shù)中可以修改指針所指向的對象,利用這個特性,一個函數(shù)可以獲得多個返回值,只要在定義這個函數(shù)時使用多個指針變量作為形參即可。6.5指針與函數(shù)實例6-5-2:將輸入的3個數(shù)從大到小輸出。本實例使用嵌套函數(shù)實現(xiàn)相關(guān)功能,在定義的排序函數(shù)中嵌套了自定義交換函數(shù),實現(xiàn)了數(shù)據(jù)按從大到小進行排序的功能,具體代碼如下:#include<stdio.h>voidswap(int*p1,int*p2)/*自定義交換函數(shù)*/{inttemp;temp=*p1;*p1=*p2;*p2=temp;}voidexchange(int*pt1,int*pt2,int*pt3)/*3個數(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ù)從該實例代碼和運行結(jié)果可以看出:(1)程序創(chuàng)建了一個自定義函數(shù)swap,用于實現(xiàn)交換兩個變量的值;還創(chuàng)建了一個exchange函數(shù),其作用是將3個數(shù)由大到小排序,在exchange函數(shù)中還調(diào)用了前面自定義的swap函數(shù),這里的swap和exchange函數(shù)都是以指針變量作為形式參數(shù)的。(2)程序運行時,通過鍵盤輸入3個數(shù)并保存在變量a、b、c中,分別將a、b、c的地址賦予q1、q2、q3,調(diào)用exchange函數(shù),將指針變量作為實際參數(shù),將實際參數(shù)變量的值傳遞給形式參數(shù)變量,此時q1和pt1都指向變量a,q2和pt2都指向變量b,q3和pt3都指向變量c,在exchange函數(shù)中又調(diào)用了swap函數(shù),當執(zhí)行swap(pt1,pt2)時,pt1也指向了變量a,pt2也指向了變量b。6.5指針與函數(shù)實例6-5-3:使用指針實現(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))/*判斷相鄰兩個元素的大小*/{t=*(p+j);*(p+j)=*(p+j+1);*(p+j+1)=t;/*借助中間變量t進行值互換*/}printf("排序后的數(shù)組:");for(i=0;i<n;i++){if(i%5==0)/*以每行5個元素的形式輸出*/printf("\n");printf("%5d",*(p+i));/*輸出數(shù)組中排序后的元素*/}printf("\n");}voidmain(){inta[20],i,n;printf("請輸入數(shù)組元素的個數(shù):\n");scanf("%d",&n);/*輸入數(shù)組元素的個數(shù)*/printf("請輸入各個元素:\n");for(i=0;i<n;i++)scanf("%d",a+i);/*給數(shù)組元素賦初值*/order(a,n);}/*調(diào)用order函數(shù)*6.5指針與函數(shù)拓展訓練六:大福源超市的員工重新擺放水果區(qū)的水果,店長要求按照水果名稱的升序進行擺放,水果名稱及其單價如下:蘋果(apple)3.50元、橘子(tangerine)2.50元、柚子(grapefriu)3.00元、橙子(orange)2.99元、菠蘿(pineapple)4.99元、葡萄(grape)5.00元。編寫程序,按照水果英文名稱的首字母升序?qū)⑺敵觥?.5指針與函數(shù)二、返回指針值的函數(shù)一個函數(shù)可以返回一個整型值、字符值、實型值等,也可以返回指針型的數(shù)據(jù)(指針值),即地址,返回指針值的函數(shù)簡稱為指針函數(shù)。定義指針函數(shù)的一般形式為:

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

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

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

int*per(intx,inty)該函數(shù)將指向存放著所求長方形周長的變量的指針值予以返回。注意:這個程序本身并不需要寫成這種形式,因為對該問題使用這種方式編寫程序并不簡便。這樣寫只是為了講解如何使用返回值為指針的函數(shù)。6.5指針與函數(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為最大值元素的下標*/return&a[m];/*返回最大值元素的地址*/}6.5指針與函數(shù)拓展訓練七:師徒二人合作生產(chǎn)一批零件,徒弟生產(chǎn)了9個零件,比師傅少生產(chǎn)21個,計算這批零件一共有多少個?將求得的零件個數(shù)利用指針返回。6.5指針與函數(shù)三、指向函數(shù)的指針函數(shù)和數(shù)組一樣,經(jīng)系統(tǒng)編譯后,其目標代碼在內(nèi)存中連續(xù)存放,其名字本身就是一個地址,是函數(shù)的入口地址。C語言中,指針可以指向變量,也可以指向函數(shù)。指向函數(shù)的指針的定義格式為:類型名(*指針變量名)(參數(shù)表);其中,類型名是函數(shù)返回值的類型,參數(shù)表是函數(shù)指針所指向函數(shù)的所有形參。例如:int(*pc)(int,int);其中,pc為指向函數(shù)的指針,所指函數(shù)有兩個整型參數(shù),其返回值為整型,如果目標函數(shù)沒有返回值,則定義格式為void(*pc)()。6.5指針與函數(shù)三、指向函數(shù)的指針定義了指向函數(shù)的指針以后,必須將一個函數(shù)名(函數(shù)的入口地址)賦給函數(shù)指針,然后才能用函數(shù)指針間接調(diào)用該函數(shù)。如:int(*pc)(int,int);/*定義指向函數(shù)的指針pc,限定pc所指函數(shù)有兩個整型參數(shù)*/intave(inta,intb);/*聲明有兩個整型參數(shù)的函數(shù)*/pc=ave;/*指針pc指向函數(shù)ave*/指向函數(shù)的指針對函數(shù)的調(diào)用格式如下:(*指針變量名)(實參表);如:(*pc)(a,b);/*調(diào)用pc所指函數(shù),a、b為實參*/6.5指針與函數(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ù)有兩個整型參數(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ù),需要給出實參*/printf("平均值是:%d\n",c);

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

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

類型標識符**指針變量名;例如:

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

溫馨提示

  • 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論