IT計(jì)算機(jī)課件結(jié)構(gòu)體與公用體_第1頁
IT計(jì)算機(jī)課件結(jié)構(gòu)體與公用體_第2頁
IT計(jì)算機(jī)課件結(jié)構(gòu)體與公用體_第3頁
IT計(jì)算機(jī)課件結(jié)構(gòu)體與公用體_第4頁
IT計(jì)算機(jī)課件結(jié)構(gòu)體與公用體_第5頁
已閱讀5頁,還剩74頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

第八章結(jié)構(gòu)體與共用體

8-1概述

8.2定義結(jié)構(gòu)體類型和定義結(jié)構(gòu)體變量

83_結(jié)構(gòu)體變量的引用

8A結(jié)構(gòu)體變量的初始化

8.5結(jié)構(gòu)體數(shù)組

&6指針與結(jié)構(gòu)體

87用指針處理鏈表

*8.8共用體

*8,9枚舉類型

8.10用typedef定義類型

&T概述.YA皿L

「數(shù)組:同類型數(shù)據(jù)的集合;

C構(gòu)造類型1結(jié)構(gòu)體:不同類型數(shù)據(jù)的集合;

〔共用體:不同類型的量共用存儲單元。

若:表示學(xué)生多門課成績,各門課成績數(shù)據(jù)類型一

致,適合用數(shù)組表示。

若:對一系列整數(shù)排序,適合用數(shù)組表示。

3

若:編程處理若干學(xué)生的基本情況;其中每個(gè)學(xué)生

的基本情況由若干項(xiàng)組成,而各項(xiàng)的類型可能

相同或不同。

項(xiàng)目:學(xué)號姓名性別出生日期成績電話號碼

數(shù)據(jù):210510LiFengM1984.5.4680029-8482500

類型:長整/字串字串字符字串整型字串

該例中構(gòu)成每個(gè)學(xué)生基本情況的數(shù)據(jù)類型不同,

可采用結(jié)構(gòu)體這種數(shù)據(jù)類型實(shí)現(xiàn)。

4

8.2定義結(jié)構(gòu)體類型新薇B構(gòu)體變量

1.定義結(jié)構(gòu)體類型

定義一般形式:struct結(jié)構(gòu)體名

{類型標(biāo)識符成員名1;

類型標(biāo)識符成員名2;

I

I

類型琮識符成員名n;

);

其中:

1)struct結(jié)構(gòu)體名組成具體的結(jié)構(gòu)體類型標(biāo)識符,

可用這個(gè)結(jié)構(gòu)體類型標(biāo)識符去定義變量等對象;

2)結(jié)構(gòu)體名、成員名應(yīng)符合標(biāo)識符命名規(guī)則;

3)類型標(biāo)識符確定各成員類型;

5

【例】定義可表示學(xué)生基本情況的結(jié)構(gòu)體類型。

項(xiàng)目:學(xué)號姓名性別出生日期成績電話號碼

數(shù)據(jù):010510LiFengM1981.5.4680029-8482500

類型:長整/字串字串字符字串整型字串

structstudent/*特定結(jié)構(gòu)體類型標(biāo)識*/

{longnum;

charname[20];

charsex;

charbirthday[12];

floatscore;

chartel[15];

);/*該類型共有6個(gè)成員*/

L6

1)結(jié)構(gòu)體不可能有統(tǒng)一的結(jié)構(gòu),因此一個(gè)結(jié)構(gòu)體的

成員數(shù)目、各成員的類型必須依據(jù)具體情況由用

戶自己定義;

2)一個(gè)C程序可定義多個(gè)結(jié)構(gòu)體類型;定義的位置

可在函數(shù)之內(nèi),也可在函數(shù)之外;位置決定其有

效范圍;

如:結(jié)構(gòu)體類型1定義;

main()—y------------::-

(結(jié)M體類型2定義;類型2有效類型1有效

…;}—

funl(…)

■)

57

3)成員名可與程序中其它量同名,且互不干擾;

4)成員的類型也可是已定義過的結(jié)構(gòu)體類型;

如:structdate/*該結(jié)構(gòu)體有3個(gè)成員*/

{intm;

intd;

inyy;};

structstudent/*該結(jié)構(gòu)體有6個(gè)成員*/

{longnum;

charname[20];

charsex;

structdatebirthday;/*成員類型:結(jié)構(gòu)體*/

floatscore;

chartel[15];};

8

5)定義結(jié)構(gòu)體類型僅僅聲明了一種數(shù)據(jù)結(jié)構(gòu),編譯

系統(tǒng)是不會為類型分配存儲空間的;此時(shí)在有效

范圍內(nèi),可用已定義的結(jié)構(gòu)體類型去定義結(jié)構(gòu)體

變量或數(shù)組,編譯系統(tǒng)將為結(jié)構(gòu)體變量或數(shù)組分

配存儲空間;

2.定義結(jié)構(gòu)體類型的變量

三種定義方法:

1)先定義結(jié)構(gòu)體類型,再用類型標(biāo)識去定義變量

structstudentstul,stu2;

structstudent是已定義的結(jié)構(gòu)體類型標(biāo)識符;

對stul>stu2是所定義的結(jié)構(gòu)體變量;編譯時(shí)將為

結(jié)構(gòu)體變量分配各自的存儲空間;

2)定義類型的同時(shí)定義變量

structstudent

/*各成員的定義*/

}stul,stu2;

3)不使用結(jié)構(gòu)體名,定義類型的同時(shí)定義變量

struct/*無結(jié)構(gòu)體名*/

{…;

???,

}stul,stu2;

說明:

界結(jié)構(gòu)體變量可以是局部的或全局的。

器結(jié)構(gòu)體變量存儲空間大小為各成員長度之和;

如變量stul存儲字節(jié)數(shù):4+20+1+6+4+15=50

11

對結(jié)構(gòu)體變量的存儲結(jié)構(gòu):各成員按定義順序連續(xù)

存儲;

stul

如:

num4

structstudent

{longnum;name20

charname[20];

1、共56字節(jié)

charsex;sex

charbirthday[12];birthday12

floatscore;score4

chartel[15];

tel15>

}stul,stu2;

成員成員字節(jié)

12

如:

structdatestul

{intm;num4、

intd;

name20

inyy;};

structstudent

sex1》共50字節(jié)

{longnum;m

birthdayd6

charname[20];y

charsex;score4

structdatebirthday;tei15」

floatscore;口7

chartel[15];成員成員字節(jié)

}stul,stu2;

13

8.3結(jié)構(gòu)體變量的引用,、.

數(shù)組引用的單位是元素,而不能引用整個(gè)數(shù)組。

結(jié)構(gòu)體變量引用的單位則是成員,同樣結(jié)構(gòu)體

變量不能被整體引用。

1.結(jié)構(gòu)體變量各成員的引用

引用形式:結(jié)構(gòu)體變量名,成員名

其中:成員運(yùn)算符',':一級,自左而右;

如:按以上定義

stul.num引用結(jié)構(gòu)體變量stu1的num成員;

stul.name引用stul的name成員(字符指針);

[i]引用name成員的第i個(gè)元素;

stul.birthday.y只能對最低級成員進(jìn)行引用;

2,結(jié)構(gòu)體變量各成員的輸入、輸出

應(yīng)按成員類型選擇輸入、輸出的格式符。

【例】按以上定義輸入

scanf("%ld",&stul.num);,■于&*/

scanf《'%d,%d,%cT,&stul-birthday,m,

&stu1,birthday.d,&stu1.birthday.y);

,0110234/(不保存前導(dǎo)0)

5,242981/

【例1gets(stu);/*成員name的指針*/

seanf(,,%sn,stu1.tel);/*成員tel的指針*/

>LiFeng/

【例】按以上定義輸出

printf("munber:%07ld\n",stul.num);/*前導(dǎo)0*/

printf(”%d,%d,%cr,stul.birthday.y,

stul-birthday-m,stul.birthday.d);

printf("name:%s\n",);

^for(i=0;[i]!=0;i++)/*數(shù)組成員輸出*/

-printf("%c",[i]);

說明:,與口運(yùn)算符同為一級,自左而右運(yùn)算。

16

3.成員的賦值

1)數(shù)值型成員賦值

如:stul,num=110234;/*不力口前導(dǎo)0*/

stul,birthday.y=1981;

stul-birthday,m=5;

2)字符數(shù)組成員賦值

如:strcpy(stul,name,"LiFeng");

錯(cuò)誤:="LiFeng";

17

3)結(jié)構(gòu)體變量間的賦值

如:stu2=stul;

注:TC下允許同類型結(jié)構(gòu)體變量間直接賦值;

其結(jié)果是按成員一一對應(yīng)賦值。

4.對成員對象可像普通變量一樣進(jìn)行相應(yīng)運(yùn)算

如:sum=stul.score+stu2,score;

如:stul.num++;/*,1級/++2級*/

先訪問成員num,而后num自加1;

18

5,結(jié)構(gòu)體變量的指針、結(jié)構(gòu)體成員的指針

注:&優(yōu)先級為2級,低于,和口;?

圖示:變量stul的指針:&Stljlnum*l

num成員指針:&stu1.num

name成員指針:stul.name

name第i個(gè)元素指針:&stu1.name[i]

birthday

最低級成員y的指針:&stul,birthday,y-----------

score

成員tel的指針:stul.tel

r19

。一網(wǎng)”fg好也亭學(xué)^^觸婚<#r

,…,I

8.4結(jié)構(gòu)體變量的初始化

定義結(jié)構(gòu)體變量的同時(shí)用初值表給出初值。

【例】定義結(jié)構(gòu)體變量存放兩位學(xué)生的基本情況,

計(jì)算平均成績,并以大寫形式輸出name成員。

#include"stdio-h"

structstudent/*定義全局結(jié)構(gòu)體類型*/

{longnum;

charname[20];

floatscore;};

main()/*!按成員順序給出初值*/

{structstudentstul={109031,"LiFeng",89.0},

stu2={109032,"WangLi",71.0);

floataver;inti;…;}

20

aver=(stul.score+stu2,score)/2.0;

printf("\n\taverage=%7,2f\n",aver);

rfor(i=0;[i]!=0;i++)/*處理stul*/

if([i]>=,a,&&[i]<=,z,)

<[i]-=32;/*成員name[i]運(yùn)登*/

rfor(i=0;[i]!=0;i++)/*處而stu2*/

if(stu2,name[i]>=,a,&&[i]<=,z,)

、stu2,name[i]-=32;

printf(“\n\t%ld,%s,%7,2f2

stul.num,stubname,stul.score);

printf("\n\t%ld,%s,%Z2f\nn,

stu2,num,stu2,name,stu2,score);

}/*main*/

21

8.5結(jié)構(gòu)體數(shù)組

數(shù)組是同類型元素的集合;結(jié)構(gòu)體數(shù)組也是同

類型元素的集合,只不過每個(gè)元素的類型均為相同

的結(jié)構(gòu)體類型。

前面介紹的結(jié)構(gòu)體變量可用來表示一位學(xué)生的

基本情況,要表示多個(gè)學(xué)生的基本情況時(shí),采用結(jié)

構(gòu)體數(shù)組比較方便。

22

1.結(jié)構(gòu)體數(shù)組的定義和初始化

例:structstudent

{longnum;

charname[20];

floatscore;

}stu[3]={{99001,"LiFeng",89.5},

{99002,"WangYi",70.5},

{99003,"ZhaoHui",92}};

說明:

1)數(shù)組stu各元素類型相同,都為structstudent型;

2)結(jié)構(gòu)體數(shù)組stu的存儲字節(jié)數(shù)為:

元素類型長X元素個(gè)數(shù)=(4+20+4)X3=84字節(jié)

23

3)結(jié)構(gòu)體數(shù)組stu的存儲結(jié)構(gòu)

990014

LiFeng\0

stu[O]<20>28

89.54J

99002

WangYi\0

stu[l]<84byte

70.5stu[l].score

99003stu[2].num

ZhaoHui\0

stu[2]

92.07

-24

2.結(jié)構(gòu)體數(shù)組的引用“‘

結(jié)構(gòu)體數(shù)組在引用時(shí),不僅要確定引用哪一個(gè)

元素,還要確定引用該元素的哪一個(gè)成員。

引用形式:數(shù)組名[下標(biāo)].成員名

其中:運(yùn)算符口與.同為一級,自左而右結(jié)合;

過程:依據(jù)數(shù)組名及下標(biāo)先定位到元素,然后再定

位到成員;

如:

stu[O].num訪問stu數(shù)組首元素的成員num;

stu[l].score訪問以1為下標(biāo)那個(gè)元素的score成員;

awarn這

【例】編程求三位學(xué)生的平均成績,并輸出成績最

高者的學(xué)號、姓名、成績。

main()

{struct/*定義局部結(jié)構(gòu)體類型及數(shù)組*/

{longnum;

charname[20];

floatscore;

}stu[3]={{99031,"LiLin",89.0},

{99032,"WangFang",71.0},

{99033,"ZhaoPing”,92.0});

floatmaxs,sum=0;

inti,p;

…;)

main()

{結(jié)構(gòu)體類型、結(jié)構(gòu)體數(shù)組stu的定義及賦初值;

floatmaxs,sum=0;

inti,p;

maxs=0;

rfor(i=0;i<3;i++)

{sum=sum+stu[i].score;/*累力口各元素score成員*/

if(stu[i],score>maxs){maxs=stu[i].score;p=i;}

1}

printf("\n\taverage=%f\n",sum/3,0);

prin曲\tnum:%ld,name:%s,score:%7,2f\n”,

stu[p].num,stu[p],name,stu[p].score);

)

27

【例】30張選票,對三名侯選人之一投票選舉,輸

入得票人名字,按名字計(jì)數(shù),輸出最后選舉結(jié)果。

#include"stdio.h"led[O].name

#defineN30led[0].count

structperson

{charname[20];

intcount;

);

main()

{structpersonled[3]=

0,“Zhang”,0,"Wang",0};

-;)

28

main()

{structpersonled[3]=

{"Li",0,"Zhang",0,"Wang",0};

charlname[20];inti,j;

rfor(i=l;i<=N;i++)/*i控制選票張數(shù)*/

{printf("Input%dNO.name:”,i);gets(lname);

rfor(j=0;j<3;j++)/*j控制數(shù)組下標(biāo)*/

if(strcmp(led[j].name,lname)==0)/*串比較*/

〔{led[j],count+=l;break;}/*計(jì)票*/

1}

for(i=0;i<3;i++)

-printf(,,\n%-10s:%d",led[i].name,led[i].count);

)YS

29

8.6指針與結(jié)構(gòu)體

1.指向結(jié)構(gòu)體變量的指針

一個(gè)結(jié)構(gòu)體變量的指針是該變量存儲區(qū)域的起

始地址,它指向結(jié)構(gòu)體這個(gè)整體。

在程序中可定義一個(gè)指向同類型結(jié)構(gòu)體的指針

變量,并將該指針變量指向某結(jié)構(gòu)體變量,之后便

可利用指針變量訪問各成員。

二,/工卡30

【例】利用結(jié)構(gòu)體指針,對某學(xué)生基本情況賦值并輸出。

main()

{structstudentYS

{longnum;charname[20];floatscore;

}stul,*p;stul

stul.num=99001;pastui*46899001

1

strcpy(,"LiFeng');472name[0]

stul.score=89.5;473namerr

p=&stul;

printf(”num:%ld\n”,(*p).num);

printf(”name:%s\n”,(*p).name);491name[19]

printf(',score:%7.2\n,,,(*p).score);49289.5

printf("%u,%u,%u,%u\nn,

&stul,&stul.num,stul,name,&stul.score);

)

、',31

1)當(dāng)p=&stul;且保持不變時(shí),

(*p).num表示訪問p所指向變量的num成員;

其中:*號為2級,括號可保證先使p與*結(jié)合。

2)當(dāng)p=&stul;且保持不變時(shí)有:

stul.numu>(*p),num<=>p->num

3),稱為指向成員運(yùn)算符;1級,自左而右;

p->num中->代替了*和.運(yùn)算符,看著更直觀;

如:

p->score:訪問p所指向變量的score成員;

p->name[i]:訪問p指向變量的name成員第i個(gè)元素。

32

2.用結(jié)構(gòu)體指針變量訪問結(jié)構(gòu)體數(shù)組元素

【例】輸入/輸出三位學(xué)生基本情況,計(jì)算平均成績

#include"stdio.h"pn99001

#include"math.h"LiFeng

<

structstudentstu[0]

I89.5

{longnum;r

charname[20];99002

WangYi

floatscore;};stu[l]

main()

I70-5

r

{structstudent*p,stu[3];99003

ZhaoHui

inti;floatsum=0;stu[2]<

???;...;p=stu;

92.0

)

33

sqrt(25);/*激活浮點(diǎn)運(yùn)算*/

rfor(i=0;i<3;i++)/*輸入所有數(shù)據(jù)*/

{printf("\t%dnumber:",i+1);

scanf("%ldn,&stu[i].num);getchar();

printf("\tname:");gets(stu[i].name);

printf("\tscore:");scanf("%f",&stu[i].score);

1)

rfor(p=stu;p<stu+3;p++)/*輸出所有數(shù)據(jù)*/

printf(”\t%-8ld%-20s%-7.2f\n”,

[p->num,p->name,p->score);

for(p=stu,i=0;i<3;i++)/*p不變*/

sum=sum+(p+i)->score;/*累加成績*/

printf("\taverage=%-7,2f\n",sum/3.0);

)

34

說明:

1)^p=stu;p++的增量為元素類型長28,從而使

p指向下一個(gè)元素;

2)當(dāng)p=stu;且保持不變時(shí),

p+i的值:stu+ix元素類型長

=stu+ix28

p+i含義:數(shù)組元素str[i]的地址;

即:p+i<=>stu+io&stu[i]:結(jié)構(gòu)體數(shù)組元素指針;

(*(P+i)).num0(p+i)->num處str[i].num;

35

3,結(jié)構(gòu)體指針作為函數(shù)參數(shù)

此時(shí)實(shí)參與形參對應(yīng)關(guān)系為:

實(shí)參形參

結(jié)構(gòu)體變量,成員

-成員的值?一與成員同類型變量

成員產(chǎn)本類型變量一

數(shù)組成員的指針

數(shù)組名、姒筌拜人口"日¥,同類型形參數(shù)組

結(jié)構(gòu)體變量的指針結(jié)構(gòu)體變量的指針,結(jié)構(gòu)體指針變量

結(jié)構(gòu)體變量名各成員值對應(yīng)傳遞-同類型結(jié)構(gòu)體變量

36

【例】一結(jié)構(gòu)體類型,可表示學(xué)號、姓名、三門課

成績及平均成績,編程對兩位學(xué)生的成績求個(gè)人平

均分、輸出所有數(shù)據(jù)項(xiàng)。

要求:1)分別用結(jié)構(gòu)體變量stul、stu2存儲數(shù)據(jù);

2)由函數(shù)aver實(shí)現(xiàn)平均分計(jì)算;

3)由函數(shù)pfun實(shí)現(xiàn)輸出;

函數(shù)間信息傳遞:

源程序:

structstudent

{longnum;

charname[20];

floatscore[3];

floataver;

);

main()

structstudentstul={...},

stu2={...};/*定義變量并賦初值*/

)

去,「?y38

main()

{structstudent/*I定義結(jié)構(gòu)體變量并賦初值*/

stul={99001,nLiHong",89,76,90,0},

stu2={99002,"WangLi",70.5,85.5,76,0};

voidaver(structstudent*p);

voidpfun(structstudents);

aver(&stul);/*實(shí)參:結(jié)構(gòu)體變量的指針*/

aver(&stu2);

pnntf("\tnumber\tname\

\t\tscorel\tscore2\tscore3\taverage\n");

pfun(stul);/*實(shí)參:結(jié)構(gòu)體變量*/

pfun(stu2);

)

二J

voidaver(structstudent*p)

{inti;floatsum=0;

[for(i=0;i<3;i++)sum=sum+p->score[i];

p->aver=sum/3,0;

return;

)

voidpfun(structstudents)/*實(shí)形參對應(yīng)成員值傳遞*/

{inti;

printf("\t%ld\t%s\t",s.num,);

for(i=0;i<3;i++)/*輸出成績成員的各元素*/

、printf("\t%"7.2f",s.score[i]);

pnntf(n\t%7.2f\n",s.aver);

return;}

;:40

【例】設(shè)計(jì)一軟件計(jì)時(shí)器,力字符顯示時(shí)「務(wù)秒'

structtime_stru/*該類型全局有效*/

{inth,m,s;};/*三個(gè)成員用一個(gè)標(biāo)識符*/

main()

{voidupdata(structtime_stru*t);

voiddisplay(structtime_stru*t);

structtime_strutime;/*定義結(jié)構(gòu)體變量*/

time.h=time,m=time,s=O;clrscr();

while(!kbhit())/*擊鍵測試*/

{updata(&time);

display(&time);

)

)

voidupdata(structtime_stru*t)

{longi;

t->s++;/*秒成員自加1*/

if(t->s==60){t->m++;t->s=O;}

if(t->m==60){t->h++;t->m=0;}

if(t->h==24)t->h=O;

for(i=l;i<8500000;i++);/*模擬1秒延時(shí)*/

return;

)

voiddisplay(structtime_stru*t)

{gotoxy(35,12);

printf(”%02d:%02d:%02d)t->h,t->m,t->s);

return;}

u-542

【例】調(diào)用標(biāo)準(zhǔn)函數(shù),顯示日期和時(shí)間。

系統(tǒng)口期函數(shù)原形:voidgetdate(structdate*datep);

系統(tǒng)時(shí)間函數(shù)原形:voidgettime(structtime*timep);

dos.h頭文件中結(jié)構(gòu)體類型的定義:

structtime{unsignedcharti_min;

unsignedcharti_hour;

unsignedcharti_hunt;,分之…秒*/

unsignedcharti_sec;

);

structdate{intda_year;

charda_day;

chardamon;

);

43

#include"dos.h"#include"graphics.h"

#definePATH,,c:\\tc30n

main()

{structdate*dp,sysdate;/*定義結(jié)構(gòu)體變量*/

structtime*tp,systime;unsignedchart;

intgd=VGA,gm=VGAHI,size;charch[20],*p;

initgraph(&gd,&gm,PATH);/*圖位初始化*/

setcolor(14);circle(320,240,200);/*畫黃色圓*/

dp=&sysdate;getdate(dp);/*取系統(tǒng)日期*/

printf(“\t\tdate:%d,%d,%d“,/*輸出日期各成員*/

dp->da_yeacdp->da_mon,dp->da_day);

size=imagesize(260,380,460,420);/*求畫面字節(jié)數(shù)*/

p=(char*)malloc(size);申請動態(tài)存儲區(qū)*/

getimage(260,380,460,420,p);/*存儲背景色畫面*/

L.:XTMo44

tp=&systime;gettime(tp);WWW-

t=tp->ti_sec;/*保存秒成員*/

/while(!kbhit())/*擊鍵測試*/

{gettime(tp);/*不斷取系統(tǒng)時(shí)間*/

/if(tp->ti_sec!=t)/*測試秒成員是否改變*/

{putimage(260,380,p,0);/*輸出畫面擦除文本*/

sprintf(ch,nTIME:%u:%u:%u",/*輸出到ch中*/

tp->ti_houi;tp->ti_min,tp->ti_sec);

outtextxy(260,380,ch);/南形模式文未輸出*/

sound(500);delay(200);/*揚(yáng)聲器發(fā)聲*/

nosoundQ;/*關(guān)閉聲音*/

t=tp->ti_sec;/*更新t*/

)

45

8.7用指針處理鏈表

1.鏈表概述

1)動態(tài)數(shù)據(jù)結(jié)構(gòu)概念

數(shù)組和結(jié)構(gòu)體是定長數(shù)據(jù)結(jié)構(gòu),而鏈表、堆

棧、隊(duì)列、樹、圖等是執(zhí)行時(shí)大小可變的動態(tài)數(shù)

據(jù)結(jié)構(gòu)。

鏈表是連成一行的數(shù)據(jù)項(xiàng)集合,每一個(gè)數(shù)據(jù)

項(xiàng)(元素)稱為節(jié)點(diǎn),可以在鏈表中的任意位置進(jìn)

行節(jié)點(diǎn)插入或刪除操作,使鏈表數(shù)據(jù)項(xiàng)的個(gè)數(shù)隨

之增加或減少。

46

2)鏈表的構(gòu)成

單向鏈表圖示:

head

其中:

用head是指針變量,存放鏈表的頭指針1048;

算各節(jié)點(diǎn)是相同的結(jié)構(gòu)體類型,該類型有三個(gè)成員;

就各節(jié)點(diǎn)應(yīng)包含一個(gè)指針成員存放下一節(jié)點(diǎn)的地址;

就各節(jié)點(diǎn)存儲有可能不連續(xù),但各節(jié)點(diǎn)邏輯上連續(xù)。

3)節(jié)點(diǎn)的構(gòu)成

上圖每個(gè)節(jié)點(diǎn)具有如下結(jié)構(gòu)體類型:

structstudent

{longnum;

floatscore;

structerstudent*next;/*鏈節(jié)成員*/

);

其中:

對血員num、score用于存放一個(gè)節(jié)點(diǎn)的具體數(shù)據(jù);

猶成員next是指針類型,用于存放下一節(jié)點(diǎn)指針,

最后一個(gè)節(jié)點(diǎn)的next成員存放空指針NULL;

我成員next是指向與自身同一類型的結(jié)構(gòu),這種結(jié)

構(gòu)稱為自引用結(jié)構(gòu)。(只有指針成員可自弓I用)

48

4)動態(tài)內(nèi)存分配和釋放

建立和維護(hù)動態(tài)數(shù)據(jù)結(jié)構(gòu)需要實(shí)現(xiàn)動態(tài)內(nèi)存

分配;如在鏈表中插入節(jié)點(diǎn)需要先申請一段存儲

區(qū)域,而刪除一個(gè)節(jié)點(diǎn)需要釋放該節(jié)點(diǎn)原先占用

的存儲區(qū)域,這可由標(biāo)準(zhǔn)函數(shù)實(shí)現(xiàn)。

內(nèi)存分配函數(shù)原形:void*malloc(unsignedsize);

功能:在內(nèi)存申請一塊長度為size個(gè)字節(jié)的空間;

若申請成功,該函數(shù)返回指向存儲塊起始

地址的指針,該指針類型為void*;否則返

回空指針(NULL)。

內(nèi)存釋放函數(shù)原形:voidfree(void*p);

功能:釋放p所指向的內(nèi)存塊。

49

5)采用鏈表的意義

并與定長數(shù)據(jù)結(jié)構(gòu)數(shù)組相比,鏈表能更好地利用

內(nèi)存,按需分配和釋放存儲空間。

就在鏈表中插入或刪除一個(gè)節(jié)點(diǎn),只需改變某節(jié)

點(diǎn)“鏈節(jié)”成員的指向,而不需要移動其它節(jié)點(diǎn),

相對數(shù)組元素的插入和刪除效率高。

50

2.單鏈表的建立和輸出

建立鏈表的準(zhǔn)備工作:

1)定義鏈表的節(jié)點(diǎn)類型;

2)定義與節(jié)點(diǎn)同類型的鏈表頭指針變量head并賦

值0,表示鏈表在建立之前是空的;

3)定義與節(jié)點(diǎn)同類型的工作指針變量pl、p2o

51

建立鏈表的步驟:

1)開辟第一個(gè)節(jié)點(diǎn)的存儲區(qū)域,使head、pl、p2

指向第一個(gè)節(jié)點(diǎn),并輸入第一個(gè)節(jié)點(diǎn)數(shù)據(jù);

head

p2101

pl-895

P2—

2)開辟下一節(jié)點(diǎn)的存儲區(qū)域,使pl指向新節(jié)點(diǎn)、

輸入新節(jié)點(diǎn)數(shù)據(jù),并將上一個(gè)節(jié)點(diǎn)的next成員

52

3)將p2也指向新節(jié)點(diǎn);

head

4)重復(fù)第2、3步,建立并鏈接多個(gè)節(jié)點(diǎn)直至所需

長度,將末尾節(jié)點(diǎn)的next成員賦值0。

head

【例】建立并輸出有3名學(xué)生數(shù)據(jù)的單鏈表。

#include"stdio.h"/*包含NULL的定義*/

#include"math-h"

#defineN3

structstudent/*結(jié)構(gòu)體類型定義*/

{longnum;

floatscore;

structstudent*next;/*自引用結(jié)構(gòu)體指針*/

);

main()

)

衛(wèi)廣等眥汨但可受MY南-t冢弋XTM54

-1r9^」二

main()w

{structstudent*head,*pl,*p2;

inti,len;sqrt(5.5);/*激活浮點(diǎn)運(yùn)算*/

head=NULL;/*head不指向任何位置*/

len=sizeof(structstudent);/*求類型長*/

rfor(i=l;i<=N;i++)/*/強(qiáng)制轉(zhuǎn)換為結(jié)構(gòu)體指針類型*/

{pl=(structstudent*)malloc(len);/*申請*/

printf("Enternum,score:");I輸入數(shù)據(jù)*/

scanf("%ld,%f",&pl->num,&pl->score);

rif(i==l)head=p2=pl;/*指向首節(jié)點(diǎn)*/

〔else{p2->next=pl;p2=pl;}/*節(jié)點(diǎn)鏈接*/

if(i==N)p2->next=NULL;"標(biāo)記末尾節(jié)點(diǎn)*/

I):

55

main()

「for(i=l;i<=N;i++)/*建立鏈表*/

L{:}

rfor(i=l;i<=N;i++)/*輸出鏈表*/

{rif(i==l)pl=head;/*pl指向首節(jié)點(diǎn)*/

〔elsepl=pl->next;/*pl指向下一節(jié)點(diǎn)*/

printf("%d:num=%ld,score=%5,2f\rT,

i,pl->num,pl->score);

i)

}/*main*/

56

【例】將上題利用函數(shù)實(shí)現(xiàn),并求平均成績。

定義如下函數(shù):

建立鏈表函數(shù):structstudent*creat(void);

輸出鏈表函數(shù):voidplink(structstudent*head);

求平均值函數(shù):floataverf(structstudent*head);

函數(shù)間信息傳遞:

57

#include"stdio.h"

#include"math.h"

#defineN3

structstudent

{longnum;

floatscore;

structstudent*next;

);

main()

)

58

main()

{structstudent*head,*creat(void);

voidplink(structstudent*head);

floataverf(structstudent*head);

inti,len;floataver;

sqrt(5.5);clrscr();

head=NULL;

head=creat();/*返回鏈表頭指針*/

plink(head);

aver=averf(head);/*返回平均值*/

printf("Average=%5,2f\n",aver);

)

structstudent*creat()

{structstudent*head,*pl,*p2;

inti,len;

len=sizeof(structstudent);

廣for(i=l;i<=N;i++)

{pl=(structstudent*)malloc(len);

printf("Enternum,score:");

scanf("%ld,%f",&pl->num,&pl->score);

if(i==l)head=p2=pl;

else{p2->next=pl;p2=pl;}

if(i==N)p2->next=NULL;

1}

return(head);/*返回鏈表頭指針*/

voidplink(structstudent*head)/*輸出各節(jié)點(diǎn)*/

{structstduent*p;

inti;

rfor(i=l;i<=N;i++)

{if(i==l)p=head;

elsep=p->next;

printf("%d:num=%ld,score=%5,2f\n",

i,p->num,p->score);

1)

return;

)

floataverf(structstudent*head)

{structstudent*p;

floatsum=0;

intc=0;

p=head;/*使p指向首節(jié)點(diǎn)*/

<while(p!=NULL)

{C++;/*c統(tǒng)計(jì)節(jié)點(diǎn)數(shù)*/

sum=sum+p->score;

p=p->next;

i)

return(sum/c);/*返回平均值*/

YS

62

3.節(jié)點(diǎn)的刪除

步驟:

1)按查找關(guān)鍵字查找要?jiǎng)h除的節(jié)點(diǎn);

2)找到,則將要?jiǎng)h除節(jié)點(diǎn)的“鏈節(jié)”成員賦給前

一節(jié)點(diǎn)的“鏈節(jié)”成員,使刪除的節(jié)點(diǎn)脫離鏈

表。

若:要?jiǎng)h除節(jié)點(diǎn)為首節(jié)點(diǎn),則將首節(jié)點(diǎn)“鏈節(jié)”

員賦給鏈頭指針手

2918

蚓§

101,NULL

r5節(jié)63

V-U*

【例】按上例刪除指定學(xué)號的節(jié)點(diǎn)

structstudent*del(structstudent*head,longn)

{structstudent*pl,*p2;/*fn:要?jiǎng)h除學(xué)號*/

pl=head;

<if(pl->num==n)head=pl->next;*刪除首節(jié)點(diǎn)*/

else

{rdo{p2=pl;pl=pl->next;

【}while(pl!=NULL&&pl->num!=n);

if(pl->num==n)p2->next=pl->next;

elseprintf(nNotbefound!\nn);

1}

free(pl);/*釋放被刪除節(jié)點(diǎn)的存儲區(qū)*/

return(head);/*返回頭指針*/

;:,64

voidplink(structstudent*head)/*更具通用性*/

{structstudent*p;

p=head;

rwhile(p!=NULL)

{printf("num=%ld,score=%5.2f\n",

p->num,p->score);

p=p->next;

1}

return;

注:本形式的鏈表輸出函數(shù)具有通用性,可適應(yīng)由

于刪除或插入節(jié)點(diǎn)引起的鏈表長度的變化。

65

4.節(jié)點(diǎn)的插入"-一

插入可分為隨意插入和按順序插入,隨意插

入包括插入到頭部、尾部或中間指定位置;按順

序插入是指按某關(guān)鍵字的順序插入,而在插入前

鏈表必須已按該關(guān)鍵字進(jìn)行了排序。

按順序插入的步驟:

1)開辟待插入節(jié)點(diǎn)的存儲區(qū)域并輸入數(shù)據(jù);

2)查找插入位置:從鏈表首節(jié)點(diǎn)開始按關(guān)鍵字成

員與待插入節(jié)點(diǎn)相同成員進(jìn)行比較,直到確定

了插入位置;

66

3)將插入位置前一節(jié)點(diǎn)的“鏈節(jié)”成員賦給待插

入節(jié)

點(diǎn)的“鏈節(jié)”成員;

若:插入點(diǎn)在鏈頭,則將頭指針賦給待插入節(jié)點(diǎn)的

“鏈節(jié)”成員;

4)將待插入節(jié)點(diǎn)的指針賦給前一節(jié)點(diǎn)“鏈節(jié)”成

員;

【例】按上例在鏈表中插入節(jié)點(diǎn)

插入函數(shù):

structstudent*insert(structstudent*head)

{structstudent*pO,*pl,*p2;

longn;intlen;

len=sizeof(structstudent);

p0=(structstudent*)malloc(len);申請新節(jié)點(diǎn)*/

printf("Enternum,scoretoinsert:");

scanf(H%ld,%f",&pO->num,&pO->score);

n=pO->num;7*產(chǎn)生學(xué)號副家n*/

pl=head;/*從首節(jié)點(diǎn)開始查找*/

I

!

pl=head;/*廠而入在頭部*/

〔if(n<pl->num){pO->next=head;head=pO;}

else

{rdo/*查找插入位置*/

{p2=pl;

pl=pl->next;

L}while(pl!=NULL&&n>pl->num);

pO->next=p2->next;/*皤入在其余位置*/

p2->next=p0;

I}

return(head);

,}/"insert*/

69

【例】編寫二個(gè)通用的函數(shù);可根據(jù)需要建立任意

節(jié)點(diǎn)數(shù)的鏈表。

structstudent*creat()/*無參有返回值*/

{structstudent*head=NULL,*pl,*p2;

intlen;longn;floats;

len=sizeof(structstudent);

/*循環(huán)次數(shù)不確定*/

rwhile(l)

{printf("Enternumber;score:");

scanf("%ld,%f",&n,&s);

if(n==0)break;/*輸入。表示數(shù)據(jù)結(jié)束*/

pl=(structstudent*)malloc(len);

1:}

return(head);}

rwhile(l)

{printf("Enternumber;score:");

scanf(n%ld,%fn,&n,&s);

if(n==O)break;/*以。表示數(shù)據(jù)結(jié)束*/

pl=(structstudent*)malloc(len);

pl->num=n;pl->score=s;*轉(zhuǎn)存入節(jié)點(diǎn)*/

rif(head==NULL)head=p2=pl;

Ielse{p2->next=pl;p2=pl;}

1}

p2->next=NULL;/*末尾鏈節(jié)成員賦空*/

return(head);/*返回鏈表頭指針*/

)/*creat*/

71

8.10用typedef定義類型的別名

關(guān)鍵字typedef可用來為類型標(biāo)識符建立一個(gè)

別名,這個(gè)別名同樣可用于變量、數(shù)組、函數(shù)等

對象的聲明。

使用一般形式:typedef原類型名新類型名;

其中:原類型名可以是標(biāo)準(zhǔn)的或用戶定義的;

新類型名即為別名,別名通常大寫;

意義:

6用較短的別名代替用戶定義的結(jié)構(gòu)體類型名;

2)使程序具有更好的通用性。

如:typedeffloatREAL;/*定義類型別名*/

REALx,y;/*用類型別名定義變量*/

如:typed

溫馨提示

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

評論

0/150

提交評論