C語言程序設計課件09 結(jié)構(gòu)和聯(lián)合李萍_第1頁
C語言程序設計課件09 結(jié)構(gòu)和聯(lián)合李萍_第2頁
C語言程序設計課件09 結(jié)構(gòu)和聯(lián)合李萍_第3頁
C語言程序設計課件09 結(jié)構(gòu)和聯(lián)合李萍_第4頁
C語言程序設計課件09 結(jié)構(gòu)和聯(lián)合李萍_第5頁
已閱讀5頁,還剩30頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第十一章結(jié)構(gòu)和聯(lián)合

概述本章將主要介紹C語言中的構(gòu)造數(shù)據(jù)類型:結(jié)構(gòu)體、聯(lián)合以及用戶自定義類型等。知識點結(jié)構(gòu)體的定義、變量的說明和引用聯(lián)合定義、變量的說明和引用本章章節(jié)11.1結(jié)構(gòu)的說明與引用 11.2結(jié)構(gòu)數(shù)組的聲明、引用和初始化 11.3聯(lián)合11.4應用程序舉例 11.5常見錯誤解析 11.6本章小結(jié)11.1結(jié)構(gòu)的說明與引用“結(jié)構(gòu)”是一種構(gòu)造類型,它是由若干“成員”組成的。每一個成員可以是一個基本數(shù)據(jù)類型或者又是一個構(gòu)造類型。定義一個結(jié)構(gòu)的一般形式為:struct結(jié)構(gòu)名

{成員表列};成員表列由若干個成員組成,每個成員都是該結(jié)構(gòu)的一個組成部分。對每個成員也必須作類型說明,其形式為:類型說明符成員名;例如:

structstu{intnum;charname[20];charsex;floatscore;};在這個結(jié)構(gòu)定義中,結(jié)構(gòu)名為stu,該結(jié)構(gòu)由4個成員組成。第一個成員為num,整型變量;第二個成員為name,字符數(shù)組;第三個成員為sex,字符變量;第四個成員為score,實型變量。說明結(jié)構(gòu)變量有以下三種方法先定義結(jié)構(gòu),再說明結(jié)構(gòu)變量。如:structstu{intnum;charname[20];charsex;floatscore;};structstustudent1,student2;在定義結(jié)構(gòu)類型的同時說明結(jié)構(gòu)變量。例如:structstu{intnum;charname[20];charsex;floatscore;}student1,student2;直接說明結(jié)構(gòu)變量。例如:struct{intnum;charname[20];charsex;floatscore;}student1,student2;這種形式的說明的一般形式為:struct{成員表列}變量名表列;三種方法中說明的student1,student2變量都具有下圖所示的結(jié)構(gòu)成員也可以又是一個結(jié)構(gòu),即構(gòu)成了嵌套的結(jié)構(gòu)。,下圖給出了另一個數(shù)據(jù)結(jié)構(gòu)。按圖可給出以下結(jié)構(gòu)定義:structdate{intmonth;intday;intyear;};Struct{intnum;charname[20];charsex;structdatebirthday;floatscore;}student1,student2;首先定義一個結(jié)構(gòu)date,由month(月)、day(日)、year(年)三個成員組成。在定義并說明變量student1和student2時,其中的成員birthday被說明為data結(jié)構(gòu)類型。成員名可與程序中其它變量同名,互不干擾。定義了結(jié)構(gòu)體變量以后,便可以引用這個變量。

引用時應遵循以下規(guī)則:(1)不能將一個結(jié)構(gòu)體變量作為一個整體進行輸入和輸出。只能對結(jié)構(gòu)體變量中的各個成員分別進行輸入和輸出。例如,已定義student1和student2為結(jié)構(gòu)體變量并且它們已有值。不能這樣引用:printf(”%ld,%s,%c,%d,%f”,student1);

也不能用以下語句整體讀入結(jié)構(gòu)體變量,如:scanf(”%ld,%s,%c,%d,%d”,&student1);但可以通過賦值語句,把一個結(jié)構(gòu)體變量的值賦給同類型的結(jié)構(gòu)體變量中。例如:student2=student1;則student2和student1具有相同的內(nèi)容。引用結(jié)構(gòu)體變量中成員的方式為:結(jié)構(gòu)體變量名.成員名例如:student1.num

即第一個人的學號student2.sex即第二個人的性別如果成員本身又是一個結(jié)構(gòu)則必須逐級找到最低級的成員才能使用。只能對最低級的成員進行賦值、存取以及運算。例如:student1.birthday.month可以對變量的成員賦值,例如:student1.num=200201001(2)對結(jié)構(gòu)體變量的成員可以像普通變量一樣進行各種運算。例如:student2.score=student1.score;sum=student1.score+student2.score;student1.age++;由于“.”運算符的優(yōu)先級最高,因此student1.age++是對student1.age進行自加運算,而不是先對age進行自加運算。(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)體變量的初始化和其他類型變量一樣,對結(jié)構(gòu)體變量可以在定義時指定初始值。例如:structstu{longnum;charname[15];charsex;intage;intscore;}student1={200201001,”zhangsan”,’M’,18,86};經(jīng)過初始化后,student1.num=200201001=”zhangsan”student1.sex=’M’student1.age=18student1.score=86[例1]用輸入語句或賦值語句來完成給結(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ù)組的每一個元素都是具有相同結(jié)構(gòu)類型的下標結(jié)構(gòu)變量。在實際應用中,經(jīng)常用結(jié)構(gòu)數(shù)組來表示具有相同數(shù)據(jù)結(jié)構(gòu)的一個群體。如一個班的學生檔案,一個車間職工的工資表等。例如:structstu{intnum;char*name;charsex;floatscore;}student[5];定義了一個結(jié)構(gòu)數(shù)組student,共有5個元素,student[0]~student[4]。每個數(shù)組元素都具有structstu的結(jié)構(gòu)形式。對結(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}};當對全部元素作初始化賦值時,也可不給出數(shù)組長度?!纠?】計算學生的平均成績和不及格的人數(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】建立同學通訊錄#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)存空間,一個結(jié)構(gòu)變量的總長度是各成員長度之和。而在“聯(lián)合”中,各成員共享一段內(nèi)存空間,一個聯(lián)合變量的長度等于各成員中最長的長度。應該說明的是,這里所謂的共享不是指把多個成員同時裝入一個聯(lián)合變量內(nèi),而是指該聯(lián)合變量可被賦予任一成員值,但每次只能賦一種值,賦入新值則沖去舊值。一個聯(lián)合類型必須經(jīng)過定義之后,才能把變量說明為該聯(lián)合類型。當一個聯(lián)合被說明時,編譯程序自動地產(chǎn)生一個變量,其長度為聯(lián)合中最大的變量長度。聯(lián)合訪問其成員的方法與結(jié)構(gòu)相同。同樣聯(lián)合變量也可以定義成數(shù)組或指針,但定義為指針時,也要用"->"符號,此時聯(lián)合訪問成員可表示成:聯(lián)合名->成員名。聯(lián)合的定義

聯(lián)合也是一種新的數(shù)據(jù)類型,它是一種特殊形式的變量。

聯(lián)合變量定義與結(jié)構(gòu)十分相似。其形式為:union聯(lián)合名

{成員表

};成員表中含有若干成員,成員的一般形式為:類型說明符成員名

成員名的命名應符合標識符的規(guī)定。

例如:定義一個聯(lián)合變量“data”。

uniondata{chara;intb;floatc;};該共用體的名稱為data,該共用體中有三個成員,分別為a、b、c。它們占用同一個起始地址的存儲空間,內(nèi)存長度等于最長的成員的長度。需要注意的是:聯(lián)合定義之后,即可進行聯(lián)合變量說明,被說明為data類型的變量,可以存放字符型量a或整型量b或存放浮點型量c。要么賦予字符型量,要么賦予整型量,要么賦予浮點型量,不能把3者同時賦予它。

聯(lián)合既可以出現(xiàn)在結(jié)構(gòu)內(nèi),它的成員也可以是結(jié)構(gòu)

例如:Struct{intage;char*addr;union{inti;char*ch;}x;}y[10];若要訪問結(jié)構(gòu)變量y[1]中聯(lián)合x的成員i,可以寫成:y[1].x.i;若要訪問結(jié)構(gòu)變量y[2]中聯(lián)合x的字符串指針ch的第一個字符可寫成:*y[2].x.ch;若寫成"y[2].x.*ch;"是錯誤的。2、聯(lián)合變量的說明

聯(lián)合變量的說明和結(jié)構(gòu)變量的說明方式相同,也有三種形式。即先定義,再說明、定義同時說明和直接說明。以聯(lián)合變量department為例,說明如下:uniondepartment{intgrade;charoffice;};uniondepartmenta,b;/*說明a,b為department類型*/或者:uniondepartment{intgrade;charoffice;}a,b;/*同時說明a,b為department類型*/或者:union{intgrade;charoffice;}a,b/*直接說明a,b為department類型*/

經(jīng)說明后的a,b變量均為department類型。a,b變量的長度應等于department的成員中最長的長度,即等于office數(shù)組的長度,共10個字節(jié)。a,b變量如賦予整型值時,只使用了2個字節(jié),而賦予字符數(shù)組時,可用10個字節(jié)。

3、聯(lián)合變量的賦值和使用

對聯(lián)合變量的賦值、使用都只能是對變量的成員進行。聯(lián)合變量的成員表示為:聯(lián)合變量名.成員名例如,a被說明為department類型的變量之后,可使用

a.grade或a.office。不允許只用聯(lián)合變量名作賦值或其它操作。也不允許對聯(lián)合變量作初始化賦值,賦值只能在程序中進行一個聯(lián)合變量,每次只能賦予一個成員值。一個聯(lián)合變量的值就是聯(lián)合變員的某一個成員值?!纠?1-4】設有一個教師與學生通用的表格,教師數(shù)據(jù)有姓名,年齡,身份,教研室四項。學生有姓名,年齡,身份,班級四項。編程輸入人員數(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");/*提示語*/ gets(body[i].name);/*gets函數(shù)接收帶空格的姓名*/ printf("inputage:\n");scanf("%d",&body[i].age);getchar();/*吸收上一句輸入的回車符*/printf("inputstatus(sort):\n"); body[i].status=getchar();if(body[i].status=='s') {getchar();/*吸收上一句輸入的回車符*/ printf("inputgrade:\n"); scanf("%d",&body[i].depa.grade);getchar();/*吸收上一句輸入的回車符*/ } else {getchar();/*吸收上一句輸入的回車符*/ 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);/*對齊輸出數(shù)據(jù)*/else printf("%15s\t%3d%3c%20s\n",body[i].name,body[i].age,body[i].status,body[i].depa.office);/*對齊輸出數(shù)據(jù)*/

} return0;}說明:在處理結(jié)構(gòu)體問題時經(jīng)常涉及字符或字符串的輸入,這時要注意:①scanf()函數(shù)用%s輸入字符串遇空格即結(jié)束,因此輸入帶空格的字符串可改用gets函數(shù)。②在輸入字符類型數(shù)據(jù)時往往得到的是空白符(空格、回車等),甚至運行終止,因此常作相應處理,即在適當?shù)牡胤皆黾觛etchar();空輸入語句,以消除緩沖區(qū)中的空白符。類型定義符typedefC語言不僅提供了豐富的數(shù)據(jù)類型,而且還允許由用戶自己定義類型說明符,也就是說允許由用戶為數(shù)據(jù)類型取“別名”。類型定義符typedef即可用來完成此功能。typedef定義的一般形式為:typedef原類型名

新類型名

其中原類型名中含有定義部分,新類型名一般用大寫表示,以便于區(qū)別。有時也可用宏定義來代替typedef的功能,但是宏定義是由預處理完成的,而typedef則是在編譯時完成的,后者更為靈活方便。例如,有整型量a,b,其說明如下:inta,b;int的完整寫法為integer,為了增加程序的可讀性,可把整型說明符用typedef定義為:typedefintINTEGER這以后就可用INTEGER來代替int作整型變量的類型說明了。

例如:INTEGERa,b;它等效于:inta,b;用typedef定義數(shù)組、指針、結(jié)構(gòu)等類型將帶來很大的方便,不僅使程序書寫簡單而且使意義更為明確,因而增強了可讀性。

例如:typedefcharNAME[20];表示NAME是字符數(shù)組類型,數(shù)組長度為20。然后可用NAME說明變量,如:NAMEa1,a2,s1,s2;完全等效于:chara1[20],a2[20],s1[20],s2[20]又如:typedefstructstu{charname[20];intage;charsex;}STU;定義STU表示stu的結(jié)構(gòu)類型,然后可用STU來說明結(jié)構(gòu)變量:STUbody1,body2;11.4應用程序舉例【例5】一個公司有10名員工,每個員工的數(shù)據(jù)包括職工號、姓名、生日和工資。請使用結(jié)構(gòu)體表示員工的信息,并用結(jié)構(gòu)體數(shù)組來存所有員工的數(shù)據(jù)。要求輸入10名員工的信息,計算平均工資,并輸出工資最高的員工的數(shù)據(jù)。然后對上述的員工數(shù)據(jù)數(shù)組按工資從大到小排序,并輸出排序后各員工的信息。#include<stdio.h>#defineN3/*員工個數(shù)N在下列各個函數(shù)內(nèi)的數(shù)值都是10,是不變的。*/floatavesalary;structst{ intnum; charname[20]; charbirth[20]; floatsalary;};voidinput(structsta[])/*輸入所有員工信息*/{ inti; for(i=0;i<N;i++){ printf("職工號,姓名,出生日期,工資:\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[])/*按員工工資從高到低進行排序*/{ 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("最高工資的員工信息:職工號%d,姓名%s,生日%s,工資%.2f\n",d[0].num,d[0].name,d[0].birth,d[0].salary);}voidoutputall(structst

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 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

提交評論