版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
指針
促成教學(xué)目標(biāo):1、能正確理解各種類(lèi)型的指針變量的定義;2、掌握指針變量的引用方法,理解指針變量運(yùn)算的含義;3、學(xué)會(huì)使用指針數(shù)組和指向指針的指針;4、靈活運(yùn)用指針作函數(shù)參數(shù)和返回值。8.1任務(wù)1用指針實(shí)現(xiàn)學(xué)生最高、最低等成績(jī)查找任務(wù)目標(biāo):能用指針實(shí)現(xiàn)學(xué)生最高、最低等成績(jī)查找。
8.1.1任務(wù)情境
8.1.2知識(shí)必備
8.1.3任務(wù)實(shí)施
8.1.4知識(shí)擴(kuò)展任務(wù)小結(jié)8.1.1任務(wù)情境
“指針”中的數(shù)據(jù)有指針和指針變量,指針變量的定義,賦值及其運(yùn)算,指針變量作為函數(shù)參數(shù)的用法,指針數(shù)組與字符串,指針與函數(shù)。
“班級(jí)學(xué)生成績(jī)管理系統(tǒng)”查找最高分、最低分和不及格成績(jī)的3個(gè)函數(shù)也可以用指針變量做參數(shù)來(lái)實(shí)現(xiàn)。指針可以說(shuō)是c語(yǔ)言的精華。
下面我們通過(guò)相關(guān)理論的學(xué)習(xí),掌握如何用指針將“學(xué)生最高、最低等成績(jī)查找”中的數(shù)據(jù)進(jìn)行相關(guān)設(shè)計(jì)。8.1.2知識(shí)必備
【例8_1】從10個(gè)數(shù)中找出其中最大值和最小值。程序代碼如下:010203040506070809101112131415161718intmax,min;/*全局變量*/voidmax_min_value(intarray[],intn){int*p,*array_end;array_end=array+n;max=min=*array;for(p=array+1;p<array_end;p++)if(*p>max)max=*p;elseif(*p<min)min=*p;return;}main(){inti,number[10];printf("enter10integerumbers:\n");for(i=0;i<10;i++)scanf("%d",&number[i]);max_min_value(number,10);printf("\nmax=%d,min=%d\n",max,min);}代碼貼士
調(diào)用一個(gè)函數(shù)只能得到一個(gè)返回值,用全局變量在函數(shù)之間“傳遞”數(shù)據(jù)。8.1.2知識(shí)必備
指針變量
通過(guò)實(shí)例分析,我們已經(jīng)看到程序中使用指針變量存放變量的地址、指針變量的初始化、及引用。
指針變量的定義指針變量的初始化指針變量的引用8.1.2知識(shí)必備
(1.1)指針變量的定義:
其一般形式為:
類(lèi)型說(shuō)明符*變量名;
其中,*表示這是一個(gè)指針變量,變量名即為定義的指針變量名,類(lèi)型說(shuō)明符表示本指針變量所指向的變量的數(shù)據(jù)類(lèi)型。
例如:int*p1;
表示p1是一個(gè)指針變量,它的值是某個(gè)整型變量的地址?;蛘哒f(shuō)p1指向一個(gè)整型變量。至于p1究竟指向哪一個(gè)整型變量,應(yīng)由向p1賦予的地址來(lái)決定。8.1.2知識(shí)必備
(1.2)指針變量的初始化:
先來(lái)介紹兩個(gè)有關(guān)的運(yùn)算符:
兩個(gè)有關(guān)的運(yùn)算符:
&:取地址運(yùn)算符。/*使用方法:&變量名*/*:指針運(yùn)算符。/*使用方法:*表示指針變量名*/
地址運(yùn)算符”&”來(lái)表示取變量的地址,實(shí)際上是變量的起始地址。指針運(yùn)算符“*”表示取指針變量所對(duì)應(yīng)內(nèi)在單元的值。
初始化的一般形式為:
數(shù)據(jù)類(lèi)型名:*變量名=初始地址值;
例如:
inta;charc;int*pa=&a;char*pc=&c;8.1.2知識(shí)必備
(1.3)指針變量的引用:
在定義了一個(gè)指針變量并確定了其指向后,就可以用來(lái)訪問(wèn)所指向的變量。
引用指針變量的一般形式為:*指針變量名
這里的星號(hào)(*)稱(chēng)為指針運(yùn)算符,也稱(chēng)作間接訪問(wèn)運(yùn)算符。
【例8.2】引用輸出兩個(gè)數(shù)的值。
程序代碼如下:010203040506070809main(){inta,b;int*pointer_1,*pointer_2;a=100;b=10;pointer_1=&a;pointer_2=&b;printf("%d,%d\n",a,b);printf("%d,%d\n",*pointer_1,*pointer_2);}代碼貼士
在開(kāi)頭處雖然定義了兩個(gè)指針變量pointer_1和pointer_2,擔(dān)它們并未指向任何一個(gè)整型變量。只是提供兩個(gè)指針變量,規(guī)定它們可以指向整型變量。程序第5、6行的作用就是使pointer_1指向a,pointer_2指向b。最后一行的*pointer_1和*pointer_2就是變量a和b。最后兩個(gè)printf函數(shù)作用是相同的。8.1.2知識(shí)必備
2.指針與函數(shù)函數(shù)的參數(shù)不僅可以是整型、實(shí)型、字符型等數(shù)據(jù),還可以是指針類(lèi)型。它的作用是將一個(gè)變量的地址傳送到另一個(gè)函數(shù)中。8.1.2知識(shí)必備
【例8.3】輸入a、b、兩個(gè)整數(shù),按先大后小的順序輸出。
程序代碼如下:01020304050607080910#include<stdio.h>main(){int*p1,*p2,*P,a,b;Scanf(“%d,%d”,”&a,&b”);P1=&a;p2=&b;If(a<b){p=p1;p1=p2;p2=p;}Printf(“a=%d,b=%d\n\n”,a,b);Printf(“max=%d,min=%d\n”,*p1,*p2);}
代碼貼士
該程序中,當(dāng)輸入a=5,b=9時(shí),由于a<b,將p1和p2進(jìn)行.交換,實(shí)際上a和b并未交換,它們?nèi)员3衷?,p1和p2的值改變了。P1的值原為&a,后來(lái)為&b,p2原值為&b,后來(lái)變成&a。這樣在輸出*p1和*p2時(shí),實(shí)際上是輸出變量b和a的值。8.1.2知識(shí)必備
3.指針與數(shù)組
一個(gè)變量有一個(gè)地址,一個(gè)數(shù)組包含若干元素,每個(gè)數(shù)組元素都在內(nèi)存中占用存儲(chǔ)單元,它們都有相應(yīng)的地址。所謂數(shù)組的指針是指數(shù)組的起始地址,數(shù)組元素的指針是數(shù)組元素的地址。
指向數(shù)組元素的指針;通過(guò)指針引用數(shù)組元素;數(shù)組名做函數(shù)參數(shù);指向多數(shù)組的指針和指針變量;8.1.2知識(shí)必備
(3.1)指向數(shù)組元素的指針
一個(gè)數(shù)組是由連續(xù)的一塊內(nèi)存單元組成的。數(shù)組名就是這塊連續(xù)內(nèi)存單元的首地址。一個(gè)數(shù)組也是由各個(gè)數(shù)組元素(下標(biāo)變量)組成的。每個(gè)數(shù)組元素按其類(lèi)型不同占有幾個(gè)連續(xù)的內(nèi)存單元。一個(gè)數(shù)組元素的首地址也是指它所占有的幾個(gè)內(nèi)存單元的首地址。
例如:
inta[10];/*定義a為包含10個(gè)整型數(shù)據(jù)的數(shù)組*/int*p;/*定義p為指向整型變量的指針*/
應(yīng)當(dāng)注意,因?yàn)閿?shù)組為int型,所以指針變量也應(yīng)為指向int型的指針變量。下面是對(duì)指針變量賦值:
p=&a[0];8.1.2知識(shí)必備把a(bǔ)[0]元素的地址賦給指針變量p。也就是說(shuō),p指向a數(shù)組的第0號(hào)元素。C語(yǔ)言規(guī)定,數(shù)組名代表數(shù)組的首地址,也就是第0號(hào)元素的地址。因此,下面兩個(gè)語(yǔ)句等價(jià):p=&a[0];p=a;在定義指針變量時(shí)可以賦給初值:int*p=&a[0];它等效于:int*p;p=&a[0];當(dāng)然定義時(shí)也可以寫(xiě)成:
int*p=a;:8.1.2知識(shí)必備從右圖8-1中我們可以看出有以下關(guān)系:
p,a,&a[0]均指向同一單元,它們是數(shù)組a的首地址,也是0號(hào)元素a[0]的首地址。應(yīng)該說(shuō)明的是p是變量,而a,&a[0]都是
常量。在編程時(shí)應(yīng)予以注意。數(shù)組指針變量說(shuō)明的一般形式為:類(lèi)型說(shuō)明符*指針變量名;
其中類(lèi)型說(shuō)明符表示所指數(shù)組的類(lèi)型。從一般形式可以看出指向數(shù)組的指針變量和指向普通變量的指針變量的說(shuō)明是相同的。圖8-18.1.2知識(shí)必備
(3.2)通過(guò)指針引用數(shù)組元素
C語(yǔ)言規(guī)定:如果指針變量p已指向數(shù)組中的一個(gè)元素,則p+1指向同一數(shù)組中的下一個(gè)元素。
引入指針變量后,就可以用兩種方法來(lái)訪問(wèn)數(shù)組元素了。
如果p的初值為&a[0],則:
p+i和a+i就是a[i]的地址,或者說(shuō)它們指向
a數(shù)組的第i個(gè)元素。如右圖8-2所示:
*(p+i)或*(a+i)就是p+i或a+i所指向的數(shù)組元素,即a[i]。例如,*(p+5)或*(a+5)就是a[5]。
指向數(shù)組的指針變量也可以帶下標(biāo),如p[i]與
*(p+i)等價(jià)。圖8-28.1.2知識(shí)必備根據(jù)以上敘述,引用一個(gè)數(shù)組元素可以用:下標(biāo)法,即用a[i]形式訪問(wèn)數(shù)組元素。在前面介紹數(shù)組時(shí)都是采用這種方法。指針?lè)?,即采?(a+i)或*(p+i)形式,用間接訪問(wèn)的方法來(lái)訪問(wèn)數(shù)組元素,其中a是數(shù)組名,p是指向數(shù)組的指針變量,其處值p=a。
8.1.2知識(shí)必備
【例8.4】輸出數(shù)組中的全部元素。
程序代碼如下:010203040506inta[10],i;for(i=0;i<10;i++)a[i]=i;for(i=0;i<5;i++)printf("a[%d]=%d\n",i,a[i]);}代碼貼士輸出數(shù)組中的全部元素
8.1.2知識(shí)必備
(3.3)數(shù)組名做函數(shù)參數(shù)數(shù)組名可以作函數(shù)的實(shí)參和形參。如:main(){intarray[10];…………f(array,10);…………}f(intarr[],intn);{…………}
8.1.2知識(shí)必備
array為實(shí)參數(shù)組名,arr為形參數(shù)組名。數(shù)組名就是數(shù)組的首地址,實(shí)參向形參傳送數(shù)組名實(shí)際上就是傳送數(shù)組的地址,形參得到該地址后也指向同一數(shù)組如圖8-3所示。
圖8-3
同樣,指針變量的值也是地址,數(shù)組指針變量的值即為數(shù)組的首地址,當(dāng)然也可作為函數(shù)的參數(shù)使用。8.1.2知識(shí)必備
【例8.5】將數(shù)組a中的n個(gè)整數(shù)按相反順序存放。
程序代碼如下:0102030405060708091011121314151617181920voidinv(intx[],intn)/*形參x是數(shù)組名*/{inttemp,i,j,m=(n-1)/2;for(i=0;i<=m;i++){j=n-1-i;temp=x[i];x[i]=x[j];x[j]=temp;}return;}main(){inti,a[10]={3,7,9,11,0,6,7,5,4,2};printf("Theoriginalarray:\n");for(i=0;i<10;i++)printf("%d,",a[i]);printf("\n");inv(a,10);printf("Thearrayhasbenninverted:\n");for(i=0;i<10;i++)printf("%d,",a[i]);printf("\n");}代碼貼士
將a[0]與a[n-1]對(duì)換,再a[1]與a[n-2]對(duì)換……,直到將a[(n-1/2)]與a[n-int((n-1)/2)]對(duì)換。今用循環(huán)處理此問(wèn)題,設(shè)兩個(gè)“位置指示變量”i和j,i的初值為0,j的初值為n-1。將a[i]與a[j]交換,然后使i的值加1,j的值減1,再將a[i]與a[j]交換,直到i=(n-1)/2為止(如圖8—4)所示8.1.2知識(shí)必備如圖8-4所示:圖8-48.1.2知識(shí)必備
(3.4)指向多數(shù)組的指針和指針變量本小節(jié)以二維數(shù)組為例介紹多維數(shù)組的指針變量。多維數(shù)組的地址設(shè)有整型二維數(shù)組a[3][4]如下:
01234567891011
它的定義為:
inta[3][4]={{0,1,2,3},{4,5,6,7},{8,9,10,11}}設(shè)數(shù)組a的首地址為1000,各下標(biāo)變量的首地址及其值。如圖8-5所示:圖8-58.1.2知識(shí)必備
前面介紹過(guò),C語(yǔ)言允許把一個(gè)二維數(shù)組分解為多個(gè)一維數(shù)組來(lái)處理。因此數(shù)組a可分解為三個(gè)一維數(shù)組,即a[0],a[1],a[2]。每一個(gè)一維數(shù)組又含有四個(gè)元素。如圖8-6所示:
例如a[0]數(shù)組,含有a[0][0],a[0][1],a[0][2],a[0][3]四個(gè)元素。圖8-68.1.2知識(shí)必備
前面介紹過(guò),C語(yǔ)言允許把一個(gè)二維數(shù)組分解為多個(gè)一維數(shù)組來(lái)處理。因此數(shù)組a可分解為三個(gè)一維數(shù)組,即a[0],a[1],a[2]。每一個(gè)一維數(shù)組又含有四個(gè)元素。如圖8-6所示:圖8-6例如a[0]數(shù)組,含有a[0][0],a[0][1],a[0][2],a[0][3]四個(gè)元素。8.1.2知識(shí)必備
數(shù)組及數(shù)組元素的地址表示如下:從二維數(shù)組的角度來(lái)看,a是二維數(shù)組名,a代表整個(gè)二維數(shù)組的首地址,也是二維數(shù)組0行的首地址,等于1000。a+1代表第一行的首地址,等于1008。如圖8-7所示:圖8-7
a[0]是第一個(gè)一維數(shù)組的數(shù)組名和首地址,因此也為1000。*(a+0)或*a是與a[0]等效的,它表示一維數(shù)組a[0]0號(hào)元素的首地址,也為1000。&a[0][0]是二維數(shù)組a的0行0列元素首地址,同樣是1000。因此,a,a[0],*(a+0),*a,&a[0][0]是相等的。8.1.2知識(shí)必備
同理,a+1是二維數(shù)組1行的首地址,等于1008。a[1]是第二個(gè)一維數(shù)組的數(shù)組名和首地址,因此也為1008。&a[1][0]是二維數(shù)組a的1行0列元素地址,也是1008。因此a+1,a[1],*(a+1),&a[1][0]是等同的。
由此可得出:a+i,a[i],*(a+i),&a[i][0]是等同的。此外,&a[i]和a[i]也是等同的。因?yàn)樵诙S數(shù)組中不能把&a[i]理解為元素a[i]的地址,不存在元素a[i]。C語(yǔ)言規(guī)定,它是一種地址計(jì)算方法,表示數(shù)組a第i行首地址。由此,我們得出:a[i],&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)元素首地址,(如圖8-8所示)由此可得出a[i]+j則是一維數(shù)組a[i]的j號(hào)元素首地址,它等于&a[i][j]。圖8-8由a[i]=*(a+i)得a[i]+j=*(a+i)+j。由于*(a+i)+j是二維數(shù)組a的i行j列元素的首地址,所以,該元素的值等于*(*(a+i)+j)。8.1.2知識(shí)必備
【例8.6】通過(guò)二維數(shù)組輸出相應(yīng)的值。程序代碼如下:010203040506070809main(){inta[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};int(*p)[4];inti,j;p=a;for(i=0;i<3;i++) {for(j=0;j<4;j++)printf("%2d",*(*(p+i)+j)); printf("\n");}}代碼貼士通過(guò)循環(huán)輸出p+i+j的值8.1.3任務(wù)實(shí)施
任務(wù)1給出的“班級(jí)學(xué)生成績(jī)管理系統(tǒng)”查找最高分、最低分和不及格成績(jī)的3個(gè)函數(shù)也可以用指針變量做參數(shù)來(lái)實(shí)現(xiàn)。下面給出的這二個(gè)函數(shù),只將原函數(shù)中的數(shù)組形參修改成指針形參,函數(shù)按指針訪問(wèn)方式編寫(xiě)。(1)
函數(shù)聲明可修改成:voidSearchMax(float*,int);//查找最高分指針訪問(wèn)函數(shù)voidSearchMin(float*,int);//查找最低分指針訪問(wèn)函數(shù)(2)
函數(shù)調(diào)用可以不修改。(3)
函數(shù)定義修改成:8.1.3任務(wù)實(shí)施
查找最高分指針訪問(wèn)函數(shù):程序代碼如下:01020304050607080910111213141516171819voidSearchMax(float*pscore,intstusize)//查找最高分指針訪問(wèn)函數(shù){floatmax=*pscore;inti,flag;system("cls");for(i=1;i<stusize;i++){ if(max<*(pscore+i)) { max=*(pscore+i); flag=i; }}gotoxy(20,5);printf("成績(jī)最高的是:%.1f\n",*(pscore+flag));gotoxy(20,10);printf("查找最高分成功,按任意鍵返回上級(jí)菜單!");getch();}代碼貼士
查找最高分指針訪問(wèn)函數(shù)
8.1.3任務(wù)實(shí)施
查找不合格學(xué)生成績(jī)指針訪問(wèn)函數(shù):程序代碼如下:01020304050607080910111213141516171819voidNotElig(float*pscore,intstusize)//查找不合格學(xué)生成績(jī)指針訪問(wèn)函數(shù){inti,flag=0;system("cls");gotoxy(20,5);printf("不合格成績(jī):");for(i=0;i<stusize;i++){if(*(pscore+i)<60){ printf("%6.1f",*(pscore+i)); flag=1; }}if(!flag){gotoxy(35,5); printf("沒(méi)有不合格成績(jī)!");}
8.1.3任務(wù)實(shí)施
2021222324gotoxy(20,10);printf("查找不合格成績(jī)成功,按任意鍵返回上級(jí)菜單!");getch(); }
代碼貼士查找不合格學(xué)生成績(jī)指針訪問(wèn)函數(shù)8.1.4知識(shí)擴(kuò)展
一維數(shù)組元素的指針訪問(wèn)方式:
一維數(shù)組的數(shù)組名實(shí)際上就是指向該數(shù)組的第一個(gè)單元的指針。一個(gè)一維數(shù)組若定義為:inta[10];
則數(shù)組名a的類(lèi)型是int*(數(shù)組名代表數(shù)組的首地址,因此是指針類(lèi)型),并且指向第一個(gè)元素;因此*a和a[0]訪問(wèn)的是同一個(gè)元素,兩種表達(dá)形式完全等價(jià),這種地址表達(dá)形式不僅可以訪問(wèn)第一個(gè)元素,結(jié)合算術(shù)運(yùn)算還可以訪問(wèn)數(shù)組的其他元素。例如:*(a+1)等價(jià)于a[1];*(a+2)等價(jià)于a[2];……*(a+i)等價(jià)于a[i]。
因此,訪問(wèn)數(shù)組元素的操作可以采用三種方法,一種叫下標(biāo)法,一種叫地址法,還有一種叫指針?lè)?。采用指針?lè)ū炔捎玫刂贩ǜ鼮楹?jiǎn)潔,執(zhí)行效率也更高。指向一維數(shù)組第一個(gè)元素的指針都可以像一維數(shù)組名那樣使用,例如:inta[10],*pa=a;*(pa+1)等價(jià)于a[1];*(pa+2)等價(jià)于a[2];……*(pa+i)等價(jià)于a[i]。8.1.4知識(shí)擴(kuò)展
下標(biāo)法與地址法、下標(biāo)法與指針?lè)ǖ膶?duì)應(yīng)關(guān)系如圖8-9所示。圖8-98.1.4知識(shí)擴(kuò)展
三種訪問(wèn)方式在形式上遵守下面的等價(jià)關(guān)系如圖8-10所示:a[i]*(a+i)特別是當(dāng)i等于0時(shí):a[0]*(a+0)*aa[i]*(pa+i)特別是當(dāng)i等于0時(shí):a[0]*(pa+0)*pa或圖8-10如:inta[5]={7,9,4,3,8};
int*pa=a;
printf(“%d”,a[0]);printf(“%d\n”,a[2]);printf(“%d”*a);printf(“%d\n”,*(a+2));printf(“%d”,*pa);printf(“%d\n”,*(pa+2));執(zhí)行結(jié)果:7474748.1.4知識(shí)擴(kuò)展
指針變量還可以用自增或自減運(yùn)算來(lái)改變指針?biāo)赶虻奈恢?,達(dá)到移動(dòng)指針的目的如圖8-11所示。printf(“%d”,*(pa++));printf(“%d”,*(++pa));printf(“%d”,*(pa--));printf(“%d”,*(--pa));圖8-11同學(xué)們想一想能否實(shí)現(xiàn):printf(?°%d?±,*(a++));printf(?°%d?±,*(a--));或printf(?°%d?±,*(++a));printf(?°%d?±,*(--a));8.1.4知識(shí)擴(kuò)展
【例8.7】輸出數(shù)組的全部元素(幾種訪問(wèn)方法比較):
程序代碼如下:
方法一:下標(biāo)法010203040506070809main(){inta[5]={1,2,3,4,5};inti;for(i=0;i<5;i++)printf("%d,",a[i]);printf("\n");}代碼貼士
用下標(biāo)法輸出數(shù)組的全部元素
8.1.4知識(shí)擴(kuò)展
方法二:地址法010203040506070809main(){inta[10]={1,2,3,4,5};
inti;
for(i=0;i<5;i++)printf("%d,",*(a+i));
printf("\n");}代碼貼士
用地址法輸出數(shù)組的全部元素
8.1.4知識(shí)擴(kuò)展
方法三:指針?lè)?10203040506070809main(){inta[10]={1,2,3,4,5};
int*p;
for(p=a;p<a+5;p++)printf("%d,",*p);
printf("\n");}代碼貼士
用指針?lè)ㄝ敵鰯?shù)組的全部元素
三種方法的輸出結(jié)果都是:1,2,3,4,5,8.1.4知識(shí)擴(kuò)展
【例8.8】下面的程序的輸出結(jié)果是什么?
程序代碼如下:
方法三:指針?lè)?10203040506070809101112#include<stdio.h>voidmain(){inta[10],*p,i;p=a;for(i=0;i<10;i++)scanf("%d",p++);/*特別要注意輸入時(shí)指針的變化*/printf("\n");for(i=0;i<10;i++,p++)/*指針p的值已經(jīng)變化*/printf("%d",*p);}代碼貼士
程序運(yùn)行結(jié)果:1234567890<回車(chē)>輸出結(jié)果不是預(yù)期的值??!
8.1.4知識(shí)擴(kuò)展
怎樣解決?其實(shí)很簡(jiǎn)單:重新使指針變量指向數(shù)組的首地址,請(qǐng)看改進(jìn)后的例子。
0102030405060708091011121314#include<stdio.h>voidmain(){inta[10],*p,i;p=a;for(i=0;i<10;i++)scanf("%d",p++);printf("\n");p=a;/*使p指針重新指向了數(shù)組的首地址*/for(i=0;i<10;i++,p++)printf("%d",*p);printf("\n");}代碼貼士
程序運(yùn)行結(jié)果:1234567890<回車(chē)>1234567890
8.1.4知識(shí)擴(kuò)展
當(dāng)執(zhí)行到第6-7兩行時(shí),隨著循環(huán)的執(zhí)行,指針p的指向在不斷的變化,循環(huán)結(jié)束后,指針p已指向數(shù)組的外面了,如果這時(shí)直接用指針來(lái)實(shí)現(xiàn)輸出其值的操作,指針指向的就不是數(shù)組的值,而是數(shù)組外面的內(nèi)容,輸出結(jié)果就不是預(yù)期的值。如果在輸出之前調(diào)整指針p的指向,使它重新指向數(shù)組的首地址,增加第9行p=a;語(yǔ)句,再輸出,就能得到預(yù)期的結(jié)果。任務(wù)小結(jié)
指針是c語(yǔ)言與數(shù)據(jù)結(jié)構(gòu)中的一個(gè)重要的組成部分,是學(xué)習(xí)后面知識(shí)的基礎(chǔ)。任務(wù)一主要介紹一下幾方面的內(nèi)容。(1)指針就是內(nèi)存地址,指針變量是一個(gè)特殊的變量,是專(zhuān)門(mén)用來(lái)存放內(nèi)存地址的。在定義一個(gè)指針變量時(shí),將其初始化為空,可以避免造成系統(tǒng)混亂指針變量的運(yùn)算(2)取地址運(yùn)算符&,取變量的地址(3)取內(nèi)容運(yùn)算符*,表示指針?biāo)缸兞康膬?nèi)容賦值運(yùn)算加減運(yùn)算關(guān)系運(yùn)算(4)指針變量可以作為函數(shù)的參數(shù),函數(shù)的返回值可以是指針類(lèi)型,還可以是指向函數(shù)的指針變量,并將函數(shù)的入口地址賦給函數(shù)的指針變量。通過(guò)對(duì)“學(xué)生成績(jī)管理系統(tǒng)”的相關(guān)數(shù)據(jù)的設(shè)計(jì)與定義,我們掌握了C的常量、變量類(lèi)型和基本使用方法以及各算術(shù)運(yùn)算符和表達(dá)式的運(yùn)算方法;理解了基本指針類(lèi)型及表達(dá)式在程序中的使用。8.2任務(wù)2用指針實(shí)現(xiàn)學(xué)生成績(jī)排序任務(wù)目標(biāo):能用指針實(shí)現(xiàn)學(xué)生成績(jī)排序。
8.2.1任務(wù)情境
8.2.2知識(shí)必備
8.2.3任務(wù)實(shí)施
8.2.4知識(shí)擴(kuò)展任務(wù)小結(jié)習(xí)題8.2.1任務(wù)情境
指針是C語(yǔ)言中廣泛使用的一種數(shù)據(jù)類(lèi)型。運(yùn)用指針編程是C語(yǔ)言最主要的風(fēng)格之一。利用指針變量可以表示各種數(shù)據(jù)結(jié)構(gòu);本任務(wù)初步實(shí)現(xiàn)按升序排列學(xué)生成績(jī)函數(shù)AsceSort()和按降序排列學(xué)生成績(jī)函數(shù)DropSort(),排序方法采用“冒泡法排序”。
在排序函數(shù)中,創(chuàng)建并生成了一個(gè)新的成績(jī)數(shù)(temp_score),其目的是在排序的程中,不影響原成績(jī)數(shù)組的排列。8.2.2知識(shí)必備
【例8.9】用選擇法對(duì)10個(gè)整數(shù)排序。
程序代碼如下:01020304050607080910111213141516171819main(){int*p,i,a[10]={3,7,9,11,0,6,7,5,4,2};printf("Theoriginalarray:\n");for(i=0;i<10;i++)printf("%d,",a[i]);printf("\n");p=a;sort(p,10);for(p=a,i=0;i<10;i++){printf("%d",*p);p++;}printf("\n");}sort(intx[],intn){inti,j,k,t;for(i=0;i<n-1;i++){k=i;for(j=i+1;j<n;j++)if(x[j]>x[k])k=j;
8.2.2知識(shí)必備
2021222324if(k!=i){t=x[i];x[i]=x[k];x[k]=t;}}}
代碼貼士調(diào)用一個(gè)函數(shù)只能得到一個(gè)返回值,用全局變量在函數(shù)之間“傳遞”數(shù)據(jù)。
8.2.2知識(shí)必備
指針與字符串
字符串就是用雙引號(hào)括起來(lái)的若干字符,其結(jié)束標(biāo)志為‘\0’,字符串指針就是指向字符串的字符指針變量。
字符串的表示形式;使用字符串指針變量與字符數(shù)組的區(qū)別;8.2.2知識(shí)必備
(1.1)字符串的表示形式:
在C語(yǔ)言中,可以用兩種方法訪問(wèn)一個(gè)字符串。用字符數(shù)組存放一個(gè)字符串,然后輸出該字符串。
【例8.10】main(){charstring[]=”IloveChina!”;printf("%s\n",string);}
說(shuō)明:和前面介紹的數(shù)組屬性一樣(如圖8-12),string是數(shù)組名,它代表字符數(shù)組的首地址。
8.2.2知識(shí)必備
用字符串指針指向一個(gè)字符串。
【例8.11】
main(){char*string=”IloveChina!”;printf("%s\n",string);}
字符串指針變量的定義說(shuō)明與指向字符變量的指針變量說(shuō)明是相同的。只能按對(duì)指針變量的賦值不同來(lái)區(qū)別。對(duì)指向字符變量的指針變量應(yīng)賦予該字符變量的地址。
8.2.2知識(shí)必備
【例8.12】在輸入的字符串中查找有無(wú)‘k’字符
程序代碼如下:0102030405060708091011121314main(){charst[20],*ps;inti;printf("inputastring:\n");ps=st;scanf("%s",ps);for(i=0;ps[i]!='\0';i++)if(ps[i]=='k'){printf("thereisa'k'inthestring\n");break;}if(ps[i]=='\0')printf("Thereisno'k'inthestring\n");}代碼貼士
在輸入的字符串中查找有無(wú)‘k’字符。8.2.2知識(shí)必備
(1.2)使用字符串指針變量與字符數(shù)組的區(qū)別:
用字符數(shù)組和字符指針變量都可實(shí)現(xiàn)字符串的存儲(chǔ)和運(yùn)算。但是兩者是有區(qū)別的。在使用時(shí)應(yīng)注意以下幾個(gè)問(wèn)題:字符串指針變量本身是一個(gè)變量,用于存放字符串的首地址。而字符串本身是存放在以該首地址為首的一塊連續(xù)的內(nèi)存空間中并以‘\0’作為串的結(jié)束。字符數(shù)組是由于若干個(gè)數(shù)組元素組成的,它可用來(lái)存放整個(gè)字符串。對(duì)字符串指針?lè)绞絚har*ps="CLanguage";可以寫(xiě)為:
char*ps;ps="CLanguage";而對(duì)數(shù)組方式:
staticcharst[]={"CLanguage"};不能寫(xiě)為:
charst[20];st={"CLanguage"};而只能對(duì)字符數(shù)組的各元素逐個(gè)賦值。8.2.2知識(shí)必備
從以上幾點(diǎn)可以看出字符串指針變量與字符數(shù)組在使用時(shí)的區(qū)別,同時(shí)也可看出使用指針變量更加方便。
前面說(shuō)過(guò),當(dāng)一個(gè)指針變量在未取得確定地址前使用是危險(xiǎn)的,容易引起錯(cuò)誤。但是對(duì)指針變量直接賦值是可以的。因?yàn)镃系統(tǒng)對(duì)指針變量賦值時(shí)要給以確定的地址。
因此,
char*ps="CLangage";
或者
char*ps;ps="CLanguage";
都是合法的。8.2.2知識(shí)必備
指針與結(jié)構(gòu)體
指針變量非常靈活方便,可以指向任一類(lèi)型的變量,若定義指針變量指向結(jié)構(gòu)體類(lèi)型變量,則可以通過(guò)指針來(lái)引用結(jié)構(gòu)體類(lèi)型變量。指向結(jié)構(gòu)體類(lèi)型變量的使用;指向結(jié)構(gòu)體類(lèi)型數(shù)組的指針的使用;8.2.2知識(shí)必備
(2.1)指向結(jié)構(gòu)體類(lèi)型變量的使用:
在C語(yǔ)言中,可以用兩種方法訪問(wèn)一個(gè)字符串。首先讓我們定義結(jié)構(gòu)體:
structstu{charname[20];longnumber;floatscore[4];};再定義指向結(jié)構(gòu)體類(lèi)型變量的指針變量:
structstu*p1,*p2;定義指針變量p1、p2,分別指向結(jié)構(gòu)體類(lèi)型變量。引用形式為:指針變量→成員8.2.2知識(shí)必備
【例8.13】對(duì)指向結(jié)構(gòu)體類(lèi)型變量的正確使用。輸入一個(gè)結(jié)構(gòu)體類(lèi)型變量的成員,并輸出。
程序代碼如下:01020304050607080910111213141516171819#include<stdlib.h>/*使用malloc()需要*/structdata/*定義結(jié)構(gòu)體*/{intday,month,year;};structstu/*定義結(jié)構(gòu)體*/{charname[20];longnum;structdatabirthday;/嵌*套的結(jié)構(gòu)體類(lèi)型成員*/};main()/*定義main()函數(shù)*/{structstu*student;定/*義結(jié)構(gòu)體類(lèi)型指針*/student=malloc(sizeof(structstu));為/指*針變量分配安全的地址*/printf("Inputname,number,year,month,day:\n");scanf("%s",student->name);輸/*入學(xué)生姓名、學(xué)號(hào)、出生年月日*/scanf("%ld",&student->num);scanf("%d%d%d",&student->birthday.year,&student->birthday.month,&student->birthday.day);
8.2.2知識(shí)必備
20212223242526printf("\nOutputname,number,year,month,day\n");/*打印輸出各成員項(xiàng)的值*/printf("%20s%10ld%10d//%d//%d\n",student->name,student->num,student->birthday.year,student->birthday.month,student->birthday.day);}代碼貼士程序中使用結(jié)構(gòu)體類(lèi)型指針引用結(jié)構(gòu)體變量的成員,需要通過(guò)C提供的函數(shù)malloc()來(lái)為指針?lè)峙浒踩牡刂?。函?shù)sizeof()返回值是計(jì)算給定數(shù)據(jù)類(lèi)型所占內(nèi)存的字節(jié)數(shù)。指針?biāo)父鞒蓡T形式為:student->namestudent->numstudent->birthday.yearstudent->birthday.monthstudent->birthday.day。
運(yùn)行結(jié)果如圖8-13所示:圖8—138.2.2知識(shí)必備
(2.2)指向結(jié)構(gòu)體類(lèi)型數(shù)組的指針的使用:
定義一個(gè)結(jié)構(gòu)體類(lèi)型數(shù)組,其數(shù)組名是數(shù)組的首地址,這一點(diǎn)前面的課程介紹得很清楚。
定義結(jié)構(gòu)體類(lèi)型的指針,既可以指向數(shù)組的元素,也可以指向數(shù)組,在使用時(shí)要加以區(qū)分?!纠?.14】在例8_13中定義了結(jié)構(gòu)體類(lèi)型,根據(jù)此類(lèi)型再定義結(jié)構(gòu)體數(shù)組及指向結(jié)構(gòu)體類(lèi)型的指針。structdata{intday,month,year;};structstu/*定義結(jié)構(gòu)體*/{charname[20]longnum;structdatabirthday;/嵌*套的結(jié)構(gòu)體類(lèi)型成員*/};8.2.2知識(shí)必備
structstustudent[4],*p;定/*義結(jié)構(gòu)體數(shù)組及指向結(jié)構(gòu)體類(lèi)型的指針*/作p=student,此時(shí)指針p就指向了結(jié)構(gòu)體數(shù)組student。p是指向一維結(jié)構(gòu)體數(shù)組的指針,對(duì)數(shù)組元素的引用可采用三種方法:地址法
student+i和p+i均表示數(shù)組第i個(gè)元素的地址,數(shù)組元素各成員的引用形式為:(student+i)->name、(student+i)->num和(p+i)->name、(p+i)->num等。student+i和p+i與&student[i]意義相同。指針?lè)ㄈ魀指向數(shù)組的某一個(gè)元素,則p++就指向其后續(xù)元素。指針的數(shù)組表示法若p=student,我們說(shuō)指針p指向數(shù)組student,p[i]表示數(shù)組的第i個(gè)元素,其效果與student[i]等同。對(duì)數(shù)組成員的引用描述為:p[i].name、p[i].num等。8.2.3任務(wù)實(shí)施
通過(guò)相關(guān)理論學(xué)習(xí)后,我們可以對(duì)“用指針實(shí)現(xiàn)學(xué)生成績(jī)排序”這個(gè)任務(wù)中學(xué)習(xí)成績(jī)排序函數(shù)用指針變量作參數(shù)來(lái)實(shí)現(xiàn)。任務(wù)2給出的“用指針實(shí)現(xiàn)學(xué)生成績(jī)排序”學(xué)生成績(jī)排序函數(shù)也可以用指針變量做參數(shù)來(lái)實(shí)現(xiàn)。下面給出的這二個(gè)函數(shù),只將原函數(shù)中的數(shù)組形參修改成指針形參,函數(shù)按指針訪問(wèn)方式編寫(xiě)。(1)
函數(shù)聲明可修改成:voidAsceSort(float*,int);//按升序排列指針訪問(wèn)函數(shù)voidDropSort(float*,int);//按降序排列指針訪問(wèn)函數(shù)void(2)
函數(shù)調(diào)用可以不修改。(3)
函數(shù)定義修改成:8.2.3任務(wù)實(shí)施
按升序排列指針訪問(wèn)函數(shù):程序代碼如下:01020304050607080910111213141516171819voidAsceSort(float*pscore,intstusize)//按升序排列指針訪問(wèn)函數(shù){ inti,j; floattemp; floattemp_score[STUSIZE],*pf; system("cls"); pf=temp_score; for(i=0;i<stusize;i++,pscore++) temp_score[i]=*pscore;for(i=0;i<stusize-1;i++) for(j=0;j<stusize-i-1;j++) if(*(pf+j+1)<*(pf+j)) { temp=*(pf+j); *(pf+j)=*(pf+j+1); *(pf+j+1)=temp; } gotoxy(5,5); printf("升序排列結(jié)果:");
8.2.3任務(wù)實(shí)施
20212223242526for(i=0;i<stusize;i++) printf("%6.1f",*(pf+i)); gotoxy(20,10); printf("升序排列成功,按任意鍵返回上級(jí)菜單!"); getch();}
代碼貼士按升序排列指針訪問(wèn)函數(shù)8.2.3任務(wù)實(shí)施
按降序排列指針訪問(wèn)函數(shù):程序代碼如下:01020304050607080910111213141516171819voidDropSort(float*pscore,intstusize)//按降序排列指針訪問(wèn)函數(shù){ inti,j; floattemp; floattemp_score[STUSIZE],*pf; system("cls"); pf=temp_score; for(i=0;i<stusize;i++,pscore++) temp_score[i]=*pscore; for(i=0;i<stusize-1;i++) for(j=0;j<stusize-i-1;j++) if(*(pf+j+1)>*(pf+j)) { temp=*(pf+j); *(pf+j)=*(pf+j+1); *(pf+j+1)=temp; }gotoxy(5,5); printf("降序排列結(jié)果:");
8.2.3任務(wù)實(shí)施
20212223242526for(i=0;i<stusize;i++) printf("%6.1f",*(pf+i)); gotoxy(20,10); printf("降序排列成功,按任意鍵返回上級(jí)菜單!"); getch();}代碼貼士按降序排列指針訪問(wèn)函數(shù)8.2.4知識(shí)擴(kuò)展
任務(wù)二完成中我們用到了結(jié)構(gòu)體,下面我們具體介紹。C語(yǔ)言中給出了另一種構(gòu)造數(shù)據(jù)類(lèi)型——“結(jié)構(gòu)(structure)”或叫“結(jié)構(gòu)體”。它相當(dāng)于其它高級(jí)語(yǔ)言中的記錄?!敖Y(jié)構(gòu)”是一種構(gòu)造類(lèi)型,它是由若干“成員”組成的。每一個(gè)成員可以是一個(gè)基本數(shù)據(jù)類(lèi)型或者又是一個(gè)構(gòu)造類(lèi)型。結(jié)構(gòu)既是一種“構(gòu)造”而成的數(shù)據(jù)類(lèi)型,那么在說(shuō)明和使用之前必須先定義它,也就是構(gòu)造它。如同在說(shuō)明和調(diào)用函數(shù)之前要先定義函數(shù)一樣。1.定義一個(gè)結(jié)構(gòu)的一般形式為:#defineSTUSIZE40struct結(jié)構(gòu)名{成員表列}成員表列由若干個(gè)成員組成,每個(gè)成員都是該結(jié)構(gòu)的一個(gè)組成部分。對(duì)每個(gè)成員也必須作類(lèi)型說(shuō)明,其形式為:類(lèi)型說(shuō)明符成員名;成員名的命名應(yīng)符合標(biāo)識(shí)符的書(shū)寫(xiě)規(guī)定。例如:
structstu{intnum;charname[20];charsex;floatscore;};8.2.4知識(shí)擴(kuò)展
2.結(jié)構(gòu)變量成員的表示方法在程序中使用結(jié)構(gòu)變量時(shí),往往不把它作為一個(gè)整體來(lái)使用。在ANSIC中除了允許具有相同類(lèi)型的結(jié)構(gòu)變量相互賦值以外,一般對(duì)結(jié)構(gòu)變量的使用,包括賦值、輸入、輸出、運(yùn)算等都是通過(guò)結(jié)構(gòu)變量的成員來(lái)實(shí)現(xiàn)的。表示結(jié)構(gòu)變量成員的一般形式是:結(jié)構(gòu)變量名.成員名例如:
boy1.num即第一個(gè)人的學(xué)號(hào)boy2.sex即第二個(gè)人的性別如果成員本身又是一個(gè)結(jié)構(gòu)則必須逐級(jí)找到最低級(jí)的成員才能使用。例如:boy1.birthday.month即第一個(gè)人出生的月份成員可以在程序中單獨(dú)使用,與普通變量完全相同。8.2.4知識(shí)擴(kuò)展
3.結(jié)構(gòu)變量的賦值和其他類(lèi)型變量一樣,對(duì)結(jié)構(gòu)變量可以在定義時(shí)進(jìn)行初始化賦值。
【例8.15】對(duì)結(jié)構(gòu)變量初始化。
程序代碼如下:010203040506070809main(){structstu{intnum;char*name;charsex;floatscore;}boy1,boy2;boy1.num=102;="Zhangping";printf("inputsexandscore\n");scanf("%c%f",&boy1.sex,&boy1.score);boy2=boy1;printf("Number=%d\nName=%s\n",boy2.num,);printf("Sex=%c\nScore=%f\n",boy2.sex,boy2.score);}代碼貼士本程序中用賦值語(yǔ)句給num和name兩個(gè)成員賦值,name是一個(gè)字符串指針變量。用scanf函數(shù)動(dòng)態(tài)地輸入sex和score成員值,然后把boy1的所有成員的值整體賦予boy2。最后分別輸出boy2的各個(gè)成員值。本例表示了結(jié)構(gòu)變量的賦值、輸入和輸出的方法。8.2.4知識(shí)擴(kuò)展
4.結(jié)構(gòu)變量的初始化和其他類(lèi)型變量一樣,對(duì)結(jié)構(gòu)變量可以在定義時(shí)進(jìn)行初始化賦值?!纠?.16】對(duì)結(jié)構(gòu)變量初始化。
程序代碼如下:010203040506070809main(){structstu{intnum;char*name;charsex;floatscore;}boy1,boy2;boy1.num=102;="Zhangping";printf("inputsexandscore\n");scanf("%c%f",&boy1.sex,&boy1.score);boy2=boy1;printf("Number=%d\nName=%s\n",boy2.num,);printf("Sex=%c\nScore=%f\n",boy2.sex,boy2.score);}代碼貼士本程序中用賦值語(yǔ)句給num和name兩個(gè)成員賦值,name是一個(gè)字符串指針變量。用scanf函數(shù)動(dòng)態(tài)地輸入sex和score成員值,然后把boy1
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 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ì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五版農(nóng)業(yè)墊資服務(wù)合同樣本2篇
- 2025年度應(yīng)急指揮車(chē)輛設(shè)備采購(gòu)合同4篇
- 教育信息化背景下的中小學(xué)教學(xué)方法變革
- 2025年度珠寶首飾出口貨物運(yùn)輸代理與鑒定服務(wù)合同4篇
- 2025年物流配送與快遞快遞行業(yè)標(biāo)準(zhǔn)化合同范本3篇
- 2025年度動(dòng)物行為研究錄像采集合同4篇
- 2025年度特種工程挖掘機(jī)購(gòu)置與操作培訓(xùn)合同4篇
- 二零二五版鋁合金門(mén)窗市場(chǎng)營(yíng)銷(xiāo)推廣合作協(xié)議4篇
- 二零二五年新型發(fā)動(dòng)機(jī)銷(xiāo)售合作協(xié)議3篇
- 2025年脫硫石膏爐渣生產(chǎn)與應(yīng)用銷(xiāo)售承包合作協(xié)議3篇
- 定額〔2025〕1號(hào)文-關(guān)于發(fā)布2018版電力建設(shè)工程概預(yù)算定額2024年度價(jià)格水平調(diào)整的通知
- 2024年城市軌道交通設(shè)備維保及安全檢查合同3篇
- 【教案】+同一直線(xiàn)上二力的合成(教學(xué)設(shè)計(jì))(人教版2024)八年級(jí)物理下冊(cè)
- 湖北省武漢市青山區(qū)2023-2024學(xué)年七年級(jí)上學(xué)期期末質(zhì)量檢測(cè)數(shù)學(xué)試卷(含解析)
- 單位往個(gè)人轉(zhuǎn)賬的合同(2篇)
- 科研倫理審查與違規(guī)處理考核試卷
- GB/T 44101-2024中國(guó)式摔跤課程學(xué)生運(yùn)動(dòng)能力測(cè)評(píng)規(guī)范
- 高危妊娠的評(píng)估和護(hù)理
- 2024年山東鐵投集團(tuán)招聘筆試參考題庫(kù)含答案解析
- 2023年高考全國(guó)甲卷數(shù)學(xué)(理)試卷【含答案】
- 數(shù)獨(dú)題目A4打印版無(wú)答案
評(píng)論
0/150
提交評(píng)論