高級(jí)語言程序設(shè)計(jì)(CC++版) 課件 第8章 結(jié)構(gòu)體_第1頁
高級(jí)語言程序設(shè)計(jì)(CC++版) 課件 第8章 結(jié)構(gòu)體_第2頁
高級(jí)語言程序設(shè)計(jì)(CC++版) 課件 第8章 結(jié)構(gòu)體_第3頁
高級(jí)語言程序設(shè)計(jì)(CC++版) 課件 第8章 結(jié)構(gòu)體_第4頁
高級(jí)語言程序設(shè)計(jì)(CC++版) 課件 第8章 結(jié)構(gòu)體_第5頁
已閱讀5頁,還剩18頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

第8章

結(jié)構(gòu)體目錄定義結(jié)構(gòu)體類型定義結(jié)構(gòu)體變量引用結(jié)構(gòu)體成員結(jié)構(gòu)體數(shù)組與指針結(jié)構(gòu)體與單鏈表共用體類型枚舉類型用typedef聲明新類型名216:12為什么引入結(jié)構(gòu)體在現(xiàn)實(shí)問題中,常常需要用一組不同的數(shù)據(jù)組合來描述一個(gè)對(duì)象。如一名學(xué)生要用學(xué)號(hào)、姓名、性別、籍貫等信息加以描述,一名教師要用工號(hào)、姓名、性別、出生日期等信息加以描述。編程時(shí)若利用多個(gè)獨(dú)立的變量來描述一個(gè)對(duì)象勢(shì)必會(huì)導(dǎo)致極大的不便。C/C++中允許編程人員自定義結(jié)構(gòu)體類型,進(jìn)而定義該類型的變量來表示現(xiàn)實(shí)問題中的對(duì)象。316:121.定義結(jié)構(gòu)體類型C/C++中支持在已有數(shù)據(jù)類型的基礎(chǔ)上定義新的復(fù)合數(shù)據(jù)類型,用“struct”關(guān)鍵字定義一個(gè)“結(jié)構(gòu)體類型”,也就定義了一個(gè)新的復(fù)合數(shù)據(jù)類型。定義結(jié)構(gòu)體的一般格式為:struct結(jié)構(gòu)體類型名{

類型名1變量名1;

……

類型名n變量名n;};例如:structstudent{ longlongnum; stringname; charsex;}; //注意結(jié)構(gòu)體定義最后以分號(hào)結(jié)束返回416:122.

定義結(jié)構(gòu)體變量定義結(jié)構(gòu)體類型后,就可以進(jìn)一步定義該結(jié)構(gòu)體類型的變量。C/C++中可使用以下三種方法定義結(jié)構(gòu)體變量。1.先定義結(jié)構(gòu)體類型再定義該類型的變量structstudent{ longlongnum; stringname; charsex;};structstudents1,s2;2.在定義結(jié)構(gòu)體類型的同時(shí)定義該類型變量structstudent{ longlongnum; stringname; charsex;}s1,s2;3.不指定結(jié)構(gòu)體類型名而直接定義結(jié)構(gòu)體變量struct{ longlongnum; stringname; charsex;}s1,s2;返回516:123.引用結(jié)構(gòu)體成員在定義結(jié)構(gòu)體變量時(shí),可以對(duì)其初始化。同種類型的結(jié)構(gòu)體變量之間可以相互賦值,但是不能將一個(gè)結(jié)構(gòu)體變量作為一個(gè)整體進(jìn)行輸入、輸出,而只能對(duì)其成員進(jìn)行輸入、輸出。引用結(jié)構(gòu)體變量成員的一般格式為:結(jié)構(gòu)體變量名.成員名例如:structstudentstu={202103061201,"Jack",'M'};cin>>stu.num;cout<<;返回616:12如果結(jié)構(gòu)體的某成員又是一個(gè)結(jié)構(gòu)體類型變量,那么必須以級(jí)聯(lián)的方式訪問該變量。#include<iostream>usingnamespacestd;structdate{ intyear; intmonth; intday;};structstudent{ longlongnum; stringname; charsex; structdatebirthday;};intmain(){ structstudentstu={202103061201,"Jack",'M',{2003,6,7}}; cout<<stu.num<<""<<<<""<<stu.sex<<""; cout<<stu.birthday.year<<"."<<stu.birthday.month<<"."<<stu.birthday.day<<endl; return0;}716:12例8.1:好多同學(xué)報(bào)名參加了英語俱樂部舉辦的“英文金曲歌唱大賽”活動(dòng),每名選手均有5位評(píng)委打分,對(duì)每名選手去掉一個(gè)最高分、去掉一個(gè)最低分,再計(jì)算剩下打分的平均分(結(jié)果精確到小數(shù)點(diǎn)后兩位)。

輸入:測(cè)試數(shù)據(jù)包括多個(gè)實(shí)例,每個(gè)實(shí)例一行,包括選手姓名,隨后是5個(gè)實(shí)數(shù)代表評(píng)委打分。

輸出:每位選手姓名和最終得分。#include<iostream>usingnamespacestd;structstudent{charname[20];doublea[5];doublegrade;};intmain(){structstudents;while(scanf("%s%lf%lf%lf%lf%lf",,&s.a[0],&s.a[1],&s.a[2],&s.a[3],&s.a[4])!=EOF){doublesum,max,min;sum=max=min=s.a[0];for(inti=1;i<5;++i){sum=sum+s.a[i];if(s.a[i]>max)max=s.a[i];elseif(s.a[i]<min)min=s.a[i];}sum=sum-max-min;s.grade=sum/3;printf("%s%.2lf\n",,s.grade);}return0;}816:124.結(jié)構(gòu)體數(shù)組與指針元素為結(jié)構(gòu)體類型變量的數(shù)組稱為結(jié)構(gòu)體數(shù)組,定義結(jié)構(gòu)體數(shù)組的方法與定義普通數(shù)據(jù)類型數(shù)組相同。所謂結(jié)構(gòu)體指針就是指向結(jié)構(gòu)體變量的指針,一個(gè)結(jié)構(gòu)體變量的起始地址就是該結(jié)構(gòu)體變量的指針。通過結(jié)構(gòu)體指針引用成員的一般格式為:結(jié)構(gòu)體指針名->成員名返回916:12例8.2:潘小姐比武招親,第一關(guān)是身高要合格。潘小姐發(fā)現(xiàn)小明擅長編程,所以把首輪根據(jù)身高進(jìn)行選撥的任務(wù)交給了小明,如果程序編得好,小明就可以直接進(jìn)入下一輪選撥,于是小明開心地笑了。

輸入:首先輸入一個(gè)整數(shù)n(1<=n<=100),表示n名競(jìng)選者;然后是n行數(shù)據(jù),每行是參加競(jìng)選者的姓名name(name無空格且長度<20)和身高h(yuǎn)(0<h<100);最后一行是兩個(gè)整數(shù)a,b表示身高的合格范圍[a,b]。

輸出:把身高合格的競(jìng)選者信息按身高從高到低輸出,格式與輸入相同。#include<iostream>usingnamespacestd;structperson{

charname[21]; inth;};intmain(){structpersonc[101];structpersont;intn,a,b,flag;flag=0;scanf("%d",&n);for(inti=0;i<n;i++) scanf("%s%d",c[i].name,&c[i].h);for(inti=0;i<n;i++) for(intj=0;j<n-i-1;j++){if(c[j].h<c[j+1].h){t=c[j];c[j]=c[j+1];c[j+1]=t;}}scanf("%d%d",&a,&b);for(inti=0;i<n;i++) if(c[i].h>=a&&c[i].h<=b) printf("%s%d\n",c[i].name,c[i].h);return0;}1016:12例8.3:從鍵盤輸入若干個(gè)學(xué)生的信息,每個(gè)學(xué)生信息包括學(xué)號(hào)、姓名、3門課的成績,計(jì)算每個(gè)學(xué)生的總分,輸出總分最高的學(xué)生的信息。

輸入:首先輸入一個(gè)整數(shù)n(1<=n<=100),表示學(xué)生人數(shù),然后輸入n行,每行包含一個(gè)學(xué)生的信息:學(xué)號(hào)(12位)、姓名(不含空格且不超過20位),以及三個(gè)整數(shù),表示語文、數(shù)學(xué)、英語三門課成績,數(shù)據(jù)之間用空格隔開。

輸出:輸出總成績最高的學(xué)生的學(xué)號(hào)、姓名、及三門課成績,用空格隔開。若有多個(gè)最高分,只輸出第一個(gè)。#include<iostream>usingnamespacestd;structstudent{ longlongnum; stringname; inta,b,c;};intmain(){ structstudents[100]; intn; cin>>n; for(inti=0;i<n;i++) cin>>s[i].num>>s[i].name>>s[i].a>>s[i].b>>s[i].c; intv=0; intm=0; structstudent*p=&s[0]; for(inti=0;i<n;i++,p++) if(v<p->a+p->b+p->c)m=i,v=p->a+p->b+p->c; cout<<s[m].num<<""<<s[m].name<<""; cout<<s[m].a<<""<<s[m].b<<""<<s[m].c; return0;}1116:125.結(jié)構(gòu)體與單鏈表結(jié)構(gòu)體類型的成員可以是基本數(shù)據(jù)類型,也可以是結(jié)構(gòu)體類型,甚至可以是指針類型。設(shè)置一個(gè)同類型指針成員存放下一個(gè)結(jié)點(diǎn)的地址,讓每個(gè)結(jié)點(diǎn)的指針成員指向下一個(gè)結(jié)點(diǎn)的地址,最后一個(gè)結(jié)點(diǎn)的指針成員為空,便可構(gòu)成一個(gè)單鏈表。單鏈表中結(jié)點(diǎn)的結(jié)構(gòu)體描述如下:structnode{ intdata; node*next;};以上定義了一個(gè)名為node的結(jié)構(gòu)體類型,該結(jié)構(gòu)體包含兩個(gè)成員,第一個(gè)成員是存放實(shí)際整型數(shù)據(jù)data,第二個(gè)成員是指向node結(jié)構(gòu)體類型的指針next,即下一個(gè)結(jié)點(diǎn)的地址。返回1216:12例8.4:n只猴子圍坐成一個(gè)圈,按順時(shí)針方向從1到n編號(hào)。然后從1號(hào)猴子開始沿順時(shí)針方向從1開始報(bào)數(shù),報(bào)到m的猴子出局,再從剛出局猴子的下一個(gè)位置重新報(bào)數(shù),…,直至剩下一個(gè)猴子它就是大王。

輸入:輸入兩個(gè)整數(shù)n和m,1<=m<=n<=100。

輸出:輸出猴王的編號(hào)。#include<iostream>usingnamespacestd;structnode{ intdata; node*next;};intmain(){ intn,m; cin>>n>>m; node*p,*q,*head=newnode; head->next=head; for(inti=n;i>=1;i--){ p=newnode; p->data=i; p->next=head->next; head->next=p; } node*prev=head,*cur=head->next; intcount=1; while(head->next->next!=head){ while(count!=m&&cur!=head){ prev=cur; cur=cur->next;

count++; } if(cur!=head){ q=cur; cur=cur->next; prev->next=cur; deleteq; count=1; }else{ prev=head; cur=head->next; } } cout<<head->next->data; return0;}1316:126.共用體類型共用體是一種特殊的數(shù)據(jù)類型,允許在相同的內(nèi)存位置存儲(chǔ)不同的數(shù)據(jù)??梢远x一個(gè)包含多個(gè)成員的共用體,但是任何時(shí)候只能有一個(gè)成員有值。共用體提供了一種使用相同的內(nèi)存位置的有效方式。定義共用體使用關(guān)鍵詞union,定義共用體類型的一般格式為:union共用體類型名{

類型名1變量名1;

……

類型名n變量名n;};例如:unionData{ //表示不同類型的變量i,ch,f可以存放到同一段存儲(chǔ)單元中 inti; charch; floatf;}a,b,c; //在聲明類型同時(shí)定義變量“共用體”與“結(jié)構(gòu)體”的定義形式相似,但它們的含義是不同的。結(jié)構(gòu)體變量所占內(nèi)存長度是各成員所占內(nèi)存長度之和,每個(gè)成員分別占有其自己的內(nèi)存單元。而共用體變量所占的內(nèi)存長度等于最長的成員的長度,幾個(gè)成員共用一個(gè)內(nèi)存區(qū)。共用體中起作用的是最后一次存放的成員,給一個(gè)新成員賦值后,舊成員就因被覆蓋而失去了作用。返回1416:12例8.5:有多名教師和學(xué)生參加會(huì)議,學(xué)生的數(shù)據(jù)包括:姓名、性別、職業(yè)、班級(jí),教師的數(shù)據(jù)包括姓名、性別、職業(yè)、職務(wù)。要求用結(jié)構(gòu)體和共用體編程實(shí)現(xiàn)輸入輸出。

輸入:輸入一個(gè)正整數(shù)n(n<10)及n名教師或?qū)W生的信息。

輸出:輸出n名教師或?qū)W生的信息。#include<iostream>usingnamespacestd;structperson{ charname[10]; charsex; charjob; union{ //聲明無名共用體類型 intclas; //成員clas(班級(jí)) charposition[10]; //成員position(職務(wù)) }category; //成員category是共用體變量};intmain(){ intn; cin>>n; personp[100]; for(inti=0;i<n;i++){ scanf("%s%c%c",p[i].name,&p[i].sex,&p[i].job); //輸入前3項(xiàng) if(p[i].job=='s')scanf("%d",&p[i].category.clas);

//如是學(xué)生,輸入班級(jí) elseif(p[i].job=='t')scanf("%s",p[i].category.position); //如是教師,輸入職務(wù) } for(inti=0;i<n;i++) if(p[i].job=='s')printf("%s%c%c%d\n",p[i].name,p[i].sex,p[i].job,p[i].category.clas); elseprintf("%s%c%c%s\n",p[i].name,p[i].sex,p[i].job,p[i].category.position); return0;}1516:127.枚舉類型若某變量只有幾種可能的取值,則可將其定義為枚舉類型。所謂“枚舉”就是指把可能的值一一列舉出來,變量的值僅限于所列舉出的值范圍。聲明枚舉類型的一般格式為:enum[枚舉名]{枚舉元素列表};例如:enumWeekday{sun,mon,tue,wed,thu,fri,sat};enumWeekdayworkday,weekend;也可以聲明沒有名字的枚舉類型,而直接定義枚舉變量。例如:enum{sun,mon,tue,wed,thu,fri,sat}workday,weekend;說明C編譯對(duì)枚舉類型的枚舉元素按常量處理,故稱枚舉常量。不要因?yàn)樗鼈兪菢?biāo)識(shí)符(有名字)而把它們看作變量,不能對(duì)它們賦值。每一個(gè)枚舉元素都代表一個(gè)整數(shù),C語言編譯按定義時(shí)的順序默認(rèn)它們的值為0,1,2,3,4,5…。也可以在定義枚舉類型時(shí)顯式地指定枚舉元素的數(shù)值。枚舉元素可以用來作判斷比較。枚舉元素的比較規(guī)則是按其初始化時(shí)指定的整數(shù)比較。返回1616:12例8.6:口袋中有紅、黃、藍(lán)、白、黑5種顏色的球各一個(gè)。每次從口袋中先后取出3個(gè)球,問得到3種不同顏色的球的可能取法,輸出每種取法。

輸入:無。

輸出:每種取法(按紅、黃、藍(lán)、白、黑字典序)。#include<iostream>usingnamespacestd;intmain(){ enumColor{red,yellow,blue,white,black}; intcnt=0,cur,loop; for(inti=red;i<=black;i++) for(intj=red;j<=black;j++) for(intk=red;k<=black;k++) if((i!=j)&&(i!=k)&&(j!=k)){ cnt++; printf("%-4d",cnt); for(loop=1;loop<=3;loop++){ switch(loop){ case1:cur=i;break; case2:cur=j;break; case3:cur=k;break; default:break; } switch(cur){ //根據(jù)球的顏色輸出相應(yīng)的文字 casered:printf("%-10s","red");break; caseyellow:printf("%-10s","yellow");break; caseblue:printf("%-10s","blue");break; casewhite:printf("%-10s","white");break; caseblack:printf("%-10s","black");break; default:break; } } printf("\n"); } return0;}1716:128.用typedef聲明新類型名1.簡(jiǎn)單地用一個(gè)新的類型名代替原有的類型名2.命名一個(gè)簡(jiǎn)單的類型名代替復(fù)雜的類型表示方法①命名一個(gè)新的類型名代表結(jié)構(gòu)體類型

命名一個(gè)新的類型名代表數(shù)組類型③命名一個(gè)新的類型名代表指針類型

④命名一個(gè)新的類型名代表指向函數(shù)的指針類型typedefstruct{ intmonth; intday;intyear;}Date; //聲明了一個(gè)新類型名Date,代表結(jié)構(gòu)體類型Datebirthday; //定義結(jié)構(gòu)體類型變量birthday,不要寫成structDatebirthday;Date*p; //定義結(jié)構(gòu)體指針變量p,指向此結(jié)構(gòu)體類型數(shù)據(jù)typedefintNum[100]; //聲明Num為整型數(shù)組類型名Numa; //定義a為整型數(shù)組名,它有100個(gè)元素typedefchar*String; //聲明String為字符指針類型Stringp,s[10]; //定義p為字符指針變量,s為字符指針數(shù)組typedefint(*Pointer)(); //聲明Pointer為指向函數(shù)的指針類型,該函數(shù)返回整型值Pointerp1,p2; //p1,p2為Pointer類型的指針變量18typedefintInteger; //指定用Integer為類型名,作用與int相同typedeffloatReal; //指定用Real為類型名,作用與float相同返回16:12用typedef聲明新類型名聲明一個(gè)新的類型名的方法是:①先按定義變量的方法寫出定義體(如:inti;)

②將變量名換成新類型名(例如:將i換成Count)③在最前面加typedef(例如:typedefintCount)

④然后可以用新類型名去定義變量簡(jiǎn)單講,就是按定義變量的方式把變量名換上新類型名,并在最前面加typedef,就聲明了新類型名代表原來的類型。以定義上述的數(shù)組類型為例來說明:①先按定義數(shù)組變量形式書寫:inta[100] ②將變量名a換成自己命名的類型名:intNum[100]③在前面加上typedef,得到typedefintNum[100] ④用來定義變量:Numa;相當(dāng)于定義了:inta[100];同樣,對(duì)字符指針類型,也是:①char*p; //定義變量p的方式

②char*String; //用新類型名String取代變量名p③typedefchar*String; //加typedef ④Stringp; //用新類型名String定義變量,相當(dāng)char*p;習(xí)慣上,常把用typedef聲明的類型名的第1個(gè)字母用大寫表示,以便與系統(tǒng)提供的標(biāo)準(zhǔn)類型標(biāo)識(shí)符相區(qū)別。1916:12用typedef聲明新類型名(1)

typedef的方法實(shí)際上是為特定的類型指定了一個(gè)同義字(synonyms)。(2)用typedef只是對(duì)已經(jīng)存在的類型指定一個(gè)新的類型名,而沒有創(chuàng)造新的類型。(3)用typedef聲明數(shù)組類型、指針類型,結(jié)構(gòu)體類型、共用體類型、枚舉類型等,使得編程更加方便。(4)typedef與#define表面相同實(shí)質(zhì)不同。#define是在預(yù)編譯時(shí)處理的,它只能作簡(jiǎn)單的字符串替換,而typedef是在編譯階段處理的,且并非簡(jiǎn)單的字符串替換。(5)當(dāng)不同源文件中用到同一類型數(shù)據(jù)(尤其是像數(shù)組、指針、結(jié)構(gòu)體、共用體等類型數(shù)據(jù))時(shí),常用typedef聲明一些數(shù)據(jù)類型。可以把所有的typedef名稱聲明單獨(dú)放在一個(gè)頭文件中,然后在需要用到它們的文件中用#include指令把它們包含到文件中。這樣編程者就不需要在各文件中自己定義typedef名稱了。(6)使用typedef名稱有利于程序的通用與移植。有時(shí)程序會(huì)依賴于硬件特性,用typedef類型就便于移植。2016:12例8.7:一個(gè)藏寶山洞出現(xiàn)在阿里巴巴面前,山洞里堆滿了n件寶物,每件物品有價(jià)值和質(zhì)量兩種屬性??墒前⒗锇桶蜕砩现挥幸粋€(gè)口袋,他只能挑選三件寶物。請(qǐng)按價(jià)值降序,若價(jià)值相同則按質(zhì)量升序排列一下這n件寶物。

輸入:第一行輸入一個(gè)整數(shù)n(1<=n<=1000)表示n件寶物;第二行有n個(gè)正整數(shù)pi代表每件物品的價(jià)值,第三行有n個(gè)正整數(shù)wi代表每件物品的質(zhì)量(1<pi,wi<10000)。

輸出:輸出共n行,每行兩個(gè)數(shù)pi,wi,順序如題所述。#include<iostream>usingnamespacestd;structtreasure{intp;intw;};intmain(){structtreasures[10001];structtreasuret;intn;while(scanf("%d",&n)!=EOF){for(inti=0;i<n;i++) scanf("%d",&s[i].p);for(inti=0;i<n;i++) scanf("%d",&s[i].w);for(inti=0;i<n;i++)for(intj=0;j<n-i-1;j++){if(s[j].p<s[j+1].p){t=s[j];s[j]=s[j+1];s[j+1]=t;}elseif(s[j].p==s[j+1].p){if(s[j].w>s[j+1].w){t=s[j];s[j]=s[j+1];s[j+1]=t;}}}for(inti=0;i<n;i++)printf("%d%d\n",s[i].p,s[i].w);}return0;}2116:12例8.8:二叉排序樹二叉排序樹,也稱為二叉查找樹??梢允且活w空樹,也可以是一顆具有如下特性的非空二叉樹:(1)若左子樹非空,則左子樹上所有節(jié)點(diǎn)關(guān)鍵字值均不大于根節(jié)點(diǎn)的關(guān)鍵字值;(2)若右子樹非空,則右子樹上所有節(jié)點(diǎn)關(guān)鍵字值均不小于根節(jié)點(diǎn)的關(guān)鍵字值;(3)左、右子樹本身也是一顆二叉排序樹?,F(xiàn)在給定N個(gè)關(guān)鍵字值各不相同的節(jié)點(diǎn),要求按順序插入一個(gè)初始為空樹的二叉排序樹中,每次插入成功后求相應(yīng)的父親節(jié)點(diǎn)的關(guān)鍵字值,如果沒有父親節(jié)點(diǎn),則輸出-1。輸入:

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論