




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第十一章結(jié)構(gòu)和聯(lián)合
概述本章將主要介紹C語(yǔ)言中的構(gòu)造數(shù)據(jù)類(lèi)型:結(jié)構(gòu)體、聯(lián)合以及用戶自定義類(lèi)型等。知識(shí)點(diǎn)結(jié)構(gòu)體的定義、變量的說(shuō)明和引用聯(lián)合定義、變量的說(shuō)明和引用本章章節(jié)11.1結(jié)構(gòu)的說(shuō)明與引用 11.2結(jié)構(gòu)數(shù)組的聲明、引用和初始化 11.3聯(lián)合11.4應(yīng)用程序舉例 11.5常見(jiàn)錯(cuò)誤解析 11.6本章小結(jié)11.1結(jié)構(gòu)的說(shuō)明與引用“結(jié)構(gòu)”是一種構(gòu)造類(lèi)型,它是由若干“成員”組成的。每一個(gè)成員可以是一個(gè)基本數(shù)據(jù)類(lèi)型或者又是一個(gè)構(gòu)造類(lèi)型。定義一個(gè)結(jié)構(gòu)的一般形式為:struct結(jié)構(gòu)名
{成員表列};成員表列由若干個(gè)成員組成,每個(gè)成員都是該結(jié)構(gòu)的一個(gè)組成部分。對(duì)每個(gè)成員也必須作類(lèi)型說(shuō)明,其形式為:類(lèi)型說(shuō)明符成員名;例如:
structstu{intnum;charname[20];charsex;floatscore;};在這個(gè)結(jié)構(gòu)定義中,結(jié)構(gòu)名為stu,該結(jié)構(gòu)由4個(gè)成員組成。第一個(gè)成員為num,整型變量;第二個(gè)成員為name,字符數(shù)組;第三個(gè)成員為sex,字符變量;第四個(gè)成員為score,實(shí)型變量。說(shuō)明結(jié)構(gòu)變量有以下三種方法先定義結(jié)構(gòu),再說(shuō)明結(jié)構(gòu)變量。如:structstu{intnum;charname[20];charsex;floatscore;};structstustudent1,student2;在定義結(jié)構(gòu)類(lèi)型的同時(shí)說(shuō)明結(jié)構(gòu)變量。例如:structstu{intnum;charname[20];charsex;floatscore;}student1,student2;直接說(shuō)明結(jié)構(gòu)變量。例如:struct{intnum;charname[20];charsex;floatscore;}student1,student2;這種形式的說(shuō)明的一般形式為:struct{成員表列}變量名表列;三種方法中說(shuō)明的student1,student2變量都具有下圖所示的結(jié)構(gòu)成員也可以又是一個(gè)結(jié)構(gòu),即構(gòu)成了嵌套的結(jié)構(gòu)。,下圖給出了另一個(gè)數(shù)據(jù)結(jié)構(gòu)。按圖可給出以下結(jié)構(gòu)定義:structdate{intmonth;intday;intyear;};Struct{intnum;charname[20];charsex;structdatebirthday;floatscore;}student1,student2;首先定義一個(gè)結(jié)構(gòu)date,由month(月)、day(日)、year(年)三個(gè)成員組成。在定義并說(shuō)明變量student1和student2時(shí),其中的成員birthday被說(shuō)明為data結(jié)構(gòu)類(lèi)型。成員名可與程序中其它變量同名,互不干擾。定義了結(jié)構(gòu)體變量以后,便可以引用這個(gè)變量。
引用時(shí)應(yīng)遵循以下規(guī)則:(1)不能將一個(gè)結(jié)構(gòu)體變量作為一個(gè)整體進(jìn)行輸入和輸出。只能對(duì)結(jié)構(gòu)體變量中的各個(gè)成員分別進(jìn)行輸入和輸出。例如,已定義student1和student2為結(jié)構(gòu)體變量并且它們已有值。不能這樣引用:printf(”%ld,%s,%c,%d,%f”,student1);
也不能用以下語(yǔ)句整體讀入結(jié)構(gòu)體變量,如:scanf(”%ld,%s,%c,%d,%d”,&student1);但可以通過(guò)賦值語(yǔ)句,把一個(gè)結(jié)構(gòu)體變量的值賦給同類(lèi)型的結(jié)構(gòu)體變量中。例如:student2=student1;則student2和student1具有相同的內(nèi)容。引用結(jié)構(gòu)體變量中成員的方式為:結(jié)構(gòu)體變量名.成員名例如:student1.num
即第一個(gè)人的學(xué)號(hào)student2.sex即第二個(gè)人的性別如果成員本身又是一個(gè)結(jié)構(gòu)則必須逐級(jí)找到最低級(jí)的成員才能使用。只能對(duì)最低級(jí)的成員進(jìn)行賦值、存取以及運(yùn)算。例如:student1.birthday.month可以對(duì)變量的成員賦值,例如:student1.num=200201001(2)對(duì)結(jié)構(gòu)體變量的成員可以像普通變量一樣進(jìn)行各種運(yùn)算。例如:student2.score=student1.score;sum=student1.score+student2.score;student1.age++;由于“.”運(yùn)算符的優(yōu)先級(jí)最高,因此student1.age++是對(duì)student1.age進(jìn)行自加運(yùn)算,而不是先對(duì)age進(jìn)行自加運(yùn)算。(3)可以引用結(jié)構(gòu)體變量成員的地址,也可以引用結(jié)構(gòu)體變量的地址。如:scanf(”%ld”,&sl.num); (輸入student1.num的值)printf(”%o”,&student1); (輸出student1的首地址)結(jié)構(gòu)體變量的地址主要用于作函數(shù)參數(shù),傳遞結(jié)構(gòu)體的地址。(4)結(jié)構(gòu)體變量的初始化和其他類(lèi)型變量一樣,對(duì)結(jié)構(gòu)體變量可以在定義時(shí)指定初始值。例如:structstu{longnum;charname[15];charsex;intage;intscore;}student1={200201001,”zhangsan”,’M’,18,86};經(jīng)過(guò)初始化后,student1.num=200201001=”zhangsan”student1.sex=’M’student1.age=18student1.score=86[例1]用輸入語(yǔ)句或賦值語(yǔ)句來(lái)完成給結(jié)構(gòu)變量賦值并輸出其值。#include"stdio.h"
intmain(){structstu{ intnum; char*name; charsex; floatscore;}student1,student2;student1.num=102;="Zhangping";printf("inputsexandscore\n");scanf("%c%f",&student1.sex,&student1.score);student2=student1;printf("Number=%d\nName=%s\n",student2.num,);printf("Sex=%c\nScore=%f\n",student2.sex,student2.score);
return0;}11.2結(jié)構(gòu)數(shù)組的聲明、引用和初始化結(jié)構(gòu)數(shù)組的每一個(gè)元素都是具有相同結(jié)構(gòu)類(lèi)型的下標(biāo)結(jié)構(gòu)變量。在實(shí)際應(yīng)用中,經(jīng)常用結(jié)構(gòu)數(shù)組來(lái)表示具有相同數(shù)據(jù)結(jié)構(gòu)的一個(gè)群體。如一個(gè)班的學(xué)生檔案,一個(gè)車(chē)間職工的工資表等。例如:structstu{intnum;char*name;charsex;floatscore;}student[5];定義了一個(gè)結(jié)構(gòu)數(shù)組student,共有5個(gè)元素,student[0]~student[4]。每個(gè)數(shù)組元素都具有structstu的結(jié)構(gòu)形式。對(duì)結(jié)構(gòu)數(shù)組可以作初始化賦值。例如:structstu{intnum;char*name;charsex;floatscore;}student[5]={{101,"Limiao","M",45},{102,"Zhangping","M",62.5},{103,"Hefang","F",92.5},{104,"Chengling","F",87},{105,"Wangming","M",58}};當(dāng)對(duì)全部元素作初始化賦值時(shí),也可不給出數(shù)組長(zhǎng)度。【例2】計(jì)算學(xué)生的平均成績(jī)和不及格的人數(shù)。#include"stdio.h"structstu{intnum;char*name;charsex;floatscore;}student[5]={{101,"Limiao",'M',45},{102,"Zhangping",'M',62.5},{103,"Hefang",'F',92.5},{104,"Chengling",'F',87},{105,"Wangming",'M',58},};intmain(){inti,c=0;floatave,s=0;for(i=0;i<5;i++){s+=student[i].score;if(student[i].score<60)c+=1;}printf("s=%.2f\n",s);ave=s/5;printf("average=%.2f\ncount=%d\n",ave,c);return0;}【例3】建立同學(xué)通訊錄#include"stdio.h"#defineNUM3structAddressBook{charname[20];charphone[10];};intmain(){structAddressBookClassMate[NUM];inti;for(i=0;i<NUM;i++){ printf("inputname:\n"); gets(ClassMate[i].name); printf("inputphone:\n"); gets(ClassMate[i].phone);}printf("name\t\t\tphone\n\n");for(i=0;i<NUM;i++)printf("%s\t\t\t%s\n",ClassMate[i].name,ClassMate[i].phone);return0;}11.3聯(lián)合“聯(lián)合”與“結(jié)構(gòu)”有一些相似之處。但兩者有本質(zhì)上的不同。在結(jié)構(gòu)中各成員有各自的內(nèi)存空間,一個(gè)結(jié)構(gòu)變量的總長(zhǎng)度是各成員長(zhǎng)度之和。而在“聯(lián)合”中,各成員共享一段內(nèi)存空間,一個(gè)聯(lián)合變量的長(zhǎng)度等于各成員中最長(zhǎng)的長(zhǎng)度。應(yīng)該說(shuō)明的是,這里所謂的共享不是指把多個(gè)成員同時(shí)裝入一個(gè)聯(lián)合變量?jī)?nèi),而是指該聯(lián)合變量可被賦予任一成員值,但每次只能賦一種值,賦入新值則沖去舊值。一個(gè)聯(lián)合類(lèi)型必須經(jīng)過(guò)定義之后,才能把變量說(shuō)明為該聯(lián)合類(lèi)型。當(dāng)一個(gè)聯(lián)合被說(shuō)明時(shí),編譯程序自動(dòng)地產(chǎn)生一個(gè)變量,其長(zhǎng)度為聯(lián)合中最大的變量長(zhǎng)度。聯(lián)合訪問(wèn)其成員的方法與結(jié)構(gòu)相同。同樣聯(lián)合變量也可以定義成數(shù)組或指針,但定義為指針時(shí),也要用"->"符號(hào),此時(shí)聯(lián)合訪問(wèn)成員可表示成:聯(lián)合名->成員名。聯(lián)合的定義
聯(lián)合也是一種新的數(shù)據(jù)類(lèi)型,它是一種特殊形式的變量。
聯(lián)合變量定義與結(jié)構(gòu)十分相似。其形式為:union聯(lián)合名
{成員表
};成員表中含有若干成員,成員的一般形式為:類(lèi)型說(shuō)明符成員名
成員名的命名應(yīng)符合標(biāo)識(shí)符的規(guī)定。
例如:定義一個(gè)聯(lián)合變量“data”。
uniondata{chara;intb;floatc;};該共用體的名稱(chēng)為data,該共用體中有三個(gè)成員,分別為a、b、c。它們占用同一個(gè)起始地址的存儲(chǔ)空間,內(nèi)存長(zhǎng)度等于最長(zhǎng)的成員的長(zhǎng)度。需要注意的是:聯(lián)合定義之后,即可進(jìn)行聯(lián)合變量說(shuō)明,被說(shuō)明為data類(lèi)型的變量,可以存放字符型量a或整型量b或存放浮點(diǎn)型量c。要么賦予字符型量,要么賦予整型量,要么賦予浮點(diǎn)型量,不能把3者同時(shí)賦予它。
聯(lián)合既可以出現(xiàn)在結(jié)構(gòu)內(nèi),它的成員也可以是結(jié)構(gòu)
例如:Struct{intage;char*addr;union{inti;char*ch;}x;}y[10];若要訪問(wèn)結(jié)構(gòu)變量y[1]中聯(lián)合x(chóng)的成員i,可以寫(xiě)成:y[1].x.i;若要訪問(wèn)結(jié)構(gòu)變量y[2]中聯(lián)合x(chóng)的字符串指針ch的第一個(gè)字符可寫(xiě)成:*y[2].x.ch;若寫(xiě)成"y[2].x.*ch;"是錯(cuò)誤的。2、聯(lián)合變量的說(shuō)明
聯(lián)合變量的說(shuō)明和結(jié)構(gòu)變量的說(shuō)明方式相同,也有三種形式。即先定義,再說(shuō)明、定義同時(shí)說(shuō)明和直接說(shuō)明。以聯(lián)合變量department為例,說(shuō)明如下:uniondepartment{intgrade;charoffice;};uniondepartmenta,b;/*說(shuō)明a,b為department類(lèi)型*/或者:uniondepartment{intgrade;charoffice;}a,b;/*同時(shí)說(shuō)明a,b為department類(lèi)型*/或者:union{intgrade;charoffice;}a,b/*直接說(shuō)明a,b為department類(lèi)型*/
經(jīng)說(shuō)明后的a,b變量均為department類(lèi)型。a,b變量的長(zhǎng)度應(yīng)等于department的成員中最長(zhǎng)的長(zhǎng)度,即等于office數(shù)組的長(zhǎng)度,共10個(gè)字節(jié)。a,b變量如賦予整型值時(shí),只使用了2個(gè)字節(jié),而賦予字符數(shù)組時(shí),可用10個(gè)字節(jié)。
3、聯(lián)合變量的賦值和使用
對(duì)聯(lián)合變量的賦值、使用都只能是對(duì)變量的成員進(jìn)行。聯(lián)合變量的成員表示為:聯(lián)合變量名.成員名例如,a被說(shuō)明為department類(lèi)型的變量之后,可使用
a.grade或a.office。不允許只用聯(lián)合變量名作賦值或其它操作。也不允許對(duì)聯(lián)合變量作初始化賦值,賦值只能在程序中進(jìn)行一個(gè)聯(lián)合變量,每次只能賦予一個(gè)成員值。一個(gè)聯(lián)合變量的值就是聯(lián)合變員的某一個(gè)成員值?!纠?1-4】設(shè)有一個(gè)教師與學(xué)生通用的表格,教師數(shù)據(jù)有姓名,年齡,身份,教研室四項(xiàng)。學(xué)生有姓名,年齡,身份,班級(jí)四項(xiàng)。編程輸入人員數(shù)據(jù),再以表格輸出。
#include<stdio.h>#defineN3intmain(){struct{charname[15];intage;charstatus;union{intgrade;charoffice[20];}depa;}body[3];inti;for(i=0;i<N;i++){ printf("inputname:\n");/*提示語(yǔ)*/ gets(body[i].name);/*gets函數(shù)接收帶空格的姓名*/ printf("inputage:\n");scanf("%d",&body[i].age);getchar();/*吸收上一句輸入的回車(chē)符*/printf("inputstatus(sort):\n"); body[i].status=getchar();if(body[i].status=='s') {getchar();/*吸收上一句輸入的回車(chē)符*/ printf("inputgrade:\n"); scanf("%d",&body[i].depa.grade);getchar();/*吸收上一句輸入的回車(chē)符*/ } else {getchar();/*吸收上一句輸入的回車(chē)符*/ printf("inputoffice:\n"); gets(body[i].depa.office); } }printf("name\t\tagestatusgrade/office\n");for(i=0;i<N;i++)
{if(body[i].status=='s')printf("%15s\t%3d%3c%20d\n",body[i].name,body[i].age,body[i].status,body[i].depa.grade);/*對(duì)齊輸出數(shù)據(jù)*/else printf("%15s\t%3d%3c%20s\n",body[i].name,body[i].age,body[i].status,body[i].depa.office);/*對(duì)齊輸出數(shù)據(jù)*/
} return0;}說(shuō)明:在處理結(jié)構(gòu)體問(wèn)題時(shí)經(jīng)常涉及字符或字符串的輸入,這時(shí)要注意:①scanf()函數(shù)用%s輸入字符串遇空格即結(jié)束,因此輸入帶空格的字符串可改用gets函數(shù)。②在輸入字符類(lèi)型數(shù)據(jù)時(shí)往往得到的是空白符(空格、回車(chē)等),甚至運(yùn)行終止,因此常作相應(yīng)處理,即在適當(dāng)?shù)牡胤皆黾觛etchar();空輸入語(yǔ)句,以消除緩沖區(qū)中的空白符。類(lèi)型定義符typedefC語(yǔ)言不僅提供了豐富的數(shù)據(jù)類(lèi)型,而且還允許由用戶自己定義類(lèi)型說(shuō)明符,也就是說(shuō)允許由用戶為數(shù)據(jù)類(lèi)型取“別名”。類(lèi)型定義符typedef即可用來(lái)完成此功能。typedef定義的一般形式為:typedef原類(lèi)型名
新類(lèi)型名
其中原類(lèi)型名中含有定義部分,新類(lèi)型名一般用大寫(xiě)表示,以便于區(qū)別。有時(shí)也可用宏定義來(lái)代替typedef的功能,但是宏定義是由預(yù)處理完成的,而typedef則是在編譯時(shí)完成的,后者更為靈活方便。例如,有整型量a,b,其說(shuō)明如下:inta,b;int的完整寫(xiě)法為integer,為了增加程序的可讀性,可把整型說(shuō)明符用typedef定義為:typedefintINTEGER這以后就可用INTEGER來(lái)代替int作整型變量的類(lèi)型說(shuō)明了。
例如:INTEGERa,b;它等效于:inta,b;用typedef定義數(shù)組、指針、結(jié)構(gòu)等類(lèi)型將帶來(lái)很大的方便,不僅使程序書(shū)寫(xiě)簡(jiǎn)單而且使意義更為明確,因而增強(qiáng)了可讀性。
例如:typedefcharNAME[20];表示NAME是字符數(shù)組類(lèi)型,數(shù)組長(zhǎng)度為20。然后可用NAME說(shuō)明變量,如:NAMEa1,a2,s1,s2;完全等效于:chara1[20],a2[20],s1[20],s2[20]又如:typedefstructstu{charname[20];intage;charsex;}STU;定義STU表示stu的結(jié)構(gòu)類(lèi)型,然后可用STU來(lái)說(shuō)明結(jié)構(gòu)變量:STUbody1,body2;11.4應(yīng)用程序舉例【例5】一個(gè)公司有10名員工,每個(gè)員工的數(shù)據(jù)包括職工號(hào)、姓名、生日和工資。請(qǐng)使用結(jié)構(gòu)體表示員工的信息,并用結(jié)構(gòu)體數(shù)組來(lái)存所有員工的數(shù)據(jù)。要求輸入10名員工的信息,計(jì)算平均工資,并輸出工資最高的員工的數(shù)據(jù)。然后對(duì)上述的員工數(shù)據(jù)數(shù)組按工資從大到小排序,并輸出排序后各員工的信息。#include<stdio.h>#defineN3/*員工個(gè)數(shù)N在下列各個(gè)函數(shù)內(nèi)的數(shù)值都是10,是不變的。*/floatavesalary;structst{ intnum; charname[20]; charbirth[20]; floatsalary;};voidinput(structsta[])/*輸入所有員工信息*/{ inti; for(i=0;i<N;i++){ printf("職工號(hào),姓名,出生日期,工資:\n"); scanf("%d%s%s%f",&a[i].num,a[i].name,&a[i].birth,&a[i].salary); }}voidaves(structstb[])/*求出所有員工的平均工資*/{ inti; floattotal=0; for(i=0;i<N;i++) total=total+b[i].salary; avesalary=total/N;}voidsort(structstc[])/*按員工工資從高到低進(jìn)行排序*/{ inti,j; structstt; for(i=0;i<N-1;i++) for(j=0;j<N-1-i;j++) if(c[j].salary<c[j+1].salary) { t=c[j]; c[j]=c[j+1]; c[j+1]=t; }}voidoutputmax(structstd[])/*輸出最高工資的員工信息*/{ printf("最高工資的員工信息:職工號(hào)%d,姓名%s,生日%s,工資%.2f\n",d[0].num,d[0].name,d[0].birth,d[0].salary);}voidoutputall(structst
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 資產(chǎn)使用協(xié)議書(shū)
- 道路搭火協(xié)議書(shū)
- 自愿訓(xùn)練協(xié)議書(shū)
- 綠城廉潔協(xié)議書(shū)
- 選房意向協(xié)議書(shū)
- 實(shí)驗(yàn)實(shí)訓(xùn)室借用協(xié)議書(shū)
- 遺增撫養(yǎng)協(xié)議書(shū)
- 廣西和螞蟻合作協(xié)議書(shū)
- 實(shí)習(xí)生技術(shù)轉(zhuǎn)讓協(xié)議書(shū)
- 鄭州婚前協(xié)議書(shū)
- 2025年度幼兒園教師編制考試全真模擬試題及答案(共五套)
- 新媒體業(yè)務(wù)面試題及答案
- 廣東省廣州市2025年中考地理模擬測(cè)試卷(含答案)
- 食堂應(yīng)急預(yù)案管理制度
- 安全生產(chǎn)法律法規(guī)基本知識(shí)
- 2025年新高考?xì)v史預(yù)測(cè)模擬試卷黑吉遼蒙卷(含答案解析)
- 2025高考語(yǔ)文名校作文題立意與例文參考11篇
- 2025年高三語(yǔ)言復(fù)習(xí)【文字運(yùn)用題】專(zhuān)項(xiàng)練習(xí)卷附答案解析
- 申報(bào)企業(yè)高級(jí)工程師職稱(chēng)述職報(bào)告
- 5.2《稻》教案-【中職專(zhuān)用】高二語(yǔ)文同步教學(xué)(高教版2023·拓展模塊下冊(cè))
- 突破困境的智慧主題班會(huì)
評(píng)論
0/150
提交評(píng)論