版權(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 3.1.2認(rèn)識地球-地圖(原卷版)
- 建筑環(huán)保材料施工合同模板
- 微電影創(chuàng)作團(tuán)隊(duì)演員合同
- 印章管理與業(yè)務(wù)流程優(yōu)化
- 停車場安全保衛(wèi)備忘錄
- 超連續(xù)譜與頻率梳在半導(dǎo)體光波導(dǎo)中的應(yīng)用研究
- 金剛石拉曼激光技術(shù)新進(jìn)展:1.6μm單縱模應(yīng)用
- 固態(tài)266nm激光器在科研中的應(yīng)用分析
- 第一性原理視角下金屬二碲化鉬吸附研究
- 二氧化硅光子晶體結(jié)構(gòu)色增強(qiáng)機(jī)理分析
- 山東昌樂二中的“271高效課堂”
- 人教版高中物理新舊教材知識對比
- 國際結(jié)算期末復(fù)習(xí)試卷5套及參考答案
- 六年級上冊數(shù)學(xué)圓中方方中圓經(jīng)典題練習(xí)
- 現(xiàn)場組織機(jī)構(gòu)框圖及說明
- 《城鎮(zhèn)燃?xì)夤芾項(xiàng)l例》解讀
- 數(shù)學(xué)歸納法原理第二歸納法跳躍歸納法反向歸納法
- 七年級數(shù)學(xué)幾何證明題(典型)
- X62W萬能銑床電氣原理圖解析(共18頁)
- 小康煤礦水文地質(zhì)類型劃分報(bào)告
- (完整版)中央空調(diào)現(xiàn)場勘察信息表
評論
0/150
提交評論