簡介:第8章結構體和共用體,前面的章節(jié)中已經(jīng)介紹了各種基本數(shù)據(jù)類型、數(shù)組和指針。但只有這些數(shù)據(jù)類型還難以處理一些比較復雜的數(shù)據(jù)結構。本章將以前面介紹的數(shù)據(jù)類型為基礎,進一步介紹結構體類型、共用體類型和枚舉類型。,,,81結構體82動態(tài)內存分配與鏈表83共用體類型84枚舉類型85用戶自定義類型86程序舉例,第8章結構體和共用體,第8章,81結構體,81結構體,811結構類型定義在實際問題中,一組數(shù)據(jù)往往具有不同的數(shù)據(jù)類型。例如,在學生登記表中,姓名應為字符型;學號可為整型或字符型;年齡應為整型性別應為字符型成績可為整型或實型。但這些顯然不能用一個數(shù)組來存放這一組數(shù)據(jù)。因為數(shù)組中各元素的類型和長度都必須一致,以便于編譯系統(tǒng)處理。為了解決這個問題,C語言中給出了另一種構造數(shù)據(jù)類型“結構體”?!敖Y構體”是一種構造類型,它是由若干“成員”組成的。每一個成員可以是一個基本數(shù)據(jù)類型或者又是一個構造類型。結構體既然是一種“構造”而成的數(shù)據(jù)類型,那么在說明和使用之前必須先定義它,也就是構造它。如同在說明和調用函數(shù)之前要先定義函數(shù)一樣。,81結構體,定義一個結構體類型的一般形式為STRUCT結構體名{結構成員的說明}成員表由若干個成員組成,每個成員都是該結構體的一個組成部分。對每個成員也必須作類型說明,其形式為類型說明符成員名成員名的命名應符合標識符的書寫規(guī)定。例如STRUCTSTU{INTNUMCHARNAME20CHARSEXFLOATSCORE},81結構體,在這個結構體定義中,結構體名為STU,該結構體由4個成員組成。第一個成員為NUM,整型變量;第二個成員為NAME,字符數(shù)組變量;第三個成員為SEX,字符變量;第四個成員為SCORE,實型變量。應注意在括號“}”后的分號是不可少的。結構體定義之后,即可進行變量說明。凡說明為結構體STU的變量都由上述4個成員組成。由此可見,結構是一種復雜的數(shù)據(jù)類型,是數(shù)目固定,類型不同的若干有序變量的集合。,81結構體,812結構體類型變量的說明說明結構體變量有以下三種方法。以上面定義的STU為例來加以說明。(1)先定義結構體類型,再說明結構體變量例如STRUCTSTU{INTNUMCHARNAME20CHARSEXFLOATSCORE}STRUCTSTUBOY1,BOY2說明了兩個變量BOY1和BOY2為STU結構類型。也可以用宏定義使用一個符號常量來表示一個結構類型,例如DEFINESTUSTRUCTSTUSTU{INTNUMCHARNAME20CHARSEXFLOATSCORE}STUBOY1,BOY2,81結構體,(2)在定義結構體類型的同時說明結構體變量例如STRUCTSTU{INTNUMCHARNAME20CHARSEXFLOATSCORE}BOY1,BOY2(3)直接說明結構體變量例如STRUCT{INTNUMCHARNAME20CHARSEXFLOATSCORE}BOY1,BOY2,81結構體,第三種方法與第二種方法的區(qū)別在于第三種方法中省去了結構體名,而直接給出結構體變量。三種方法中說明的BOY1,BOY2變量都具有相同的結構。說明了BOY1,BOY2變量為STU類型后,即可向這兩個變量中的各個成員賦值。在上述STU結構體定義中,所有的成員都是基本數(shù)據(jù)類型或數(shù)組類型。成員也可以又是一個結構體類型,即構成了嵌套的結構體。,81結構體,例如STRUCTDATE{INTMONTHINTDAYINTYEAR}STRUCT{INTNUMCHARNAME20CHARSEXSTRUCTDATEBIRTHDAYFLOATSCORE}BOY1,BOY2,首先定義一個結構體DATE,由MONTH月、DAY日、YEAR年三個成員組成。在定義并說明變量BOY1和BOY2時,其中的成員BIRTHDAY被說明為DATA結構體類型。成員名可與程序中其它變量同名,互不干擾。結構體變量成員的表示方法,在程序中使用結構體變量時,往往不把它作為一個整體來使用。,說明結構體在內存中存儲容量是各成員容量之和,這是與后面聯(lián)合體的重要區(qū)別。,81結構體,813結構體變量的引用一般情況下,不能對一個結構體變量作為整體引用,只能引用其中的成員。結構體變量中成員引用的一般形式為結構體變量名成員名其中,“”是域成員運算符,是C語言中優(yōu)先級最高的運算符之一。例如BOY1NUM即第一個人的學號,BOY2SEX即第二個人的性別。如果成員本身又是一個結構體,則必須逐級找到最低級的成員才能使用。例如BOY1BIRTHDAYMONTH即第一個人出生的月份。成員可以在程序中單獨使用,與普通變量完全相同。,81結構體,814結構體變量的賦值對于結構體變量,只有以下兩種情況可以對結構體變量賦值。(1)結構體變量整體賦值例如BOY2BOY1(2)取結構體變量地址例如注意結構體變量名是地址常量,含義與數(shù)組名和函數(shù)名相同,不能對結構體變量做整體輸入/輸出。例如SCANF“D,S,C,F“,PRINTF“D,S,C,F“,BOY1這些語句都是不允許的,只能對結構體成員進行輸入/輸出。,81結構體,例81給結構體變量賦值并輸出其值。INCLUDEVOIDMAIN{STRUCTSTU/定義結構體STU/{INTNUMCHARNAMECHARSEXFLOATSCORE}BOY1,BOY2/定義STU類型的變量BOY1、BOY2/BOY1NUM102BOY1NAME“ZHANGPING“PRINTF“INPUTSEXANDSCORE\N“SCANF“CF“,/給BOY1的成員SEX和SCORE賦值/BOY2BOY1/把BOY1整體賦給BOY2/PRINTF“NUMBERD\NNAMES\N“,BOY2NUM,BOY2NAMEPRINTF“SEXC\NSCORE62F\N“,BOY2SEX,BOY2SCORE},81結構體,程序運行結果INPUTSEXANDSCOREM96↙NUMBER102NAMEZHANGPINGSEXMSCORE︼9600,本程序中用賦值語句給NUM和NAME兩個成員賦值,NAME是一個字符串指針變量。用SCANF函數(shù)動態(tài)地輸入SEX和SCORE成員值,然后把BOY1的所有成員的值整體賦予BOY2。最后分別輸出BOY2的各個成員值。,81結構體,815結構體變量的初始化如果結構體變量為全局變量或者靜態(tài)變量,則可以對它做初始化賦值。對局部或自動結構體變量不能做初始化賦值。,81結構體,例82外部結構體變量初始化。INCLUDESTRUCTSTU/定義結構體/{INTNUMCHARNAMECHARSEXFLOATSCORE}BOY2,BOY1{102,“ZHANGPING“,M,785}/對變量BOY1的成員初始化/VOIDMAIN{BOY2BOY1/把BOY1整體賦給BOY2/PRINTF“NUMBERD\NNAMES\N“,BOY2NUM,BOY2NAMEPRINTF“SEXC\NSCORE62F\N“,BOY2SEX,BOY2SCORE},81結構體,程序運行結果NUMBER102NAMEZHANGPINGSEXMSCORE︼7850,本程序中,BOY2,BOY1均被定義為外部結構體變量,并對BOY1作了初始化賦值。在MAIN函數(shù)中,把BOY1的值整體賦予BOY2,然后用兩個PRINTF語句輸出BOY2各成員的值。,81結構體,例83靜態(tài)結構體變量初始化。INCLUDEVOIDMAIN{STATICSTRUCTSTU/定義靜態(tài)結構體/{INTNUMCHARNAMECHARSEXFLOATSCORE}BOY2,BOY1{102,“ZHANGPING“,M,785}/對變量BOY1的成員初始化/BOY2BOY1PRINTF“NUMBERD\NNAMES\N“,BOY2NUM,BOY2NAMEPRINTF“SEXC\NSCORE62F\N“,BOY2SEX,BOY2SCORE}本程序是把BOY1,BOY2都定義為靜態(tài)局部的結構體變量,同樣可以做初始化賦值。,81結構體,816結構體數(shù)組一個結構體變量可以處理一個對象,如果有多個對象,則需要多個結構體變量,數(shù)組的元素也可以是結構體類型的,因此可以構成結構體數(shù)組。結構體數(shù)組的每一個元素都是具有相同結構體類型的下標結構體變量。在實際應用中,經(jīng)常用結構體數(shù)組來表示具有相同數(shù)據(jù)結構的一個群體。如一個班的學生檔案,一個車間職工的工資表等。結構體數(shù)組的定義方法和結構體變量相似,也有三種方式(1)先定義結構體類型,再定義結構體數(shù)組。例如STRUCTSTU{INTNUMCHARNAMECHARSEXFLOATSCORE};STRUCTSTUBOY5定義了一個結構體數(shù)組BOY,共有5個元素,BOY0~BOY4。每個數(shù)組元素都具有STRUCTSTU的結構體形式。,81結構體,(2)在定義結構體類型的同時定義結構體數(shù)組。例如STRUCTSTU{INTNUMCHARNAMECHARSEXFLOATSCORE}BOY5(3)直接定義結構體數(shù)組。例如STRUCT{INTNUMCHARNAMECHARSEXFLOATSCORE}BOY5,81結構體,對外部結構體數(shù)組或靜態(tài)結構體數(shù)組可以做初始化賦值。例如STRUCTSTU{INTNUMCHARNAMECHARSEXFLOATSCORE}BOY5{{101,“LIPING“,M,45},{102,“ZHANGPING“,M,625},{103,“HEFANG“,F,925},{104,“CHENGLING“,F,87},{105,“WANGMING“,M,58}}當對全部元素做初始化賦值時,也可不給出數(shù)組長度。,81結構體,例84計算學生的平均成績和不及格的人數(shù)。INCLUDESTRUCTSTU/定義結構體/{INTNUMCHARNAMECHARSEXFLOATSCORE}BOY5{{101,“LIPING“,M,45},{102,“ZHANGPING“,M,625},{103,“HEFANG“,F,925},{104,“CHENGLING“,F,87},{105,“WANGMING“,M,58}}/對結構體數(shù)組元素初始化/VOIDMAIN{INTI,C0FLOATAVE,S0FORI0I成員名例如PSTUNUM或PSTUNUM應該注意PSTU兩側的括號不可少,因為成員符“”的優(yōu)先級高于“”。如去掉括號寫作PSTUNUM,則等效于PSTUNUM,這樣,意義就完全不對了。,81結構體,例86分析下面程序的運行結果。INCLUDESTRUCTSTU/定義結構體/{INTNUMCHARNAMECHARSEXFLOATSCORE}BOY1{102,“ZHANGPING“,M,785},PSTUVOIDMAIN{PSTUPRINTF“NUMBERD\NNAMES\N“,BOY1NUM,BOY1NAMEPRINTF“SEXC\NSCORE62F\N\N“,BOY1SEX,BOY1SCOREPRINTF“NUMBERD\NNAMES\N“,PSTUNUM,PSTUNAMEPRINTF“SEXC\NSCORE62F\N\N“,PSTUSEX,PSTUSCOREPRINTF“NUMBERD\NNAMES\N“,PSTUNUM,PSTUNAMEPRINTF“SEXC\NSCORE62F\N\N“,PSTUSEX,PSTUSCORE},81結構體,本程序序定義了一個結構體類型STU,定義了STU類型結構變量BOY1并作了初始化賦值,還定義了一個指向STU類型結構體的指針變量PSTU。在MAIN函數(shù)中,PSTU被賦予BOY1的地址,因此PSTU指向BOY1。然后在PRINTF語句內用三種形式輸出BOY1的各個成員值。,程序運行結果NUMBER102NAMEZHANGPINGSEXMSCORE︼7850,82動態(tài)內存分配與鏈表,我們存儲數(shù)量比較多的同類型或同結構的數(shù)據(jù)時,一般首先考慮數(shù)組。然而在實際應用中,當處理一些難以確定其數(shù)量的數(shù)據(jù)時,如果用數(shù)組來處理,必須事先分配一個足夠大的連續(xù)空間,以保證數(shù)組元素數(shù)量充分夠用,但這樣處理時對存儲空間的一種浪費。C語言使用動態(tài)內存分配來解決這樣的問題,其中常用的就是鏈表。鏈表是一種常見的數(shù)據(jù)結構,它動態(tài)地進行存儲分配,并且可以方便而又簡單地進行數(shù)據(jù)插入,刪除等操作。,82動態(tài)內存分配與鏈表,821鏈表的概念鏈表是指若干個數(shù)據(jù)按一定的原則連接起來。這個原則為前一個數(shù)據(jù)指向下一個數(shù)據(jù),只有通過前一個數(shù)據(jù)項才能找到下一個數(shù)據(jù)項。鏈表有一個“頭指針”HEAD,它指向鏈表的第一個元素(數(shù)據(jù)項)。鏈表的一個元素稱為一個“結點”NODE。結點中包含兩部分內容,第一部分是結點數(shù)據(jù)本身,如圖81中的A、B、C、D所示。結點的第二部分是一個指針,它指向下一個結點。最后一個結點稱為“表尾”,表尾結點的指針不指向任何地址,因此為空(NULL)。,圖81鏈表結構圖,82動態(tài)內存分配與鏈表,如果每個結點采用一個指針,將前一個結點的指針指向下一個結點,這稱為單鏈表。如果每個結點有兩個指向其他結點的指針,則稱為雙鏈表。本節(jié)主要討論單鏈表的運算。由以上簡單鏈表可以看到,鏈表中的每個結點至少包含兩個域,一個域用來存放數(shù)據(jù),其類型根據(jù)需存放的數(shù)據(jù)類型定義。另一個域用來存放下一個結點的地址,因此必然是一個指針類型,此指針的類型應該是所指向的表結點的結構體類型。在C語言中,可以用結構體類型來實現(xiàn)鏈表,例如STRUCTSTUDENT{INTLONGFLOATSCORESTRUCTSTUDENTNEXT/指向下一結點/}其中NEXT是結構體指針變量,用來存放下一個結點的地址,即NEXT是指向下一個結點。,82動態(tài)內存分配與鏈表,822動態(tài)存儲分配C語言允許在函數(shù)執(zhí)行部分的任何地方使用動態(tài)存儲分配函數(shù)開辟或收回存儲單元,這樣的存儲分配叫動態(tài)存儲分配。動態(tài)分配使用自由、節(jié)約內存。鏈表是動態(tài)分配存儲空間的,也就是說在需要的時候才開辟一個結點的存儲空間。在C語言中提供了以下有關的函數(shù)來實現(xiàn)動態(tài)存儲分配和釋放,這些函數(shù)包含在“STDIOH”或“MALLOCH”中。,82動態(tài)內存分配與鏈表,1MALLOC函數(shù)(分配內存空間函數(shù))調用形式為VOIDMALLOCSIZE其作用是在內存中動態(tài)獲取一個大小為SIZE個字節(jié)的連續(xù)存儲空間。該函數(shù)將返回一個VOID類型的指針,若分配成功,就返回所分配的空間的起始地址,否則,就返回空指針(NULL)。2.CALLOC函數(shù)(分配內存空間函數(shù))調用形式為VOIDCALLOCUNSIGNEDN,UNSIGNEDSIZE其作用是在內存中動態(tài)獲取N個大小為SIZE個字節(jié)的存儲空間。該函數(shù)將返回一個VOID類型的指針,若分配成功,就返回內存單元的起始地址,否則,返回空指針(NULL)。用該函數(shù)可以動態(tài)地獲取一個一維數(shù)組空間,其中N為數(shù)組元素個數(shù),每個數(shù)組元素的大小為SIZE個字節(jié)。,82動態(tài)內存分配與鏈表,3.FREE函數(shù)(釋放內存空間函數(shù))調用形式為VOIDFREEVOIDP其作用是釋放由P指針所指向的內存空間。即系統(tǒng)回收,使這段空間又可以被其他變量所用。指針變量P是最近一次調用MALLOC或CALLOC函數(shù)時返回的值,不能是任意的地址。4REALLOC函數(shù)調用形式為VOIDRECALLOCVOIDP,UNSIGNEDSIZE其作用是將P所指的已分配的內存空間重新分配成大小為SIZE個字節(jié)的空間。它用于改變已分配的空間的大小,可以增減單元數(shù)。函數(shù)返回新內存的首地址,如果內存不夠,則返回空指針(NULL)。,82動態(tài)內存分配與鏈表,例87分配一塊區(qū)域,輸入一個學生數(shù)據(jù)。INCLUDEINCLUDEVOIDMAIN{STRUCTSTU/定義結構體/{INTNUMCHARNAMECHARSEXFLOATSCORE}PS/定義一個結構體指針變量PS/PSSTRUCTSTUMALLOCSIZEOFSTRUCTSTUPSNUM102/輸入學生數(shù)據(jù)/PSNAME“ZHANGPING“PSSEXMPSSCORE625PRINTF“NUMBERD\NNAMES\N“,PSNUM,PSNAMEPRINTF“SEXC\NSCORE62F\N“,PSSEX,PSSCOREFREEPS},82動態(tài)內存分配與鏈表,程序運行結果NUMBER102NAMEZHANGPINGSEXMSCORE︼6250,本程序中,定義了結構體類型STU,定義了STU類型指針變量PS。然后分配一塊STU大內存區(qū),并把首地址賦予PS,使PS指向該區(qū)域。再以PS為指向結構體的指針變量對各成員賦值,并用PRINTF輸出各成員值。最后用FREE函數(shù)釋放PS指向的內存空間。整個程序包含了申請內存空間、使用內存空間、釋放內存空間三個步驟,實現(xiàn)存儲空間的動態(tài)分配。,82動態(tài)內存分配與鏈表,823建立和輸出鏈表所謂動態(tài)建立鏈表是指在程序執(zhí)行過程中從無到有地建立鏈表,將一個個新生成的結點順次鏈接入已建立的鏈表上,上一個結點的指針域存放下一個結點的起始地址,并給各結點數(shù)據(jù)域賦值。所謂輸出鏈表是將鏈表上各個結點的數(shù)據(jù)域中的值依次輸出,直到鏈表結尾。,82動態(tài)內存分配與鏈表,例88以三個結構體變量為結點建立一個簡單的鏈表并輸出。INCLUDESTRUCTNODE{INTDATASTRUCTNODENEXT}VOIDMAIN{STRUCTNODEA,B,C,HEAD,PHEAD/頭結點指向A結點/ADATA5ANEXT/A結點指向B結點/BDATA10BNEXT/B結點指向C結點/CDATA15CNEXTNULL/C結點是尾結點/PHEAD/使P指向A結點/WHILEPNULL{PRINTF“D“,PDATA/輸出指針P所指向結點的數(shù)據(jù)/PPNEXT/使P指向下一個結點/}PRINTF“NULL\N“},程序運行結果51015NULL,82動態(tài)內存分配與鏈表,824鏈表的基本操作鏈表的基本操作包括,建立并初始化鏈表,遍歷訪問鏈表(包括查找結點、輸出結點等),刪除鏈表中的結點,在鏈表中插入結點。鏈表的各種基本操作的步驟如下。1建立鏈表①建立頭結點(或定義頭指針變量)。②讀取數(shù)據(jù)。③生成新結點。④將數(shù)據(jù)存入結點的數(shù)據(jù)域中。⑤將新結點連接到鏈表中(將新結點地址賦給上一個結點的指針域連接到鏈表)。⑥重復步驟②~⑤,直到尾結點為止。,82動態(tài)內存分配與鏈表,2.遍歷訪問鏈表輸出鏈表即順序訪問鏈表中各結點的數(shù)據(jù)域,方法是從頭結點開始,不斷地讀取數(shù)據(jù)和下移指針變量,直到尾結點為止。3.刪除鏈表中的一個結點①找到要刪除結點的前驅結點。②將要刪除結點的后驅結點的地址賦給要刪除結點的前驅結點的指針域。③將要刪除結點的存儲空間釋放。4.在鏈表的某結點前插入一個結點①開辟一個新結點并將數(shù)據(jù)存入該結點的數(shù)據(jù)域。②找到插入點結點。③將新結點插入到鏈表中,將新結點的地址賦給插入點上一個結點的指針域,并將插入點的地址存入新結點的指針域。,
下載積分: 4 賞幣
上傳時間:2024-01-06
頁數(shù): 93
大小: 0.54(MB)
子文件數(shù):
簡介:相同音素,LOOKATTHEPICTURETHENFINISH2D,A,H,J,K,,/EI/,幸福四口之家,E,B,D,C,G,P,T,V,八口大家庭,,/I/,I,Y,雙胞胎之家,,/AI/,U,Q,W,幸福三口之家,,/JU/,F,L,M,N,S,X,Z,七口大家庭,,/E/,O,孤寡老人,,/?U/,R,孤寡老人,,/?/,四九三十六,I(愛)Y(玩)的O、R在后頭。即含元音音素EI的有4個,含元音音素I的有9個,含元音音素JU的有3個,含元音音素E的有6個。,元音素分類記憶口決,1含元音音素EI4個字母AAEIHHEIT∫JJD3EIKKKEI記憶口決4A景點HAI(害)JAKE(杰克)2含元音音素I9個字母BBBICCSIDDDIEEIGGD3IPPPITTTIVVVIZZZI記憶口決9E(億)P(警察)拿CDBEG(祈求)TV(電視)捉ZP,3含元音音素JU3個字母UUJUQQKJUWWD∧BLJU記憶口決3克U(油)考驗W(我)的IQ4含元音音素E6個字母FFEFLLELMMEMNNENSSESXXEKSZZZI記憶口決6個掃地FLOOR的男人MAN聽后Z真S傷X心5含元音音素AI字母IIAIYYWAI,5含元音音素AI字母IIAIYYWAI6)單獨發(fā)音2個字母OO?URR?,SUMMARY,
下載積分: 4 賞幣
上傳時間:2024-01-06
頁數(shù): 15
大?。?2.42(MB)
子文件數(shù):