版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第7章復(fù)合的數(shù)據(jù)類型7.3結(jié)構(gòu)體數(shù)組和結(jié)構(gòu)體指針的使用7.4結(jié)構(gòu)體與函數(shù)的關(guān)系7.6共用體、枚舉和typedef類型定義*7.5鏈表7.7程序案例目錄7.1結(jié)構(gòu)概念的引入7.2結(jié)構(gòu)體的描述與存儲7.1結(jié)構(gòu)概念的引入如何表示如圖7-1所示一個學(xué)生的相關(guān)信息呢?圖7-1一個學(xué)生的數(shù)據(jù)信息7.1結(jié)構(gòu)概念的引入前面學(xué)習(xí)的數(shù)據(jù)類型都是單一數(shù)據(jù)類型,如整型、浮點型、字符型等,而數(shù)組中的每個元素也必須是一種數(shù)據(jù)類型。而這里學(xué)生的“學(xué)號”、“姓名”、“性別”、“民族”、“手機(jī)”、“通訊地址”等信息可以用多個字符型數(shù)組存儲,“年齡”可以用一個整型變量存儲。
相關(guān)存儲變量定義如下:charnumber[14 /*學(xué)號:2013011020001*/charname[10]; /*姓名:宋曉倩*/intage /*年齡:18*/charsex[3]; /*性別:女*/charnation[20]; /*民族:漢族*/charmobile[20]; /*手機(jī)/charaddress[40]; /*通訊地址:沈陽市大東區(qū)勞動路32號*/7.1結(jié)構(gòu)概念的引入但這只是一個學(xué)生的信息,如果想存儲多個學(xué)生的信息呢?例如:2013011020002、趙子強(qiáng)、19、男、漢族沈陽市沈河區(qū)惠工街28號2013011020003、王
芳、18、女、漢族沈陽市鐵西區(qū)北二路17號
……上面這些數(shù)據(jù)就不能直接用簡單類型來定義各個變量了。C語言為用戶提供了一種新的數(shù)據(jù)類型——結(jié)構(gòu)體(struct),可以將這些簡單數(shù)據(jù)“封裝”在一起,構(gòu)成一個復(fù)合的數(shù)據(jù)類型,就可以表示上面學(xué)生的相關(guān)信息。7.2結(jié)構(gòu)體的描述與存儲結(jié)構(gòu)體的類型定義如下:其中struct是結(jié)構(gòu)體類型的關(guān)鍵字,不能省略,表示后面定義的類型是一個結(jié)構(gòu)體類型,結(jié)構(gòu)體類型名為合法的標(biāo)識符,即用戶可以定義一個新的結(jié)構(gòu)體類型(注意是類型而不是變量)。注意右花括號后面有一個分號“;”作為結(jié)構(gòu)體類型定義的結(jié)束標(biāo)志,不能省略?;ɡㄌ杻?nèi)的成員列表用來定義組成該結(jié)構(gòu)體類型的各個成員,對每個成員應(yīng)進(jìn)行類型說明,方法與定義其他簡單類型變量一致。7.2.1結(jié)構(gòu)體的類型定義struct
結(jié)構(gòu)體類型名{
成員說明表列};7.2結(jié)構(gòu)體的描述與存儲例如前面講的學(xué)生數(shù)據(jù)可以表示如下:structstudent{charnumber[14]; /*學(xué)號*/charname[10]; /*姓名*/intage; /*年齡*/charsex[3]; /*性別*/charnation[20]; /*民族*/charmobile[20]; /*手機(jī)*/ charaddress[40]; /*通訊地址*/};注意,該定義只是定義了一個結(jié)構(gòu)體類型,即student就像前面的簡單類型int、float一樣,是一個類型名。而要使用該類型存儲數(shù)據(jù),還必須用結(jié)構(gòu)體類型定義對應(yīng)的結(jié)構(gòu)體變量或結(jié)構(gòu)體數(shù)組,才能為其賦值并使用。結(jié)構(gòu)體類型的定義一般都放在主函數(shù)的前面,而不是放在主函數(shù)內(nèi)部進(jìn)行定義。7.2.1結(jié)構(gòu)體的類型定義7.2結(jié)構(gòu)體的描述與存儲結(jié)構(gòu)體類型的變量定義可以有以下三種方式。
1.先聲明結(jié)構(gòu)體類型再定義結(jié)構(gòu)體變量例如:structstudent{charnumber[14]; /*學(xué)號*/charname[10];
/*姓名*/intage;
/*年齡*/charsex[3];
/*性別*/charnation[20]; /*民族*/charmobile[20]; /*手機(jī)*/ charaddress[40]; /*通訊地址*/};structstudents1,s2; /*定義s1、s2為student結(jié)構(gòu)體類型變量*/7.2.2結(jié)構(gòu)體變量定義及初始化struct
結(jié)構(gòu)體類型名{
成員說明表列};struct結(jié)構(gòu)體類型名
變量名表;7.2結(jié)構(gòu)體的描述與存儲2.在定義結(jié)構(gòu)體類型的同時定義結(jié)構(gòu)體變量這種方法是在定義出結(jié)構(gòu)體類型的同時直接定義所需變量,好處是可以簡化語句。例如:structstudent{charnumber[14]; /*學(xué)號*/charname[10]; /*姓名*/intage;
/*年齡*/charsex[3]; /*性別*/charnation[20]; /*民族*/charmobile[20]; /*手機(jī)*/ charaddress[40]; /*通訊地址*/}s1,s2; /*在定義結(jié)構(gòu)體類型student時直接定義出變量s1、s2*/7.2.2結(jié)構(gòu)體變量定義及初始化7.2結(jié)構(gòu)體的描述與存儲3.省略結(jié)構(gòu)體名直接定義結(jié)構(gòu)體變量可以省略結(jié)構(gòu)體類型名來定義一個結(jié)構(gòu)體類型。例如:struct /*此處省略了結(jié)構(gòu)體類型名*/{charnumber[14]; *學(xué)號*/charname[10]; /*姓名*/intage;
/*年齡*/charsex[3]; /*性別*/charnation[20]; /*民族*/charmobile[20]; /*手機(jī)*/ charaddress[40]; /*通訊地址*/}s1,s2; /*直接定義出變量s1、s2,該類型不能在其他地方再定義變量*/這種方法可以不指明結(jié)構(gòu)體類型名而直接定義出各個變量,但有一個缺點,就是這種定義方法只能在定義類型的同時直接定義出變量,在以后程序其他位置因為沒有定義結(jié)構(gòu)體類型名而無法再定義其他該類型變量。7.2.2結(jié)構(gòu)體變量定義及初始化7.2結(jié)構(gòu)體的描述與存儲結(jié)構(gòu)體變量的初始化的一般格式如下:其中,初值表為各成員的初值表達(dá)式。注意:初值表達(dá)式的類型應(yīng)與對應(yīng)成員的類型相同,否則會出錯。各初值表達(dá)式之間用逗號分隔。例如:structstudent{charnumber[14]; /*學(xué)號*/charname[10]; /*姓名*/intage; /*年齡*/charsex[3]; /*性別*/charnation[20]; /*民族*/charmobile[20]; /*手機(jī)*/ charaddress[40]; /*通訊地址*/};structstudents1={"2013011020001","宋曉倩",18,"女","漢族",,"沈陽市大東區(qū)勞動路32號"};/*定義s1為student結(jié)構(gòu)體類型變量并為其各成員賦初值*/7.2.3結(jié)構(gòu)體變量的初始化struct
結(jié)構(gòu)體類型名變量名={初值表};7.2結(jié)構(gòu)體的描述與存儲1.結(jié)構(gòu)體成員的引用方法直接引用結(jié)構(gòu)體變量成員的一般格式如下:例如,前面定義的student結(jié)構(gòu)體類型的變量s1,其成員age的表示方法為s1.age,而不能直接寫成age。7.2.4結(jié)構(gòu)體變量和成員的引用及賦值結(jié)構(gòu)體變量名.成員名7.2結(jié)構(gòu)體的描述與存儲2.結(jié)構(gòu)體成員的賦值結(jié)構(gòu)體變量是一個復(fù)合構(gòu)造類型的變量,在賦值的時候只能對該結(jié)構(gòu)體變量的每個最底層成員進(jìn)行賦值,而不能直接對結(jié)構(gòu)體變量本身賦值。例如:s1.age=18;/*將s1的成員age的值賦為18*/strcpy(,"宋曉倩"); /*將s1的成員name的值賦為宋曉倩,字符串不允許直接賦值*/7.2.4結(jié)構(gòu)體變量和成員的引用及賦值7.2結(jié)構(gòu)體的描述與存儲3.結(jié)構(gòu)體變量的整體賦值結(jié)構(gòu)體類型變量可以整體引用來賦值。假設(shè)變量s1中各成員已賦有初值,可以有如下整體賦值語句:s2=s1; /*將結(jié)構(gòu)體變量s1的成員各值全部賦給結(jié)構(gòu)體變量s2*/即將變量s1的所有成員的值一一賦給變量s2的各成員。結(jié)構(gòu)體型變量只能對逐個成員進(jìn)行輸入或輸出,不可進(jìn)行整體的輸入或輸出。例如,下面語句為結(jié)構(gòu)體變量s2的每個成員從鍵盤賦初值:scanf("%s%s%d%s%s%s%s",s2.number,,&s2.age,s2.sex,s2.nation,s2.mobile,s2.address);7.2.4結(jié)構(gòu)體變量和成員的引用及賦值7.2結(jié)構(gòu)體的描述與存儲結(jié)構(gòu)體類型變量占內(nèi)存大小是它里面各成員所占內(nèi)存大小之和。結(jié)構(gòu)體變量在定義后,系統(tǒng)就為該變量分配了一段連續(xù)的存儲單元。例如:structdata{inta;floatb;charc;}d1;上述變量d1的內(nèi)存分配如圖7-2所示??梢杂胹izeof運(yùn)算符測出一個結(jié)構(gòu)類型或結(jié)構(gòu)變量的字節(jié)數(shù)。在TC中,結(jié)構(gòu)體變量d1共占有7個連續(xù)內(nèi)存單元,a、b、c三個成員所占的字節(jié)數(shù)分別是2、4、1。7.2.5結(jié)構(gòu)變量的空間分配及查看方法圖7-2結(jié)構(gòu)體變量data17.2結(jié)構(gòu)體的描述與存儲計算結(jié)構(gòu)體類型所占內(nèi)存大小的語句格式為:例如,表達(dá)式sizeof(data)或sizeof(d1)都可以計算該類型所占內(nèi)存大小。7.2.5結(jié)構(gòu)變量的空間分配及查看方法sizeof(結(jié)構(gòu)體類型名)或sizeof(結(jié)構(gòu)體變量名)7.2結(jié)構(gòu)體的描述與存儲結(jié)構(gòu)體類型的定義可以進(jìn)行嵌套,即一個結(jié)構(gòu)體類型里的某一成員本身又是一個結(jié)構(gòu)體類型。這時可以將里面的結(jié)構(gòu)體先定義,外層的結(jié)構(gòu)體類型后定義。如一個學(xué)生信息里要是想加上出生日期時,出生日期應(yīng)該包括年、月、日三個值就需要先定義一個結(jié)構(gòu)體類型“出生日期”,然后再定義結(jié)構(gòu)體類型“學(xué)生”。定義語句如下:structbirthday /*定義結(jié)構(gòu)體類型birthday*/{intyear; /*出生年份*/intmonth; /*出生月份*/intday; /*出生日期*/};structstudent /*該結(jié)構(gòu)體類型定義為學(xué)生信息*/{charnumber[14];charname[10];intage;charsex[3];charnation[20];structbirthdaydate; /*定義出生日期的成員*/charmobile[20];charaddress[40];};structstudents1,s2;7.2.6結(jié)構(gòu)體類型的嵌套定義7.2結(jié)構(gòu)體的描述與存儲這時如果想表示變量s1的成員date中的成員year,就可以用兩級直接引用符號來表示,如s1.date.year,語句s1.date.year=1996;即給成員s1.date.year賦初值為1996。若對嵌套結(jié)構(gòu)體變量賦初值,也按嵌套的結(jié)構(gòu)體各成員順序進(jìn)行賦初值。例如:structstudents1={"2013011020001","宋曉倩",18,"女","漢族",1996,04,17,,"沈陽市大東區(qū)勞動路32號"};/*定義s1為student結(jié)構(gòu)體類型變量并為其各成員賦初值*/7.2.6結(jié)構(gòu)體類型的嵌套定義7.2結(jié)構(gòu)體的描述與存儲【案例7-1】定義一個結(jié)構(gòu)體類型student,定義兩個學(xué)生變量,為一個學(xué)生變量在定義時賦初值,在運(yùn)行時輸入另一個學(xué)生的學(xué)號、姓名、年齡、性別、民族、通訊地址、手機(jī)等信息,將兩個學(xué)生的信息顯示在屏幕上。打開源程序調(diào)試運(yùn)行程序當(dāng)為第二個學(xué)生輸入相關(guān)信息:2013011020002趙子強(qiáng)19男
漢陽市沈河區(qū)惠工街28號程序運(yùn)行結(jié)果7.3結(jié)構(gòu)體數(shù)組和結(jié)構(gòu)體指針的使用1.結(jié)構(gòu)體數(shù)組的定義結(jié)構(gòu)體型數(shù)組的定義方式如下:7.3.1結(jié)構(gòu)體數(shù)組struct結(jié)構(gòu)體類型名{
成員說明表列};struct結(jié)構(gòu)體類型名
數(shù)組名[數(shù)組元素個數(shù)];7.3結(jié)構(gòu)體數(shù)組和結(jié)構(gòu)體指針的使用例如,若想存儲一個班的30名所有學(xué)生信息,可定義一個結(jié)構(gòu)體類型的數(shù)組:structstudent /*學(xué)生結(jié)構(gòu)體類型定義*/{charnumber[14]; /*學(xué)號*/charname[10]; /*姓名*/intage; /*年齡*/charsex[3]; /*性別*/charnation[20]; /*民族*/charmobile[12]; /*手機(jī)*/charaddress[40]; /*通訊地址*/ };structstudentstu[30]; /*定義一個學(xué)生類型的結(jié)構(gòu)體數(shù)組stu,可以存儲30個學(xué)生信息*/7.3.1結(jié)構(gòu)體數(shù)組7.3結(jié)構(gòu)體數(shù)組和結(jié)構(gòu)體指針的使用2.結(jié)構(gòu)體數(shù)組的初始化結(jié)構(gòu)體數(shù)組也可以像普通數(shù)組一樣進(jìn)行初始化,這時可以用兩層花括號把初始值括起來,例如下面語句定義了一個具有2個元素的結(jié)構(gòu)體數(shù)組stu,并為這兩個元素初始化:structstudentstu[2]={{"2013011020001","宋曉倩",18,"女","漢族",,"沈陽市大東區(qū)勞動路32號"},{"2013011020002","趙子強(qiáng)",19,"男","漢族",,"沈陽市沈河區(qū)惠工街28號"}};7.3.1結(jié)構(gòu)體數(shù)組提示:當(dāng)結(jié)構(gòu)體數(shù)組初始化時在初始化的時候?qū)?yīng)位置的成員賦值與其類型要一致,否則會出錯。7.3結(jié)構(gòu)體數(shù)組和結(jié)構(gòu)體指針的使用3.結(jié)構(gòu)體數(shù)組各元素中成員的引用結(jié)構(gòu)體數(shù)組各元素中成員的引用方法如下:在引用結(jié)構(gòu)體類型數(shù)組中各元素時,變量名是“數(shù)組名[數(shù)組下標(biāo)值]”,然后用直接運(yùn)算符“.”連接結(jié)構(gòu)體的“成員名”即可。例如:stu[0].age=18;/*為結(jié)構(gòu)體數(shù)組第一個元素的成員age賦初值為18*/7.3.1結(jié)構(gòu)體數(shù)組數(shù)組名[數(shù)組下標(biāo)值].成員名7.3結(jié)構(gòu)體數(shù)組和結(jié)構(gòu)體指針的使用1.指向結(jié)構(gòu)體變量的指針可以定義一個結(jié)構(gòu)體類型的指針來指向結(jié)構(gòu)體變量,定義格式為:若有一個結(jié)構(gòu)體型指針指向一個結(jié)構(gòu)體變量,則使用該指針表示結(jié)構(gòu)體變量中的各成員可以表示為:這里“(*指針名)”等價于“結(jié)構(gòu)體變量名”。但因為“.”的運(yùn)算優(yōu)先級別高于“*”,所以必須將“*指針名”用圓括號括起來才行。例如:structstudents1,*p=&s1;/*定義student類型的變量s1和指針p,并將指針p指向變量s1*/(*p).age=18;/*使用指針p為變量s1的成員age賦初值為18*/7.3.2結(jié)構(gòu)體指針struct
結(jié)構(gòu)體類型名*指針名=&結(jié)構(gòu)體變量名;(*指針名).成員名7.3結(jié)構(gòu)體數(shù)組和結(jié)構(gòu)體指針的使用如果在程序中大量使用指針來表示結(jié)構(gòu)體變量中的各成員,書寫很麻煩。這時就引入了另一個運(yùn)算符——間接成員運(yùn)算符(->)。間接成員運(yùn)算符“->”的左邊是一個結(jié)構(gòu)體指針變量,右邊是所指結(jié)構(gòu)體的一個成員名。間接引用結(jié)構(gòu)體變量成員的一般格式如下:例如上面語句可改寫為:p->age=18;/*與語句(*p).age=18;等價*/一般地說,如果指針變量已指向結(jié)構(gòu)體變量,則可以用以下三種形式訪問結(jié)構(gòu)體變量的成員:(1)結(jié)構(gòu)體變量.成員
(2)指針變量->成員
(3)(*指針變量).成員7.3.2結(jié)構(gòu)體指針
指針名->成員名7.3結(jié)構(gòu)體數(shù)組和結(jié)構(gòu)體指針的使用2.指向結(jié)構(gòu)體數(shù)組的指針指向結(jié)構(gòu)體類型數(shù)組的指針也可以像普通指針一樣進(jìn)行各種運(yùn)算,指針前后移動等,定義指向結(jié)構(gòu)體數(shù)組的指針格式如下:例如,下面程序段實現(xiàn)了使用指針對結(jié)構(gòu)體數(shù)組的各元素的成員從鍵盤賦值的功能:inti;structstudentstu[30],*p=stu;/*定義結(jié)構(gòu)體數(shù)組stu和指針p,并將p指向數(shù)組的首地址*/for(i=0;i<30;i++) /*循環(huán)從鍵盤讀入每個學(xué)生的信息*/{scanf("%s%s%d%s%s%s%s",p->number,p->name,&p->age,p->sex,p->nation,p->mobile,p->address);p++;/*指針p后移到下一個元素上*/}7.3.2結(jié)構(gòu)體指針struct
結(jié)構(gòu)體類型名*指針名=結(jié)構(gòu)體數(shù)組名;7.3結(jié)構(gòu)體數(shù)組和結(jié)構(gòu)體指針的使用使用結(jié)構(gòu)體指針指向結(jié)構(gòu)體數(shù)組要注意以下兩點。(1)如果p的初值為stu,即指向第一個元素,則p加1后p就指向下一個元素的地址。例如:(++p)->name/*是先使p自加1(后移),然后得到它指向的元素中的name成員值*/(p++)->name/*是先得到p->name的值,然后使p自加1(后移),指向stu[1]*/(2)程序定義p是指向該結(jié)構(gòu)體類型的指針,即p在自加或自減時都是指向結(jié)構(gòu)體數(shù)組中每個元素的首地址,則不能將該指針指向結(jié)構(gòu)體的該元素內(nèi)的某一成員。7.3.2結(jié)構(gòu)體指針7.3結(jié)構(gòu)體數(shù)組和結(jié)構(gòu)體指針的使用【案例7-2】修改【案例7-1】,使用結(jié)構(gòu)體數(shù)組和結(jié)構(gòu)體指針實現(xiàn)其功能,使用結(jié)構(gòu)體指針指向該數(shù)組,實現(xiàn)對兩個數(shù)組元素各成員的賦值及輸出。打開源程序調(diào)試運(yùn)行程序當(dāng)為第1個學(xué)生輸入相關(guān)信息:2013011020001宋曉倩18女
漢陽市大東區(qū)勞動路32號當(dāng)為第2個學(xué)生輸入相關(guān)信息:2013011020002趙子強(qiáng)19男
漢陽市沈河區(qū)惠工街28號程序運(yùn)行結(jié)果如下:7.4結(jié)構(gòu)體與函數(shù)的關(guān)系結(jié)構(gòu)體類型的變量、指針和數(shù)組作為函數(shù)參數(shù)時需要注意以下幾點:(1)定義結(jié)構(gòu)體類型時,應(yīng)在子函數(shù)和主函數(shù)的外面定義,這樣才能在兩個函數(shù)中都使用該類型定義變量。因此,具有多個函數(shù)的C程序,應(yīng)將共用的結(jié)構(gòu)體類型定義為全局的,且放在所有函數(shù)定義之前,以便所有的函數(shù)都可以使用該類型。(2)子函數(shù)的形參為結(jié)構(gòu)體類型,應(yīng)與主函數(shù)中的調(diào)用語句中的實參類型相同。(3)指向結(jié)構(gòu)體的指針變量也可以作為函數(shù)的參數(shù)。當(dāng)函數(shù)的參數(shù)是結(jié)構(gòu)體指針變量時,可以通過結(jié)構(gòu)體指針變量間接地引用其所有成員。(4)結(jié)構(gòu)體數(shù)組作為函數(shù)的參數(shù)與普通數(shù)組作為函數(shù)參數(shù)相同,都是將實參數(shù)組的首地址傳給形參數(shù)組,兩個數(shù)組共用同一個內(nèi)存空間。所以改變形參數(shù)組中元素的各成員值,實參數(shù)組中元素的各成員值也會改變。7.4.1結(jié)構(gòu)體變量、指針和數(shù)組作為函數(shù)參數(shù)7.4結(jié)構(gòu)體與函數(shù)的關(guān)系【案例7-3】結(jié)構(gòu)體變量、指針、數(shù)組分別作為函數(shù)參數(shù)示例。打開源程序程序運(yùn)行結(jié)果如下:7.4結(jié)構(gòu)體與函數(shù)的關(guān)系函數(shù)的類型就是函數(shù)的返回值的類型,所以當(dāng)結(jié)構(gòu)體變量或指針作為函數(shù)參數(shù)時,在定義該函數(shù)時,要保證函數(shù)類型名與函數(shù)返回值類型一致。結(jié)構(gòu)體類型的變量作為函數(shù)返回值的使用方法與普通變量一致,就是將結(jié)構(gòu)體變量名返回即可。需要注意的是在這種使用方法中,結(jié)構(gòu)體類型變量的傳遞方式是值傳遞方式。結(jié)構(gòu)體類型的指針作為函數(shù)返回值時,在函數(shù)名前面加一個“*”即可,表示返回值為一個結(jié)構(gòu)體類型的指針。7.4.2結(jié)構(gòu)體變量和指針作為函數(shù)的返回值7.4結(jié)構(gòu)體與函數(shù)的關(guān)系【案例7-4】結(jié)構(gòu)體變量、指針分別作為函數(shù)返回值示例。程序分析修改【案例7-3】,增加了兩個函數(shù)search1和search2,分別為結(jié)構(gòu)體變量和結(jié)構(gòu)體指針作為函數(shù)的返回值。實現(xiàn)在結(jié)構(gòu)體數(shù)組中查找對應(yīng)學(xué)生姓名的結(jié)構(gòu)體變量,并返回該結(jié)構(gòu)體變量或結(jié)構(gòu)體指針。保留【案例7-3】中output1和output2,實現(xiàn)輸出學(xué)生信息的功能。打開源程序程序運(yùn)行結(jié)果如下:7.5共用體、枚舉和typedef類型定義C語言就提供了共同體數(shù)據(jù)類型,共用體也是一種構(gòu)造數(shù)據(jù)類型,它將不同類型的數(shù)據(jù)項存放在同一個內(nèi)存區(qū)域內(nèi),組成共用體的各個數(shù)據(jù)項也稱為成員或域,共用體也稱為聯(lián)合體。共用體與結(jié)構(gòu)體的不同之處在于:結(jié)構(gòu)體變量的各成員占用的是連續(xù)的單獨的存儲單元,而共用體變量的各成員占用的是同一個存儲單元。
1.共用體類型的定義共用體類型定義一般格式如下:7.5.1共用體union共用體類型名{
成員說明表列};7.5共用體、枚舉和typedef類型定義其中,union是關(guān)鍵字,表示后面的類型是一個共用體類型,不能省略。共用體類型名為合法的標(biāo)識符,花括號內(nèi)的成員列表用來說明組成該共用體的各個成員,對每個成員應(yīng)進(jìn)行類型說明。其成員定義方法與其他簡單類型變量一致。例如:uniondata/*共用體類型名為data*/{chara;intb;floatc;};7.5.1共用體7.5共用體、枚舉和typedef類型定義
2.共用體變量的定義共用體變量的定義和結(jié)構(gòu)體變量的定義方式相似,也有三種方法。(1)先定義共用體類型后定義共用體變量。例如:uniondata/*共用體類型名為data*/{chara;intb;floatc;};uniondatax;/*定義x為data共用體類型變量*/7.5.1共用體union共用體類型名{
成員說明表列};union共用體類型名變量名表;7.5共用體、枚舉和typedef類型定義
(2)在定義共用體類型的同時定義結(jié)構(gòu)變量。這種方法是在定義出共用體類型的同時直接定義所需變量,好處是可以簡化語句。例如上面的定義可改為:uniondata{chara;intb;floatc;}x;/*在定義共用體類型data時直接定義出變量x*/(3)直接定義共用體變量。可以省略結(jié)構(gòu)體類型名來定義一個結(jié)構(gòu)體類型。例如上面的定義還可改為:union/*此處省略了共用體類型名*/{chara;intb;floatc;}x;/*直接定義變量x,此類型不能在別處再定義其它變量*/7.5.1共用體7.5共用體、枚舉和typedef類型定義
3.共用體成員的引用及初始化對共用體變量的使用是通過對其成員的引用實現(xiàn)的,引用共用體變量成員一般格式如下:例如,給共用體變量x的b成員賦值為10,語句為:x.b=10;但共用體變量與結(jié)構(gòu)體變量不同的是,不能在定義的同時初始化,但可對第一個成員賦初值。例如:下面的兩個定義中,第一個是合法的,第二個是不合法的。uniondatax={'A'};/*合法,只為第一個成員賦初值*/uniondatax={'A',10,23.5};/*非法,為全部成員賦值是錯誤的,因為各成員共用同一空間*/7.5.1共用體共用體變量名.成員名7.5共用體、枚舉和typedef類型定義對共用體任何一個成員賦值都會導(dǎo)致共享區(qū)域數(shù)據(jù)發(fā)生變化,所以共用體只能保證有一個成員的值是有效的。7.5.1共用體圖7-5共用體變量存儲單元示意圖7.5共用體、枚舉和typedef類型定義【案例7-6】共用體示例。設(shè)計一個教師與學(xué)生通用的結(jié)構(gòu)體類型,教師信息有姓名、年齡、職業(yè)、教研室四項;學(xué)生信息有姓名、年齡、職業(yè)、班級四項。輸入一個老師或?qū)W生信息,然后顯示出來。程序分析:因為教師和學(xué)生信息有共同的三個信息,只有最后一項不同,所以設(shè)計一個共用體depart,里同有兩個成員class和office,分別表示學(xué)生的班級和教師的教研室。再設(shè)一個結(jié)構(gòu)體類型person,里面包括name(姓名)、age(年齡)、job(職業(yè))和depa(部門,教師為教研室,學(xué)生為班級)。在主函數(shù)中通過職業(yè)的值為“教師”或“學(xué)生”來決定最后一項的值為學(xué)生的“班級”還是教師的“教研室”。最后循環(huán)輸出這些信息。打開源程序程序運(yùn)行結(jié)果:7.5共用體、枚舉和typedef類型定義若某個變量只能取少數(shù)幾個值,可否將其允許取值一一列出,定義后該類型的變量只能取列出的若干個值之一?例如一周7天,一年有12個月。這些信息如果想定義為一個變量,這個變量的值只能取有限的幾個。C語言提供“枚舉”類型,就是將變量的取值指定為若干值之一,其中每個值用一個名字標(biāo)識。
1.枚舉類型的定義枚舉類型定義的一般格式如下:或?qū)憺椋?.5.2枚舉enum枚舉類型名
{枚舉值表
};enum枚舉類型名
{枚舉值表};7.5共用體、枚舉和typedef類型定義若某個變量只能取少數(shù)幾個值,可否將其允許取值一一列出,定義后該類型的變量只能取列出的若干個值之一?例如一周7天,一年有12個月。這些信息如果想定義為一個變量,這個變量的值只能取有限的幾個。C語言提供“枚舉”類型,就是將變量的取值指定為若干值之一,其中每個值用一個名字標(biāo)識。
1.枚舉類型的定義枚舉類型定義的一般格式如下:或?qū)憺椋浩渲?,enum為關(guān)鍵字,表示定義一個枚舉類型。枚舉類型名須為C語言合法的標(biāo)識符。花括號內(nèi)的標(biāo)識符稱為枚舉元素或枚舉常量,各枚舉常量之間用逗號隔開,注意右花括號后的分號“;”不能省略。7.5.2枚舉enum枚舉類型名
{枚舉值表
};enum枚舉類型名
{枚舉值表};7.5共用體、枚舉和typedef類型定義例如,定義一個枚舉類型week代表一周的七天,定義格式如下:enumweek{MON,TUE,WED,THU,FRI,SAT,SUN};應(yīng)注意的是,每個枚舉常量對應(yīng)著一個整數(shù)值。一般情況一下,枚舉類型中的枚舉常量是從0開始順序取值的。如上面語句中,從MON到SUN的取值分別為0、1、2、3、4、5、6。也可以顯式指定各枚舉常量的值,如:enumweek{MON=1,TUE,WED,THU,FRI,SAT,SUN};這時從MON到SUN的取值分別為1、2、3、4、5、6、7,每個值順序加1。也可以分隔著定義各常量的值,這時在顯式定義的值后面的各隱式的值是顯式的值依次加1,直到下一個顯式的值改變,如:enumcolor{red=0,yellow,blue=3,white,black};此時,red=0,則red之后的yellow順序增1,yellow為1;同理blue=3,則white為4,black為5。7.5.2枚舉7.5共用體、枚舉和typedef類型定義2.枚舉型變量的定義(1)先定義枚舉類型后定義枚舉型變量。與結(jié)構(gòu)體或共用體類型變量定義的基本方法相似,這種方法就是先定義枚舉類型,然后使用“enum枚舉類型名”來定義這種類型的變量,例如:enumweek{MON,TUE,WED,THU,FRI,SAT,SUN};/*定義week類型*/enumweekday;/*定義week類型的枚舉變量day*/(2)在定義枚舉類型的同時定義枚舉型變量。這種方法是在定義枚舉類型的后面直接定義出該類型的變量,可以簡化程序。enumweek{MON,TUE,WED,THU,FRI,SAT,SUN}day;/*在定義week類型同時定義變量day*/(3)直接定義枚舉類型變量。這種定義方法可以省略枚舉類型名,直接定義出枚舉變量。但這種方法不能在其他位置再定義這種枚舉類型的變量。enum{MON,TUE,WED,THU,FRI,SAT,SUN}day;/*在定義枚舉類型時直接定義變量day*/7.5.2枚舉7.5共用體、枚舉和typedef類型定義3.枚舉變量的使用枚舉型變量只能取相應(yīng)枚舉類型列表中的各值,如:enumweek{MON=1,TUE,WED,THU,FRI,SAT,SUN}day;/*定義枚舉類型week和枚舉變量day*/day=WED;/*枚舉變量day賦值為WED*/7.5.2枚舉提示:使用枚舉類型需要注意的地方(1)在枚舉類型定義中,枚舉常量的命名規(guī)則與標(biāo)識符相同,并且不能另作它用。(2)枚舉常量不是變量,不能在程序中用賦值語句對其賦值。例如:為常量MON賦值語句:MON=56;是錯誤的。(3)只能把枚舉常量賦給枚舉變量,不能把對應(yīng)的整數(shù)直接賦給枚舉變量,但可以用強(qiáng)制類型轉(zhuǎn)換來進(jìn)行轉(zhuǎn)換。如,day=7;語句是錯誤的,但day=(enumweek)7;語句則是正確的。(4)枚舉常量不是字符常量也不是字符串常量,使用時不能加單、雙引號。(5)輸出枚舉常量或枚舉變量的整數(shù)值時,應(yīng)使用整型輸出格式符。若要輸出枚舉常量名,需經(jīng)過轉(zhuǎn)換??梢杂靡韵抡Z句輸出其常量名。day=MON;if(day==MON)printf("MONDAY");(6)枚舉常量可以進(jìn)行比較運(yùn)算,由它們對應(yīng)的整數(shù)參加比較。7.5共用體、枚舉和typedef類型定義【案例7-7】從鍵盤中輸入一個1~7之間的整數(shù),并把它轉(zhuǎn)換為星期一到星期日顯示。注意枚舉類型的定義及使用方法。程序分析:因為只有1~7這幾個數(shù)字是有效的,所以定義一個枚舉類型為week的變量day,然后從鍵盤輸入一個整數(shù),將其轉(zhuǎn)換成enumweek類型后賦給變量day,再使用switch開關(guān)語句對day進(jìn)行判斷,并輸出對應(yīng)的星期值。若不是這7個正確的值,則輸出錯誤提示信息。打開源程序程序運(yùn)行結(jié)果:當(dāng)輸入一個正確的數(shù)字3和一個錯誤的數(shù)字9時,程序運(yùn)行結(jié)果如下:
7.5共用體、枚舉和typedef類型定義在學(xué)習(xí)鏈表的知識時,定義結(jié)構(gòu)體類型的指針,每次都需使用struct加上結(jié)構(gòu)體名來定義,十分麻煩。C語言可以將這種書寫復(fù)雜的類型名重新定義,變成一個像整型、浮點型那樣的簡單定義格式嗎?C語言提供給用戶一個重新定義類型的語句,那就是typedef語句,使用它,可以將復(fù)雜的構(gòu)造類型重新定義成一個簡單類型,這樣書寫的時候十分方便。使用typedef重新定義一個類型名格式如下:其中,typedef為關(guān)鍵字,表示重定義。原類型名是C語言提供的任一種數(shù)據(jù)類型,可以是簡單數(shù)據(jù)類型,也可以是構(gòu)造數(shù)據(jù)類型;新類型名是代表原類型名的一個別名。使用新類型名可以像使用原類型名那樣定義變量了。7.5.3typedef聲明新的類型名typedef
原類型名
新類型名;7.5共用體、枚舉和typedef類型定義例如:typedefintInteger;/*將int類型重新起別名為Integer*/Integerx,y;/*使用Integer定義變量x和y,與用int定義等價*/再如,原來有一個結(jié)構(gòu)體類型birthday,其結(jié)構(gòu)類型及變量定義如下:structbirthday /*定義結(jié)構(gòu)體類型birthday*/{intyear,month,day;/*定義年、月、日3個成員值*/};structbirthdaydate; /*定義birthday結(jié)構(gòu)體類型的變量date*/現(xiàn)在使用typedef語句就可以重定義為如下格式:typedefstructbirthday{intyear,month,day; /*定義年、月、日3個成員值*/}Birth; /*定義birthday結(jié)構(gòu)體類型并重命名為Birth*/Birthdate;/*使用Birth類型(birthday的別名)定義變量date*/7.5.3typedef聲明新的類型名*7.6鏈表C語言提供一種動態(tài)存儲分配的數(shù)據(jù)結(jié)構(gòu),事先不必確定其長度,且各元素不必順序存放,各元素之間以指針相互鏈接,稱為單鏈表,其結(jié)點結(jié)構(gòu)如圖7-3所示。其中,data部分稱為數(shù)據(jù)域,用于存儲一個數(shù)據(jù)元素的信息。next部分稱為指針域,用于存儲其直接后繼的存儲地址的信息。7.6.1鏈表基礎(chǔ)知識及動態(tài)分配函數(shù)圖7-3單鏈表的結(jié)點示意圖*7.6鏈表在圖7-4中,head為頭指針,該指針指向鏈表的第一個結(jié)點,該結(jié)點稱為頭結(jié)點,不存放任何信息。其中,“∧”表示空指針,在程序中可用常量NULL來表示,它表示鏈表的結(jié)束。單鏈表分為帶頭結(jié)點(其next域指向鏈表第一個結(jié)點的存儲地址)和不帶頭結(jié)點兩種類型。帶頭結(jié)點的鏈表中每個結(jié)點的存儲地址均放在其前驅(qū)結(jié)點中,這樣算法對所有的結(jié)點處理可一致化,因此,本書討論的單鏈表均指帶頭結(jié)點的單鏈表。帶頭結(jié)點的空單鏈表如圖7-4(a)所示,帶頭結(jié)點的非空單鏈表如圖7-4(b)所示。7.6.1鏈表基礎(chǔ)知識及動態(tài)分配函數(shù)圖7-4單鏈表示意圖*7.6鏈表單鏈表的結(jié)構(gòu)體類型及指針定義如下:structnode{intdata; /*定義數(shù)據(jù)域*/structnode*next; /*定義指針域*/};structnode*head; /*定義結(jié)構(gòu)體類型的頭指針*/7.6.1鏈表基礎(chǔ)知識及動態(tài)分配函數(shù)*7.6鏈表1.分配一個內(nèi)存空間函數(shù)mallocmalloc函數(shù)的調(diào)用格式如下:在內(nèi)存中分配一個長度為size的連續(xù)存儲空間,返回值是新分配存儲空間的首地址,若內(nèi)存不足,則返回NULL。例如:int*pt;pt=(int*)malloc(sizeof(int));/*動態(tài)生成一個整型變量并將pt指向它*/該程序段表示分配了一個int型的內(nèi)存空間,并將pt指向該空間的首地址。其中的(int*)是強(qiáng)制將其后面的變量轉(zhuǎn)換為整型指針,賦給左邊的指針變量pt。7.6.1鏈表基礎(chǔ)知識及動態(tài)分配函數(shù)指針名=(類型名*)malloc(size);*7.6鏈表2.分配n個內(nèi)存空間函數(shù)calloccalloc函數(shù)的調(diào)用格式如下:在內(nèi)存中分配n塊長度為size的連續(xù)存儲空間,返回值是新分配存儲空間的首地址,若內(nèi)存不足,則返回NULL。calloc函數(shù)與malloc函數(shù)均用于動態(tài)分配存儲空間,區(qū)別在于calloc函數(shù)可以一次分配n塊區(qū)域。例如:char*p;p=(char*)calloc(5,sizeof(char));表示分配5個且每個大小為1個字節(jié)的連續(xù)空間,將其類型強(qiáng)制轉(zhuǎn)換為字符類型并賦給p,結(jié)果即讓p指向該存儲空間的首地址。7.6.1鏈表基礎(chǔ)知識及動態(tài)分配函數(shù)指針名=(類型名*)calloc(n,size);*7.6鏈表3.釋放內(nèi)存空間函數(shù)freefree函數(shù)的調(diào)用格式如下:釋放該指針?biāo)傅囊粔K存儲空間,該空間系統(tǒng)可另作它用。注意這個指針?biāo)傅目臻g必須是由malloc函數(shù)分配的才行,free函數(shù)無返回值。例如:int*pt; /*定義一個整型指針pt*/pt=(int*)malloc(sizeof(int));/*動態(tài)生成一個整型變量并將pt指向它*/free(pt); /*釋放pt所指的內(nèi)存單元*/7.6.1鏈表基礎(chǔ)知識及動態(tài)分配函數(shù)free(指針名);*7.6鏈表鏈表常用的操作有鏈表的初始化、鏈表的建立、求鏈表長度、元素的查找、元素的插入、刪除操作等。
1.單鏈表的初始化單鏈表的初始化即構(gòu)造一個僅包含頭結(jié)點的空單鏈表。其過程是首先申請一個結(jié)點并讓指針head指向該結(jié)點,然后將它的指針域賦為空(NULL),最后返回頭指針head。
2.單鏈表的建立設(shè)一個尾指針last,使其指向當(dāng)前鏈表的尾結(jié)點。每讀入有效的數(shù)據(jù)則申請一個結(jié)點s,并將讀取的數(shù)據(jù)存放到新結(jié)點s的數(shù)據(jù)域中,將s的尾指針設(shè)為空指針(NULL),然后將新結(jié)點插入到當(dāng)前鏈表尾部(last指針?biāo)傅慕Y(jié)點后面),直到循環(huán)結(jié)束為止。3.求鏈表長度操作因為鏈表是鏈?zhǔn)浇Y(jié)構(gòu),所以鏈表中元素個數(shù)不是已知的。想求表中元素個數(shù)還要設(shè)一個計數(shù)變量j(初值為0),將一個指針p先指向鏈表中第一個元素,當(dāng)p不為空時,循環(huán)將p指針后移,j加1,循環(huán)結(jié)束后j值即為鏈表長度。7.6.2鏈表的操作*7.6鏈表4.元素的按值查找操作從鏈表的第一個元素結(jié)點開始,由前向后依次比較單鏈表中各結(jié)點數(shù)據(jù)域中的值,若某結(jié)點數(shù)據(jù)域中的值與給定的值x相等,則循環(huán)結(jié)束;否則繼續(xù)向后比較直到表結(jié)束,然后判斷指針p,若p不為空表示單鏈表中有x結(jié)點,輸出查找成功的信息并輸出x所在表中的位置;否則輸出查找失敗的信息。5.插入操作順序表的插入操作需要移動大量的數(shù)據(jù)元素,而鏈表的插入只需修改指針而無需移動原來表中元素,那鏈表的插入操作是如何實現(xiàn)呢?在指針?biāo)傅慕Y(jié)點后插入新結(jié)點。若要在鏈表中指針p所指位置后面插入一個結(jié)點,則插入操作步驟如下。(1)先將結(jié)點s的指針域指向結(jié)點p的下一個結(jié)點(執(zhí)行語句s->next=p->next)。(2)再將結(jié)點p的指針域改為指向新結(jié)點s(執(zhí)行語句p->next=s)。7.6.
溫馨提示
- 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 石膏生產(chǎn)流程管理制度
- 資產(chǎn)登記保管制度
- 護(hù)理質(zhì)量與公共衛(wèi)生
- 2026上半年黑龍江工程學(xué)院事業(yè)單位招聘14人參考考試試題附答案解析
- 2026山東聊城市新聊泰城市建設(shè)發(fā)展有限公司首批用人招聘10人備考考試題庫附答案解析
- 2026年馬鞍山市交通運(yùn)輸綜合行政執(zhí)法支隊公開選調(diào)工作人員14名備考考試題庫附答案解析
- 2026年上半年黑龍江事業(yè)單位聯(lián)考大慶市招聘164人備考考試試題附答案解析
- 2026新疆博爾塔拉州博樂市中西醫(yī)結(jié)合醫(yī)院面向全市選聘義務(wù)行風(fēng)監(jiān)督員備考考試試題附答案解析
- 2026年福建莆田市司法局市學(xué)園公證處編外人員4人備考考試試題附答案解析
- 2026江西九江市德安縣消防大隊招聘2人參考考試試題附答案解析
- 高中期末家長會
- 2023年度國家社科基金一般項目申請書(語言學(xué))立項成功范本,特珍貴
- 風(fēng)機(jī)系統(tǒng)巡檢內(nèi)容及標(biāo)準(zhǔn)
- 新生兒高血糖護(hù)理課件
- 熱食類食品制售管理制度
- 五金件外觀檢驗標(biāo)準(zhǔn)
- 香精概論第四章-芳香療法課件
- 電梯安裝調(diào)試工地EHS管理要求和交底
- 車輛考核制度6篇
- JJF 1487-2014超聲波探傷試塊校準(zhǔn)規(guī)范
- GB/T 39253-2020增材制造金屬材料定向能量沉積工藝規(guī)范
評論
0/150
提交評論