C語言程序設(shè)計第9章._第1頁
C語言程序設(shè)計第9章._第2頁
免費預(yù)覽已結(jié)束,剩余22頁可下載查看

下載本文檔

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

文檔簡介

1、C語言程序段計第 9 章結(jié)構(gòu)體及其應(yīng)用:學習目標e 掌握構(gòu)造類型一結(jié)構(gòu)體類型及其使用學習內(nèi)容e 結(jié)構(gòu)體類型及其定義結(jié)構(gòu)體變量的定義及使用e 結(jié)構(gòu)體數(shù)組的使用結(jié)構(gòu)體指針的使用c 鏈表及其基本操作9.1一個程序?qū)嵗纠?-1】一個學生的信息包括學號、姓名、平時成績、期末 成績和總評成績,其中總評成績的計算公式為:總評成績二 平時成績X30%+期末成績X70%o根據(jù)給定的平時成績和期 末成績計算總評成績,并輸出學生的信息。 根據(jù)本題的情況,用以下形式構(gòu)造名為student的結(jié)構(gòu)體 類型。struct student/ *st udent為結(jié)構(gòu)體類型名*/ int num;/*學號為“代型*/char

2、 name| 10|/*姓名用字符數(shù)組*/float si, s2, score;/*3個成績?yōu)槠巴栊?/; struct student是一種結(jié)構(gòu)體類型,它由 5 個數(shù)據(jù) 項組成,此處的數(shù)據(jù)項稱為結(jié)構(gòu)體成員或者域。接 下來可以用 struct student這個數(shù)據(jù)類型定義變量, 只有變量才能存儲數(shù)據(jù)。例如,下面語句定義了 一個結(jié)構(gòu)體變量:struct student wang;:彎構(gòu)怦量中成員的引用形式為:結(jié)構(gòu)體變 量成員名。 比女口: wang.num、 wang name wang. si等。結(jié)構(gòu)體成員在程序中的作用和用 法與普通變量相同?!境绦虼a】【程序代碼】#include s

3、tdio.hinclude string.h”struct student廣定義結(jié)構(gòu)體類空*/int num;char name(10;float s1ts2.score:;main()struct student wang;/定義結(jié)構(gòu)體變廣以卜給變赧名為wang的學生賦值Vwan g.num=101;strcpy(,*wanghaiH):wang.s1=92.0;wang.s2=87.5;wang.score-wang.sV0.3+wang.s2*0.7;廣計林總評成纟/ 廣以卜輸出該學生信息/printfCNO.:%dnw,wang.num); printf(MNAME:

4、%snM,);printf(Ms1-%7.2f,s2-%7.2f.score-%7.2fnn,wang.s1,wang.s2.wang.score); 程序輸出結(jié)果為:o.:ieiA HE: zngha 11-87.5D八c。88 859.2結(jié)構(gòu)體類型的使用一組相關(guān)的數(shù)據(jù)可能是相同類型的, 也可能是不同類型的。為了封裝相關(guān)的 數(shù)據(jù),就需要采用可以包含不同類型成 員的類型來定義這樣的數(shù)據(jù),這種類型 就是結(jié)構(gòu)體類型。9.2.1結(jié)構(gòu)體類型的定義定義結(jié)構(gòu)體類型的一般形式為: struct 結(jié)構(gòu)體類型名類型名 1 成員名 1;類熨名 2 成員名 2;類型名 1 成員名 1;例如:str

5、uct stud int num; char name20; char sex; int age; float score3; char address30;;注意事項:(1 ) struct是關(guān)鍵字,標志結(jié)構(gòu)體類型。struct后 面是所定義的結(jié)構(gòu)體類型的名字,結(jié)構(gòu)體名應(yīng)符 合標識符的命名規(guī)則。這里結(jié)構(gòu)體名可以省略, 省略后將成為無名結(jié)構(gòu)體。(2)結(jié)構(gòu)體的各個成員用花括號括起來,結(jié)構(gòu)體 成員的定義方式和變量的定義方式一樣,成員名 的命名規(guī)則和變量相同;各成員之間用分號分隔; 結(jié)構(gòu)體類型的定義以分號結(jié)束。(3)結(jié)構(gòu)體成員的數(shù)據(jù)類型可以是基本類型的, 也可以是構(gòu)造類型,如數(shù)組或其他結(jié)構(gòu)體類型。9

6、.2.2結(jié)構(gòu)體變量的定義及引用:結(jié)構(gòu)體變量的定義(1)先聲明結(jié)構(gòu)體類型再定義變量名j 列如struct stud廣定義結(jié)構(gòu)體類型*/ int num;char name20;char sex;int age;float score3;char address30;;struct stud student1,student2;廣怎義結(jié)構(gòu)體變雖/結(jié)構(gòu)體變最 student 和 student2 屮各成員的賦值宿況如圖所示。numnamesexscotepscotep)eddxess101皆13乃.4893P25z”102M11695 19992 疋義結(jié)構(gòu)體類空的同時怎義結(jié)構(gòu)體變怎這種方法定義的一般

7、形式為:struct結(jié)構(gòu)體名成員表列變疑名表列;例如,I.面的結(jié)構(gòu)體類型struct stud也口J以采取以下形式定義:struct stud int num;char name20;char sex;int age;float score3);char address30; student1=101 /,ghzn,M,18,75.4,;,xianH,student2;這里只對變Mstudentl進行了賦初值操作。霜酪結(jié)構(gòu)體類型的同時定義結(jié)構(gòu)體變量即不出現(xiàn)般定義形式為:struct成員表列變量名表列; 例如:structint num;char name20;char sex

8、; int age;float score3; char address30; student1,student2;:結(jié)構(gòu)體變量中成員的引用結(jié)構(gòu)體變量本身不能代表一個特定的值,只 有它的成員才會有特定的值。因此使用結(jié)構(gòu)體變 量時,要引用其成員。結(jié)構(gòu)體變量中成員的引用 形式是:結(jié)構(gòu)體變量成員名例如, 結(jié)構(gòu)體變量studentl中各個成員引用形式 如下:studentl.num、student 1.name、student 1.sex、studentl .age、studentl .addressstudent1score0、studentl .score1 、studentlscore2結(jié)構(gòu)體類

9、型嵌套以上給出的例/中,結(jié)構(gòu)體成員的類型都足基本類型和數(shù)組類 型。實際上,成員的類型可以足任何數(shù)據(jù)類些。下而給出成員類型 是另-個結(jié)構(gòu)體類型的例子。例如:struct date/* 日期結(jié)構(gòu)*7int year;int month;int day;struct studentint num;char name20;char sex;int age;struct date birthday; /* struct date為結(jié)構(gòu)體類型*7char address30);stu=102;,xhy,;M,16,1977,5,8,HbeijingH;9.2.3結(jié)構(gòu)體數(shù)組:*在例中一個結(jié)構(gòu)體變量只能處理一

10、個人的信息(如一個 學生的學號、姓名、成績等數(shù)據(jù))。但在實際應(yīng)用中經(jīng)常需 要處理一批人的信息,這時應(yīng)該使用結(jié)構(gòu)體類型的數(shù)組。定 義結(jié)構(gòu)體數(shù)組與定義結(jié)構(gòu)體變量的方法相同。例如:struct studentint num;char name20;char sex;int age;float score;char address30; stu3J;【例92】候選人得票統(tǒng)計程序。設(shè)冇3個候選人,10個投票人,輸入得票人的名字并進行統(tǒng) 計,謚后輸出各人得票結(jié)果?!境绦虼a】include string.hinclude stdio.hstruct personcharname20;廣候選人姓名/int

11、count;廣候選人票數(shù)/leader(3=wstar-.O.Mmeryn.O. sunM.O):廣定義結(jié)構(gòu)體數(shù)細井初始化/main()int i.j;char leadername20;for(i=1 ;iv=10;i+)scanf(R%sw,leader_name);for(j0;jv3;j+)if(strcmp(leader_name,)-0)廣比較輸入的劣字與仗選人的名字,leaderj.count+;/*相為于leaderj.count= leaderj.count +1 ;*/printf(W);for(i=0;i3;i+)prin tf(%5s:%dnM,

12、leaderi. nameleaderi.count);9.2.4結(jié)構(gòu)體指針結(jié)構(gòu)體指針是指基類型為結(jié)構(gòu)體類型的指針 變量。通過結(jié)構(gòu)體指針可以間接訪問結(jié)構(gòu)體 中的成員。【例 93】使用結(jié)構(gòu)體指針輸出學生基本信息。 【程序代碼】#include string.h”include stdio.h” main()struct student/*定義一個結(jié)構(gòu)體類空/long num;char namc20;char sex;float score;;struct student stu/p;r定義結(jié)構(gòu)體變ftslu和結(jié)構(gòu)體指針p 7p=&stu;/*結(jié)構(gòu)體指針pJ旨向結(jié)構(gòu)體變量stu */stu

13、.num=101;strcpy(,MXuhuayuM);stu.sex=,M,;stu.score=90.0;printf(HNo.:%ldn name:%s nsex:%c nscore:%frr,stunum,stuname,stusex,stuscore);pnntf(HNo.:%ldnname:%snsex:%cnscore:%fnM,(*p).num,(*p).name,(*p).sex,(*p).score);:程序分析:程序中將結(jié)構(gòu)體變量Stu的地址賦給指針變量p,也就是便p指向Stu,然后對Stu的容成員賦值, 第一個printf(j函藪輸出stu葩畧個戒員舸值

14、,第 二個printf譎數(shù)也是用乗輸出stu各成員的值,彳旦 使由俯是Cp).num這梓的形衣。:通過結(jié)構(gòu)體指針引用成員的方式有兩種:1CP)成員名2p成員名(。為指向運算符)指針變量可以指向結(jié)構(gòu)體變量,當然也可以指向 結(jié)構(gòu)體數(shù)組,其使用方法與指向數(shù)組的指針的使 用方法類似,只不過把普通數(shù)組換成了結(jié)構(gòu)體數(shù) 組。【例94】 使川指向結(jié)構(gòu)體數(shù)組的指針實現(xiàn)多名學生信息的輸出。 【程序代碼】#includeHstdio.htfstruct student int num;char name20;char sex;int age;struct studentstu3=101 ,”Xuhy;M;18,10

15、2/Liuhm,M194103/LpH;F,20;main()struct student *p;廠定義結(jié)構(gòu)體指針*/printf(HNo. Name sex agenM);for(p=stu;pnum,p-name,p-sex,p-age);9.3鏈表 9.3.1鏈表的基本結(jié)構(gòu)鏈表是一種動態(tài)數(shù)據(jù)結(jié)構(gòu),可根據(jù)需要動態(tài) 地開辟存儲空間,隨時釋放不再需要的存儲空間。 這樣可以有效利用存儲空間,提高存儲空間利用率。 下圖是一種單向鏈表結(jié)構(gòu)示意圖。head1658254610241236:鏈表中的每個元素稱為鏈表的結(jié)點,每個結(jié) 點中包括兩部分內(nèi)容,即用戶需要的數(shù)據(jù)和 下一個結(jié)點的地址,也就是說,鏈表中

16、的每 個結(jié)點是由數(shù)據(jù)域和指針域組成。在鏈表中通常用一個指針指向鏈奏開頭的結(jié) 點,該指軒祿為頭指針。囪9-3卸h ead即気 頭指針,它指向第一個結(jié)點。:單向鏈表中前一個結(jié)點的指針域指向后一個 結(jié)點,這梅苛以通過前一個結(jié)點引用潔一個 結(jié)點。最后一個結(jié)點不再指向其他結(jié)點,稱 為尾結(jié)點(即表尾),衛(wèi)的指針域的值是NULL(空指針),表示整個鏈表到此結(jié)束。【例9-5】建立一個簡單鏈表,它由3個存放學欝囂杲夢翥f姓名)的結(jié)點組成10510577.577.5NULLNULL【程序代碼】include stdio.h” struct nodeint num;r存儲學生學號/float score;/*存儲學

17、生成績7struct node next;/*圧義結(jié)構(gòu)體指指向卜個絆點;main()struct node a,b,c,*head/p;a. num=101:a.score=85.4;r給結(jié)點a的num和score域賦ftV/b. num=103;b.score=96.1;r給結(jié)點b的num和score域賦值Vc. num=105;c.score=77.5;/* 給結(jié)點c的num和score域奴值 */head=&a;/頭指針head指向結(jié)點aTa. next=&b;/*鏈接結(jié)點b和a結(jié)點/b. next=&c;/*鏈接結(jié)點c和b結(jié)點c. next=NULL; /*結(jié)點

18、c為尾結(jié)點 Tp=head; /S 史P指針指向第1個結(jié)點/do/依次輸出丼結(jié)點數(shù)據(jù)/printf(M學巧二滋成纟貞:%5.2fn,p-num,p-score);p-p-ext; /指針p后移.指向卜一結(jié)點/Jwhile (p!NULL); 9.3.2鏈表的基本操作1.動態(tài)分配和釋放存儲區(qū)動態(tài)開辟存儲空間需要使用malloc()函數(shù),釋 放存儲空間使用free()函數(shù)。這些函數(shù)包含在頭文 件”stdlib.h”中。(1) malloc()函數(shù)函數(shù)調(diào)用的一般形式為:malloc(size)功能:在內(nèi)存申請分配一個size字節(jié)的存儲區(qū)。調(diào) 用結(jié)果為新分配的存儲區(qū)的首地址,是一個void*類型指針,

19、若申請失敗,則返回NULL。例如:struct node *p;p=(struct node *)malloc(sizeof(struct no de);上面語句中sizeofMC語言的運算符,功能是計算數(shù)據(jù)類型 或變量所占的字節(jié)數(shù),sizeof(struct node)是計算struct node類型所占的字節(jié)數(shù),那么malloc(sizeof(struct node)的功能是申請分配一個struct node類型所需大小的存儲區(qū)。 由于malloc()的返回值是無類型指針,而指針p的基類型是struct node類型,因此需要進行強制類型轉(zhuǎn)換,將malloc()函數(shù)的返回值轉(zhuǎn)換為指向str

20、uct node類型的指針。(2) free()函數(shù)函數(shù)調(diào)用的一般形式為:free(p)功能: 釋放指針p所指向的動態(tài)存儲區(qū)。2.建立單向鏈表建立動態(tài)鏈表是指在程序執(zhí)行過程中從無到有地 建立起一個鏈表,即一個一個地開辟結(jié)點和輸入 結(jié)點數(shù)據(jù),并建立起前后鏈接關(guān)系?!纠?-6】建立鏈表函數(shù)。建立一個有若干名學 生數(shù)據(jù)的單向動態(tài)鏈表,當輸入的學生學號 為0時結(jié)束操作。int num; float score; struct node 5ext;:struct node *create()struct node *head/s/p;int c:float x;head(struct nodett)ma

21、lloc(sizeof(struct node);/I成頭結(jié)點/p=head;向第個結(jié)點/print-, glj輸入結(jié)來:E);scanf(-%d%r.&c.&x);/輸入學生數(shù)抵 */while (c?=0)s=(struct node#)malloc(sizeof(struct node); /生成新結(jié)點s*/ s-num=c;/將讀入的孚生學號存放到新結(jié)點s的數(shù)撫域中s-score-x;廣將瀆入的學生成細仔放到新給點s的數(shù)抄;域中丿p-next=s;廣將新給點s插入到駁兀/p=s;/修改盡折針p抵向為詢的用結(jié)點/scanf(R%d%r.&c.&x);rE入

22、新的學生數(shù)據(jù)/p-nexUNULL;廣軻冊肩個結(jié)點的指什域?為空return(head);廣返冋頭【程序代碼】#include stdio.hinclude ” stdlib.h”struct nodehead3.輸出鏈表【例97】輸出鏈表函數(shù)。【程序代碼】void print(struct node *head)struct node *p;printfCM輸出學生結(jié)點信息n”);p=head-next;廣指針p指向第1個結(jié)點*/while (p!=NULL)printf(”學號:d成績:%5.1fn,p-num,p-score);p=p-next;廣指針p后移,指向下一結(jié)點74刪除鏈表中的

23、結(jié)點從鏈表中刪去一個結(jié)點,首先要找到這個結(jié)點,然后把它從鏈表中分 離開來,撤銷原*的鏈接關(guān)系,同時保證原有鏈衣的鏈接關(guān)系?!纠?-8】刪除結(jié)點函數(shù),刪除鏈表中學號為num的結(jié)點?!揪幊趟悸贰?1)刪除結(jié)點操作分兩步完成。第一步查找要刪除的結(jié)點,第二步進 行刪除。(2)查找結(jié)點時,從p指向的第一個結(jié)點幵始,檢查該結(jié)點中的num值足否等于輸入的要求刪除的那個學號,如果相等,就找到了要刪 除的結(jié)點,如不和等,就將p后移一個結(jié)點,直到找到要刪除的結(jié)點 或者遇到鏈尾為止。在移動p的同時移動6 使用q記錄P的前驅(qū)結(jié)點, 如圖9-6(a)所示。(3)找到待刪除結(jié)點后,使q指向要刪除結(jié)點p的后繼結(jié)點,如圖96

24、(b)所示,然后釋放結(jié)點p的內(nèi)存空間,如圖96(c)所示?!境绦虼a】struct node *del(struct node *head,int num) struct node *p,*q;q=head;p=head-next;while(num!=p-num&p!=NULL)q=p;p=p-n ext;if(num=p-num)q-next=p-next;free(p);elseprintfC 沒有找到學號為d 的結(jié)點! nnum); return(head);5.在鏈表中插入結(jié)點對鏈表的插入是指將一個結(jié)點插入到一個已 有的鏈表中,為了能做到正確插入,必須解 決兩個問題:如何找到

25、插入的位置;如何實 現(xiàn)插入?!纠?-9】插入結(jié)點函數(shù)。假定原鏈表結(jié)點已經(jīng)按學號從小到大排列。struct node *ins(struct node *head,int c,float x)struct node *p,*q,*s;s=(struct node *)malloc(sizeof(struct node);廣生成新結(jié)點 s*/ s-num=c;廣將耍插入的學牛學號存放到新結(jié)點 s 的數(shù)據(jù)域中/ s-score=x;廣將耍插入的學生成績存放到新結(jié)點 s 的數(shù)據(jù)域中/ q=head;p=head-An ext;while (p!=NULL&cp-num)q=p; p=p-nex

26、t;q-next=s; if(p!=NULL) sn ext=p;elses-n ext=NULL; return(head);程序分析:首先定義一個新結(jié)點存儲待插入的結(jié)點信息(如 圖97中的結(jié)點s),從指針p指向第一個結(jié)點開 始, 將p-nu【程序代碼】口與時目比較,如果cp-num,將p后移,并使q始終指向p的前驅(qū)結(jié)點,如圖9-7(a)所示,直到p-num-c為止,這時找到新結(jié)點的 插入位置。如果插入位置是鏈表的尾部,將新結(jié)點插到鏈尾 即可。如果插入位置在鏈表中間, 則讓s-next指向p結(jié)點, 如圖9-7(b)所示,然后讓qnext指向s結(jié)點,如 圖9-7(c)所示。9.3.3鏈表綜合應(yīng)

27、用【例910】編制主函數(shù).調(diào)用鏈表建立函數(shù),輸出函數(shù),刪除函數(shù)及插入函數(shù),完 成鏈農(nóng)的基木操作?!境绦虼a】main()struct nodo *h;int del_num,in_num;float in score;h=create();廣建立鏈表/print(h);/*輸出鏈農(nóng)7printfC*n輸入要刪除的學生結(jié)點的學號:rT); scanf(M%dK,&del num);h=del(h,deLnum);廣刪除鏈表結(jié)點/print(h);廣輸出鏈0/printf(Mn輸入耍插入的學生結(jié)點信息:iT);scanf(%d%fH,&in_num&n_score);h=i

28、ns(h,in_num,in_score);/插入結(jié)點/print(h);/嘯出鏈表*/程序運行過程為:.學號為p時揄入結(jié)宏,鎬岀*住纟吉點佶息 2 人應(yīng)巒8S.0,嚴臺纏.12匕成堪,3說績.95.088.DGS. A輸出學些結(jié)點信息I,1.比逸*S5-0 a 95.0I 1”成紐h 65.U9.4結(jié)構(gòu)體應(yīng)用實例【例910】 某班有45名學生, 現(xiàn)在對他們的期末考試 成績進行統(tǒng)計。假定期末考3門課,分別為物理、 數(shù)學和化學,要求計算每個學生的平均成績和總成 績,最后計算本班每門課的平均成績?!揪幊趟悸贰浚?)木程序分成三部分: 學生數(shù)拯輸入 (包扌舌計算學生平 均成績和總成績)、學生成績單輸

29、出、本班每門課總成 絨和平均成績的計算和輸出,分別由三個函數(shù)來實現(xiàn), 在主程序中調(diào)用這三個函數(shù)。(2)定義結(jié)構(gòu)體來存儲學生數(shù)據(jù),包括學生基木信息,學 生三門課成績(利用數(shù)組),平均成績,總成績。(3)將結(jié)構(gòu)體數(shù)組地址作為實參傳遞給函數(shù),以便在函數(shù) 中使用結(jié)構(gòu)體指針對學生數(shù)據(jù)進行操作。(W代碼】律include stdio.h*#include conio.h*#include string.h常define NU 3/*以3名學牛為例*/struct studentlong num;/定義成員變敏.存儲學生學號/char name(10;廣定義成員變f乙 儲學生姓名/float score3;廣定義成員變仃儲學門課的成絨/float aver_person;/疋義成員變爪儲學生平均成績/float sum_person;/定義成 8 變仔儲學生總成絨/;void print(structstudent *p)/輸出個人成纟列I/int i;for(i0;inum); printfOtirt:幺x %sn*.p-name); printfCVt數(shù)學4 %5.1f | p-score0);printf(物理:%5.1f p s

溫馨提示

  • 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

提交評論