




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領
文檔簡介
指針
促成教學目標:1、能正確理解各種類型的指針變量的定義;2、掌握指針變量的引用方法,理解指針變量運算的含義;3、學會使用指針數(shù)組和指向指針的指針;4、靈活運用指針作函數(shù)參數(shù)和返回值。8.1任務1用指針實現(xiàn)學生最高、最低等成績查找任務目標:能用指針實現(xiàn)學生最高、最低等成績查找。
8.1.1任務情境
8.1.2知識必備
8.1.3任務實施
8.1.4知識擴展任務小結(jié)8.1.1任務情境
“指針”中的數(shù)據(jù)有指針和指針變量,指針變量的定義,賦值及其運算,指針變量作為函數(shù)參數(shù)的用法,指針數(shù)組與字符串,指針與函數(shù)。
“班級學生成績管理系統(tǒng)”查找最高分、最低分和不及格成績的3個函數(shù)也可以用指針變量做參數(shù)來實現(xiàn)。指針可以說是c語言的精華。
下面我們通過相關理論的學習,掌握如何用指針將“學生最高、最低等成績查找”中的數(shù)據(jù)進行相關設計。8.1.2知識必備
【例8_1】從10個數(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)用一個函數(shù)只能得到一個返回值,用全局變量在函數(shù)之間“傳遞”數(shù)據(jù)。8.1.2知識必備
指針變量
通過實例分析,我們已經(jīng)看到程序中使用指針變量存放變量的地址、指針變量的初始化、及引用。
指針變量的定義指針變量的初始化指針變量的引用8.1.2知識必備
(1.1)指針變量的定義:
其一般形式為:
類型說明符*變量名;
其中,*表示這是一個指針變量,變量名即為定義的指針變量名,類型說明符表示本指針變量所指向的變量的數(shù)據(jù)類型。
例如:int*p1;
表示p1是一個指針變量,它的值是某個整型變量的地址。或者說p1指向一個整型變量。至于p1究竟指向哪一個整型變量,應由向p1賦予的地址來決定。8.1.2知識必備
(1.2)指針變量的初始化:
先來介紹兩個有關的運算符:
兩個有關的運算符:
&:取地址運算符。/*使用方法:&變量名*/*:指針運算符。/*使用方法:*表示指針變量名*/
地址運算符”&”來表示取變量的地址,實際上是變量的起始地址。指針運算符“*”表示取指針變量所對應內(nèi)在單元的值。
初始化的一般形式為:
數(shù)據(jù)類型名:*變量名=初始地址值;
例如:
inta;charc;int*pa=&a;char*pc=&c;8.1.2知識必備
(1.3)指針變量的引用:
在定義了一個指針變量并確定了其指向后,就可以用來訪問所指向的變量。
引用指針變量的一般形式為:*指針變量名
這里的星號(*)稱為指針運算符,也稱作間接訪問運算符。
【例8.2】引用輸出兩個數(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);}代碼貼士
在開頭處雖然定義了兩個指針變量pointer_1和pointer_2,擔它們并未指向任何一個整型變量。只是提供兩個指針變量,規(guī)定它們可以指向整型變量。程序第5、6行的作用就是使pointer_1指向a,pointer_2指向b。最后一行的*pointer_1和*pointer_2就是變量a和b。最后兩個printf函數(shù)作用是相同的。8.1.2知識必備
2.指針與函數(shù)函數(shù)的參數(shù)不僅可以是整型、實型、字符型等數(shù)據(jù),還可以是指針類型。它的作用是將一個變量的地址傳送到另一個函數(shù)中。8.1.2知識必備
【例8.3】輸入a、b、兩個整數(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);}
代碼貼士
該程序中,當輸入a=5,b=9時,由于a<b,將p1和p2進行.交換,實際上a和b并未交換,它們?nèi)员3衷担琾1和p2的值改變了。P1的值原為&a,后來為&b,p2原值為&b,后來變成&a。這樣在輸出*p1和*p2時,實際上是輸出變量b和a的值。8.1.2知識必備
3.指針與數(shù)組
一個變量有一個地址,一個數(shù)組包含若干元素,每個數(shù)組元素都在內(nèi)存中占用存儲單元,它們都有相應的地址。所謂數(shù)組的指針是指數(shù)組的起始地址,數(shù)組元素的指針是數(shù)組元素的地址。
指向數(shù)組元素的指針;通過指針引用數(shù)組元素;數(shù)組名做函數(shù)參數(shù);指向多數(shù)組的指針和指針變量;8.1.2知識必備
(3.1)指向數(shù)組元素的指針
一個數(shù)組是由連續(xù)的一塊內(nèi)存單元組成的。數(shù)組名就是這塊連續(xù)內(nèi)存單元的首地址。一個數(shù)組也是由各個數(shù)組元素(下標變量)組成的。每個數(shù)組元素按其類型不同占有幾個連續(xù)的內(nèi)存單元。一個數(shù)組元素的首地址也是指它所占有的幾個內(nèi)存單元的首地址。
例如:
inta[10];/*定義a為包含10個整型數(shù)據(jù)的數(shù)組*/int*p;/*定義p為指向整型變量的指針*/
應當注意,因為數(shù)組為int型,所以指針變量也應為指向int型的指針變量。下面是對指針變量賦值:
p=&a[0];8.1.2知識必備把a[0]元素的地址賦給指針變量p。也就是說,p指向a數(shù)組的第0號元素。C語言規(guī)定,數(shù)組名代表數(shù)組的首地址,也就是第0號元素的地址。因此,下面兩個語句等價:p=&a[0];p=a;在定義指針變量時可以賦給初值:int*p=&a[0];它等效于:int*p;p=&a[0];當然定義時也可以寫成:
int*p=a;:8.1.2知識必備從右圖8-1中我們可以看出有以下關系:
p,a,&a[0]均指向同一單元,它們是數(shù)組a的首地址,也是0號元素a[0]的首地址。應該說明的是p是變量,而a,&a[0]都是
常量。在編程時應予以注意。數(shù)組指針變量說明的一般形式為:類型說明符*指針變量名;
其中類型說明符表示所指數(shù)組的類型。從一般形式可以看出指向數(shù)組的指針變量和指向普通變量的指針變量的說明是相同的。圖8-18.1.2知識必備
(3.2)通過指針引用數(shù)組元素
C語言規(guī)定:如果指針變量p已指向數(shù)組中的一個元素,則p+1指向同一數(shù)組中的下一個元素。
引入指針變量后,就可以用兩種方法來訪問數(shù)組元素了。
如果p的初值為&a[0],則:
p+i和a+i就是a[i]的地址,或者說它們指向
a數(shù)組的第i個元素。如右圖8-2所示:
*(p+i)或*(a+i)就是p+i或a+i所指向的數(shù)組元素,即a[i]。例如,*(p+5)或*(a+5)就是a[5]。
指向數(shù)組的指針變量也可以帶下標,如p[i]與
*(p+i)等價。圖8-28.1.2知識必備根據(jù)以上敘述,引用一個數(shù)組元素可以用:下標法,即用a[i]形式訪問數(shù)組元素。在前面介紹數(shù)組時都是采用這種方法。指針法,即采用*(a+i)或*(p+i)形式,用間接訪問的方法來訪問數(shù)組元素,其中a是數(shù)組名,p是指向數(shù)組的指針變量,其處值p=a。
8.1.2知識必備
【例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知識必備
(3.3)數(shù)組名做函數(shù)參數(shù)數(shù)組名可以作函數(shù)的實參和形參。如:main(){intarray[10];…………f(array,10);…………}f(intarr[],intn);{…………}
8.1.2知識必備
array為實參數(shù)組名,arr為形參數(shù)組名。數(shù)組名就是數(shù)組的首地址,實參向形參傳送數(shù)組名實際上就是傳送數(shù)組的地址,形參得到該地址后也指向同一數(shù)組如圖8-3所示。
圖8-3
同樣,指針變量的值也是地址,數(shù)組指針變量的值即為數(shù)組的首地址,當然也可作為函數(shù)的參數(shù)使用。8.1.2知識必備
【例8.5】將數(shù)組a中的n個整數(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]對換,再a[1]與a[n-2]對換……,直到將a[(n-1/2)]與a[n-int((n-1)/2)]對換。今用循環(huán)處理此問題,設兩個“位置指示變量”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知識必備如圖8-4所示:圖8-48.1.2知識必備
(3.4)指向多數(shù)組的指針和指針變量本小節(jié)以二維數(shù)組為例介紹多維數(shù)組的指針變量。多維數(shù)組的地址設有整型二維數(shù)組a[3][4]如下:
01234567891011
它的定義為:
inta[3][4]={{0,1,2,3},{4,5,6,7},{8,9,10,11}}設數(shù)組a的首地址為1000,各下標變量的首地址及其值。如圖8-5所示:圖8-58.1.2知識必備
前面介紹過,C語言允許把一個二維數(shù)組分解為多個一維數(shù)組來處理。因此數(shù)組a可分解為三個一維數(shù)組,即a[0],a[1],a[2]。每一個一維數(shù)組又含有四個元素。如圖8-6所示:
例如a[0]數(shù)組,含有a[0][0],a[0][1],a[0][2],a[0][3]四個元素。圖8-68.1.2知識必備
前面介紹過,C語言允許把一個二維數(shù)組分解為多個一維數(shù)組來處理。因此數(shù)組a可分解為三個一維數(shù)組,即a[0],a[1],a[2]。每一個一維數(shù)組又含有四個元素。如圖8-6所示:圖8-6例如a[0]數(shù)組,含有a[0][0],a[0][1],a[0][2],a[0][3]四個元素。8.1.2知識必備
數(shù)組及數(shù)組元素的地址表示如下:從二維數(shù)組的角度來看,a是二維數(shù)組名,a代表整個二維數(shù)組的首地址,也是二維數(shù)組0行的首地址,等于1000。a+1代表第一行的首地址,等于1008。如圖8-7所示:圖8-7
a[0]是第一個一維數(shù)組的數(shù)組名和首地址,因此也為1000。*(a+0)或*a是與a[0]等效的,它表示一維數(shù)組a[0]0號元素的首地址,也為1000。&a[0][0]是二維數(shù)組a的0行0列元素首地址,同樣是1000。因此,a,a[0],*(a+0),*a,&a[0][0]是相等的。8.1.2知識必備
同理,a+1是二維數(shù)組1行的首地址,等于1008。a[1]是第二個一維數(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]也是等同的。因為在二維數(shù)組中不能把&a[i]理解為元素a[i]的地址,不存在元素a[i]。C語言規(guī)定,它是一種地址計算方法,表示數(shù)組a第i行首地址。由此,我們得出:a[i],&a[i],*(a+i)和a+i也都是等同的。
另外,a[0]也可以看成是a[0]+0,是一維數(shù)組a[0]的0號元素的首地址,而a[0]+1則是a[0]的1號元素首地址,(如圖8-8所示)由此可得出a[i]+j則是一維數(shù)組a[i]的j號元素首地址,它等于&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知識必備
【例8.6】通過二維數(shù)組輸出相應的值。程序代碼如下: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");}}代碼貼士通過循環(huán)輸出p+i+j的值8.1.3任務實施
任務1給出的“班級學生成績管理系統(tǒng)”查找最高分、最低分和不及格成績的3個函數(shù)也可以用指針變量做參數(shù)來實現(xiàn)。下面給出的這二個函數(shù),只將原函數(shù)中的數(shù)組形參修改成指針形參,函數(shù)按指針訪問方式編寫。(1)
函數(shù)聲明可修改成:voidSearchMax(float*,int);//查找最高分指針訪問函數(shù)voidSearchMin(float*,int);//查找最低分指針訪問函數(shù)(2)
函數(shù)調(diào)用可以不修改。(3)
函數(shù)定義修改成:8.1.3任務實施
查找最高分指針訪問函數(shù):程序代碼如下:01020304050607080910111213141516171819voidSearchMax(float*pscore,intstusize)//查找最高分指針訪問函數(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("成績最高的是:%.1f\n",*(pscore+flag));gotoxy(20,10);printf("查找最高分成功,按任意鍵返回上級菜單!");getch();}代碼貼士
查找最高分指針訪問函數(shù)
8.1.3任務實施
查找不合格學生成績指針訪問函數(shù):程序代碼如下:01020304050607080910111213141516171819voidNotElig(float*pscore,intstusize)//查找不合格學生成績指針訪問函數(shù){inti,flag=0;system("cls");gotoxy(20,5);printf("不合格成績:");for(i=0;i<stusize;i++){if(*(pscore+i)<60){ printf("%6.1f",*(pscore+i)); flag=1; }}if(!flag){gotoxy(35,5); printf("沒有不合格成績!");}
8.1.3任務實施
2021222324gotoxy(20,10);printf("查找不合格成績成功,按任意鍵返回上級菜單!");getch(); }
代碼貼士查找不合格學生成績指針訪問函數(shù)8.1.4知識擴展
一維數(shù)組元素的指針訪問方式:
一維數(shù)組的數(shù)組名實際上就是指向該數(shù)組的第一個單元的指針。一個一維數(shù)組若定義為:inta[10];
則數(shù)組名a的類型是int*(數(shù)組名代表數(shù)組的首地址,因此是指針類型),并且指向第一個元素;因此*a和a[0]訪問的是同一個元素,兩種表達形式完全等價,這種地址表達形式不僅可以訪問第一個元素,結(jié)合算術(shù)運算還可以訪問數(shù)組的其他元素。例如:*(a+1)等價于a[1];*(a+2)等價于a[2];……*(a+i)等價于a[i]。
因此,訪問數(shù)組元素的操作可以采用三種方法,一種叫下標法,一種叫地址法,還有一種叫指針法。采用指針法比采用地址法更為簡潔,執(zhí)行效率也更高。指向一維數(shù)組第一個元素的指針都可以像一維數(shù)組名那樣使用,例如:inta[10],*pa=a;*(pa+1)等價于a[1];*(pa+2)等價于a[2];……*(pa+i)等價于a[i]。8.1.4知識擴展
下標法與地址法、下標法與指針法的對應關系如圖8-9所示。圖8-98.1.4知識擴展
三種訪問方式在形式上遵守下面的等價關系如圖8-10所示:a[i]*(a+i)特別是當i等于0時:a[0]*(a+0)*aa[i]*(pa+i)特別是當i等于0時: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知識擴展
指針變量還可以用自增或自減運算來改變指針所指向的位置,達到移動指針的目的如圖8-11所示。printf(“%d”,*(pa++));printf(“%d”,*(++pa));printf(“%d”,*(pa--));printf(“%d”,*(--pa));圖8-11同學們想一想能否實現(xiàn):printf(?°%d?±,*(a++));printf(?°%d?±,*(a--));或printf(?°%d?±,*(++a));printf(?°%d?±,*(--a));8.1.4知識擴展
【例8.7】輸出數(shù)組的全部元素(幾種訪問方法比較):
程序代碼如下:
方法一:下標法010203040506070809main(){inta[5]={1,2,3,4,5};inti;for(i=0;i<5;i++)printf("%d,",a[i]);printf("\n");}代碼貼士
用下標法輸出數(shù)組的全部元素
8.1.4知識擴展
方法二:地址法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知識擴展
方法三:指針法010203040506070809main(){inta[10]={1,2,3,4,5};
int*p;
for(p=a;p<a+5;p++)printf("%d,",*p);
printf("\n");}代碼貼士
用指針法輸出數(shù)組的全部元素
三種方法的輸出結(jié)果都是:1,2,3,4,5,8.1.4知識擴展
【例8.8】下面的程序的輸出結(jié)果是什么?
程序代碼如下:
方法三:指針法010203040506070809101112#include<stdio.h>voidmain(){inta[10],*p,i;p=a;for(i=0;i<10;i++)scanf("%d",p++);/*特別要注意輸入時指針的變化*/printf("\n");for(i=0;i<10;i++,p++)/*指針p的值已經(jīng)變化*/printf("%d",*p);}代碼貼士
程序運行結(jié)果:1234567890<回車>輸出結(jié)果不是預期的值??!
8.1.4知識擴展
怎樣解決?其實很簡單:重新使指針變量指向數(shù)組的首地址,請看改進后的例子。
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");}代碼貼士
程序運行結(jié)果:1234567890<回車>1234567890
8.1.4知識擴展
當執(zhí)行到第6-7兩行時,隨著循環(huán)的執(zhí)行,指針p的指向在不斷的變化,循環(huán)結(jié)束后,指針p已指向數(shù)組的外面了,如果這時直接用指針來實現(xiàn)輸出其值的操作,指針指向的就不是數(shù)組的值,而是數(shù)組外面的內(nèi)容,輸出結(jié)果就不是預期的值。如果在輸出之前調(diào)整指針p的指向,使它重新指向數(shù)組的首地址,增加第9行p=a;語句,再輸出,就能得到預期的結(jié)果。任務小結(jié)
指針是c語言與數(shù)據(jù)結(jié)構(gòu)中的一個重要的組成部分,是學習后面知識的基礎。任務一主要介紹一下幾方面的內(nèi)容。(1)指針就是內(nèi)存地址,指針變量是一個特殊的變量,是專門用來存放內(nèi)存地址的。在定義一個指針變量時,將其初始化為空,可以避免造成系統(tǒng)混亂指針變量的運算(2)取地址運算符&,取變量的地址(3)取內(nèi)容運算符*,表示指針所指變量的內(nèi)容賦值運算加減運算關系運算(4)指針變量可以作為函數(shù)的參數(shù),函數(shù)的返回值可以是指針類型,還可以是指向函數(shù)的指針變量,并將函數(shù)的入口地址賦給函數(shù)的指針變量。通過對“學生成績管理系統(tǒng)”的相關數(shù)據(jù)的設計與定義,我們掌握了C的常量、變量類型和基本使用方法以及各算術(shù)運算符和表達式的運算方法;理解了基本指針類型及表達式在程序中的使用。8.2任務2用指針實現(xiàn)學生成績排序任務目標:能用指針實現(xiàn)學生成績排序。
8.2.1任務情境
8.2.2知識必備
8.2.3任務實施
8.2.4知識擴展任務小結(jié)習題8.2.1任務情境
指針是C語言中廣泛使用的一種數(shù)據(jù)類型。運用指針編程是C語言最主要的風格之一。利用指針變量可以表示各種數(shù)據(jù)結(jié)構(gòu);本任務初步實現(xiàn)按升序排列學生成績函數(shù)AsceSort()和按降序排列學生成績函數(shù)DropSort(),排序方法采用“冒泡法排序”。
在排序函數(shù)中,創(chuàng)建并生成了一個新的成績數(shù)(temp_score),其目的是在排序的程中,不影響原成績數(shù)組的排列。8.2.2知識必備
【例8.9】用選擇法對10個整數(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知識必備
2021222324if(k!=i){t=x[i];x[i]=x[k];x[k]=t;}}}
代碼貼士調(diào)用一個函數(shù)只能得到一個返回值,用全局變量在函數(shù)之間“傳遞”數(shù)據(jù)。
8.2.2知識必備
指針與字符串
字符串就是用雙引號括起來的若干字符,其結(jié)束標志為‘\0’,字符串指針就是指向字符串的字符指針變量。
字符串的表示形式;使用字符串指針變量與字符數(shù)組的區(qū)別;8.2.2知識必備
(1.1)字符串的表示形式:
在C語言中,可以用兩種方法訪問一個字符串。用字符數(shù)組存放一個字符串,然后輸出該字符串。
【例8.10】main(){charstring[]=”IloveChina!”;printf("%s\n",string);}
說明:和前面介紹的數(shù)組屬性一樣(如圖8-12),string是數(shù)組名,它代表字符數(shù)組的首地址。
8.2.2知識必備
用字符串指針指向一個字符串。
【例8.11】
main(){char*string=”IloveChina!”;printf("%s\n",string);}
字符串指針變量的定義說明與指向字符變量的指針變量說明是相同的。只能按對指針變量的賦值不同來區(qū)別。對指向字符變量的指針變量應賦予該字符變量的地址。
8.2.2知識必備
【例8.12】在輸入的字符串中查找有無‘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");}代碼貼士
在輸入的字符串中查找有無‘k’字符。8.2.2知識必備
(1.2)使用字符串指針變量與字符數(shù)組的區(qū)別:
用字符數(shù)組和字符指針變量都可實現(xiàn)字符串的存儲和運算。但是兩者是有區(qū)別的。在使用時應注意以下幾個問題:字符串指針變量本身是一個變量,用于存放字符串的首地址。而字符串本身是存放在以該首地址為首的一塊連續(xù)的內(nèi)存空間中并以‘\0’作為串的結(jié)束。字符數(shù)組是由于若干個數(shù)組元素組成的,它可用來存放整個字符串。對字符串指針方式char*ps="CLanguage";可以寫為:
char*ps;ps="CLanguage";而對數(shù)組方式:
staticcharst[]={"CLanguage"};不能寫為:
charst[20];st={"CLanguage"};而只能對字符數(shù)組的各元素逐個賦值。8.2.2知識必備
從以上幾點可以看出字符串指針變量與字符數(shù)組在使用時的區(qū)別,同時也可看出使用指針變量更加方便。
前面說過,當一個指針變量在未取得確定地址前使用是危險的,容易引起錯誤。但是對指針變量直接賦值是可以的。因為C系統(tǒng)對指針變量賦值時要給以確定的地址。
因此,
char*ps="CLangage";
或者
char*ps;ps="CLanguage";
都是合法的。8.2.2知識必備
指針與結(jié)構(gòu)體
指針變量非常靈活方便,可以指向任一類型的變量,若定義指針變量指向結(jié)構(gòu)體類型變量,則可以通過指針來引用結(jié)構(gòu)體類型變量。指向結(jié)構(gòu)體類型變量的使用;指向結(jié)構(gòu)體類型數(shù)組的指針的使用;8.2.2知識必備
(2.1)指向結(jié)構(gòu)體類型變量的使用:
在C語言中,可以用兩種方法訪問一個字符串。首先讓我們定義結(jié)構(gòu)體:
structstu{charname[20];longnumber;floatscore[4];};再定義指向結(jié)構(gòu)體類型變量的指針變量:
structstu*p1,*p2;定義指針變量p1、p2,分別指向結(jié)構(gòu)體類型變量。引用形式為:指針變量→成員8.2.2知識必備
【例8.13】對指向結(jié)構(gòu)體類型變量的正確使用。輸入一個結(jié)構(gòu)體類型變量的成員,并輸出。
程序代碼如下:01020304050607080910111213141516171819#include<stdlib.h>/*使用malloc()需要*/structdata/*定義結(jié)構(gòu)體*/{intday,month,year;};structstu/*定義結(jié)構(gòu)體*/{charname[20];longnum;structdatabirthday;/嵌*套的結(jié)構(gòu)體類型成員*/};main()/*定義main()函數(shù)*/{structstu*student;定/*義結(jié)構(gòu)體類型指針*/student=malloc(sizeof(structstu));為/指*針變量分配安全的地址*/printf("Inputname,number,year,month,day:\n");scanf("%s",student->name);輸/*入學生姓名、學號、出生年月日*/scanf("%ld",&student->num);scanf("%d%d%d",&student->birthday.year,&student->birthday.month,&student->birthday.day);
8.2.2知識必備
20212223242526printf("\nOutputname,number,year,month,day\n");/*打印輸出各成員項的值*/printf("%20s%10ld%10d//%d//%d\n",student->name,student->num,student->birthday.year,student->birthday.month,student->birthday.day);}代碼貼士程序中使用結(jié)構(gòu)體類型指針引用結(jié)構(gòu)體變量的成員,需要通過C提供的函數(shù)malloc()來為指針分配安全的地址。函數(shù)sizeof()返回值是計算給定數(shù)據(jù)類型所占內(nèi)存的字節(jié)數(shù)。指針所指各成員形式為:student->namestudent->numstudent->birthday.yearstudent->birthday.monthstudent->birthday.day。
運行結(jié)果如圖8-13所示:圖8—138.2.2知識必備
(2.2)指向結(jié)構(gòu)體類型數(shù)組的指針的使用:
定義一個結(jié)構(gòu)體類型數(shù)組,其數(shù)組名是數(shù)組的首地址,這一點前面的課程介紹得很清楚。
定義結(jié)構(gòu)體類型的指針,既可以指向數(shù)組的元素,也可以指向數(shù)組,在使用時要加以區(qū)分?!纠?.14】在例8_13中定義了結(jié)構(gòu)體類型,根據(jù)此類型再定義結(jié)構(gòu)體數(shù)組及指向結(jié)構(gòu)體類型的指針。structdata{intday,month,year;};structstu/*定義結(jié)構(gòu)體*/{charname[20]longnum;structdatabirthday;/嵌*套的結(jié)構(gòu)體類型成員*/};8.2.2知識必備
structstustudent[4],*p;定/*義結(jié)構(gòu)體數(shù)組及指向結(jié)構(gòu)體類型的指針*/作p=student,此時指針p就指向了結(jié)構(gòu)體數(shù)組student。p是指向一維結(jié)構(gòu)體數(shù)組的指針,對數(shù)組元素的引用可采用三種方法:地址法
student+i和p+i均表示數(shù)組第i個元素的地址,數(shù)組元素各成員的引用形式為:(student+i)->name、(student+i)->num和(p+i)->name、(p+i)->num等。student+i和p+i與&student[i]意義相同。指針法若p指向數(shù)組的某一個元素,則p++就指向其后續(xù)元素。指針的數(shù)組表示法若p=student,我們說指針p指向數(shù)組student,p[i]表示數(shù)組的第i個元素,其效果與student[i]等同。對數(shù)組成員的引用描述為:p[i].name、p[i].num等。8.2.3任務實施
通過相關理論學習后,我們可以對“用指針實現(xiàn)學生成績排序”這個任務中學習成績排序函數(shù)用指針變量作參數(shù)來實現(xiàn)。任務2給出的“用指針實現(xiàn)學生成績排序”學生成績排序函數(shù)也可以用指針變量做參數(shù)來實現(xiàn)。下面給出的這二個函數(shù),只將原函數(shù)中的數(shù)組形參修改成指針形參,函數(shù)按指針訪問方式編寫。(1)
函數(shù)聲明可修改成:voidAsceSort(float*,int);//按升序排列指針訪問函數(shù)voidDropSort(float*,int);//按降序排列指針訪問函數(shù)void(2)
函數(shù)調(diào)用可以不修改。(3)
函數(shù)定義修改成:8.2.3任務實施
按升序排列指針訪問函數(shù):程序代碼如下:01020304050607080910111213141516171819voidAsceSort(float*pscore,intstusize)//按升序排列指針訪問函數(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任務實施
20212223242526for(i=0;i<stusize;i++) printf("%6.1f",*(pf+i)); gotoxy(20,10); printf("升序排列成功,按任意鍵返回上級菜單!"); getch();}
代碼貼士按升序排列指針訪問函數(shù)8.2.3任務實施
按降序排列指針訪問函數(shù):程序代碼如下:01020304050607080910111213141516171819voidDropSort(float*pscore,intstusize)//按降序排列指針訪問函數(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任務實施
20212223242526for(i=0;i<stusize;i++) printf("%6.1f",*(pf+i)); gotoxy(20,10); printf("降序排列成功,按任意鍵返回上級菜單!"); getch();}代碼貼士按降序排列指針訪問函數(shù)8.2.4知識擴展
任務二完成中我們用到了結(jié)構(gòu)體,下面我們具體介紹。C語言中給出了另一種構(gòu)造數(shù)據(jù)類型——“結(jié)構(gòu)(structure)”或叫“結(jié)構(gòu)體”。它相當于其它高級語言中的記錄?!敖Y(jié)構(gòu)”是一種構(gòu)造類型,它是由若干“成員”組成的。每一個成員可以是一個基本數(shù)據(jù)類型或者又是一個構(gòu)造類型。結(jié)構(gòu)既是一種“構(gòu)造”而成的數(shù)據(jù)類型,那么在說明和使用之前必須先定義它,也就是構(gòu)造它。如同在說明和調(diào)用函數(shù)之前要先定義函數(shù)一樣。1.定義一個結(jié)構(gòu)的一般形式為:#defineSTUSIZE40struct結(jié)構(gòu)名{成員表列}成員表列由若干個成員組成,每個成員都是該結(jié)構(gòu)的一個組成部分。對每個成員也必須作類型說明,其形式為:類型說明符成員名;成員名的命名應符合標識符的書寫規(guī)定。例如:
structstu{intnum;charname[20];charsex;floatscore;};8.2.4知識擴展
2.結(jié)構(gòu)變量成員的表示方法在程序中使用結(jié)構(gòu)變量時,往往不把它作為一個整體來使用。在ANSIC中除了允許具有相同類型的結(jié)構(gòu)變量相互賦值以外,一般對結(jié)構(gòu)變量的使用,包括賦值、輸入、輸出、運算等都是通過結(jié)構(gòu)變量的成員來實現(xiàn)的。表示結(jié)構(gòu)變量成員的一般形式是:結(jié)構(gòu)變量名.成員名例如:
boy1.num即第一個人的學號boy2.sex即第二個人的性別如果成員本身又是一個結(jié)構(gòu)則必須逐級找到最低級的成員才能使用。例如:boy1.birthday.month即第一個人出生的月份成員可以在程序中單獨使用,與普通變量完全相同。8.2.4知識擴展
3.結(jié)構(gòu)變量的賦值和其他類型變量一樣,對結(jié)構(gòu)變量可以在定義時進行初始化賦值。
【例8.15】對結(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);}代碼貼士本程序中用賦值語句給num和name兩個成員賦值,name是一個字符串指針變量。用scanf函數(shù)動態(tài)地輸入sex和score成員值,然后把boy1的所有成員的值整體賦予boy2。最后分別輸出boy2的各個成員值。本例表示了結(jié)構(gòu)變量的賦值、輸入和輸出的方法。8.2.4知識擴展
4.結(jié)構(gòu)變量的初始化和其他類型變量一樣,對結(jié)構(gòu)變量可以在定義時進行初始化賦值。【例8.16】對結(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);}代碼貼士本程序中用賦值語句給num和name兩個成員賦值,name是一個字符串指針變量。用scanf函數(shù)動態(tài)地輸入sex和score成員值,然后把boy1
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025-2030年中國鋅空電池市場需求分析及發(fā)展前景預測報告
- 2025-2030年中國計算機機房行業(yè)運行態(tài)勢及發(fā)展盈利分析報告
- 2025-2030年中國純鐵鋼坯市場運行態(tài)勢規(guī)劃研究報告
- 2025-2030年中國糕點及面包市場運行動態(tài)與營銷策略研究報告
- 2025-2030年中國硅藻土行業(yè)運行現(xiàn)狀及發(fā)展前景分析報告
- 2024數(shù)學競賽CHKMO中國新加坡合練訓練題
- 重慶城市職業(yè)學院《液壓元件》2023-2024學年第二學期期末試卷
- 長治幼兒師范高等??茖W?!峨姎夤こ糖把丶夹g(shù)》2023-2024學年第二學期期末試卷
- 遼寧工業(yè)大學《計算機輔助造型設計》2023-2024學年第二學期期末試卷
- 四川衛(wèi)生康復職業(yè)學院《企業(yè)運營管理課程設計》2023-2024學年第二學期期末試卷
- 高中英語課程設計目的
- 2024-2025學年北京一零一中學初三期初測試數(shù)學試題含解析
- 2024年12月大學英語四級CET-4真題試卷
- 高中生物學選擇性必修一測試卷及答案解析
- 佳能EOS700D使用說明書
- 煤礦應急叫應、回應、響應機制
- 圓圈正義讀書分享課件
- DL∕T 1910-2018 配電網(wǎng)分布式饋線自動化技術(shù)規(guī)范
- 護理人力資源配置原則及調(diào)配方案
- 2023級武漢大學臨床醫(yī)學畢業(yè)考試試卷
- 高中體育與健康課耐久跑教案
評論
0/150
提交評論