第14章結(jié)構(gòu)體、共用體、枚舉和typedef_第1頁(yè)
第14章結(jié)構(gòu)體、共用體、枚舉和typedef_第2頁(yè)
第14章結(jié)構(gòu)體、共用體、枚舉和typedef_第3頁(yè)
第14章結(jié)構(gòu)體、共用體、枚舉和typedef_第4頁(yè)
第14章結(jié)構(gòu)體、共用體、枚舉和typedef_第5頁(yè)
已閱讀5頁(yè),還剩27頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、第14章 結(jié)構(gòu)體、共用體、枚舉和typedef 程序設(shè)計(jì)中,如何合理組織數(shù)據(jù)是門(mén)大學(xué)問(wèn),前面介紹過(guò)的數(shù)組是種組織數(shù)據(jù)的方式,但數(shù)組只適用于同類(lèi)型的數(shù)據(jù),如果類(lèi)型不同又當(dāng)如何?而且,現(xiàn)實(shí)中,很多東西都具有不同的屬性,以人為例,像姓名、性別、身高等等都是其屬性,如何合理存儲(chǔ)并方便地訪問(wèn)這些信息,是本章介紹的內(nèi)容。14.1 什么是結(jié)構(gòu)體 仍以人為例來(lái)介紹,要管理姓名、單位、Email地址、聯(lián)系電話等信息,現(xiàn)實(shí)生活中,很多人采用名片的形式,將這些信息印在一張卡片上。收集的一張張名片大大方便了數(shù)據(jù)的管理,將這種理念借鑒到C語(yǔ)言程序設(shè)計(jì)中,是否有類(lèi)似于名片的那么一種變量呢? 有,答案就是“結(jié)構(gòu)體變量”,是

2、一種復(fù)合變量,在進(jìn)一步說(shuō)明結(jié)構(gòu)體變量前,先來(lái)看“結(jié)構(gòu)體”的概念,結(jié)構(gòu)體和結(jié)構(gòu)體變量的關(guān)系類(lèi)似與類(lèi)型與普通變量的關(guān)系,結(jié)構(gòu)體中說(shuō)明了結(jié)構(gòu)體變量的信息格式,而結(jié)構(gòu)體變量是結(jié)構(gòu)體的實(shí)例。14.1.1 結(jié)構(gòu)體的定義只有定義了一個(gè)結(jié)構(gòu)體,才能聲明并使用結(jié)構(gòu)體變量,正如,只有確定了名片上要印什么內(nèi)容,才能開(kāi)始印刷名片。結(jié)構(gòu)體的定義就是說(shuō)明結(jié)構(gòu)體變量要存儲(chǔ)什么信息的過(guò)程。C語(yǔ)言提供了關(guān)鍵字struct來(lái)定義一個(gè)結(jié)構(gòu),一般形式的結(jié)構(gòu)定義為:struct 結(jié)構(gòu)名稱(chēng)(或稱(chēng)標(biāo)識(shí))存儲(chǔ)數(shù)據(jù)列表;(或稱(chēng)成員變量列表);注意:在定義結(jié)構(gòu)時(shí),一定不要忘記花括號(hào)后的分號(hào),因?yàn)榻Y(jié)構(gòu)的定義可以看成一條完整的C+語(yǔ)句,否則編譯器會(huì)

3、報(bào)錯(cuò)。舉例來(lái)說(shuō),struct personchar name20;int age;char email50;14.1.2 聲明結(jié)構(gòu)體變量以上面person結(jié)構(gòu)為例,定義完畢后,person就可以看成是一種類(lèi)型,可以通過(guò)下述形式聲明結(jié)構(gòu)體變量zangsan:struct person zangsan;注意區(qū)分person和zangsan,person只是結(jié)構(gòu)體定義,是種規(guī)范說(shuō)明,編譯器并不為其分配內(nèi)存空間,而zangsan是實(shí)實(shí)在在的結(jié)構(gòu)體變量,占據(jù)一定的內(nèi)存空間。在定義結(jié)構(gòu)體的同時(shí)也可以完成一個(gè)或多個(gè)結(jié)構(gòu)體變量的聲明,舉例來(lái)說(shuō):struct personchar name20;int age;

4、char email50;zangsan,lisi,wangwu,*zaoliu;上述代碼在定義結(jié)構(gòu)體person的同時(shí),一口氣聲明了3個(gè)結(jié)構(gòu)體變量:zangsan,lisi,wangwu,甚至還聲明了一個(gè)指向person結(jié)構(gòu)的指針zaoliu。14.1.3 初始化結(jié)構(gòu)變量在聲明結(jié)構(gòu)變量的同時(shí),可以進(jìn)行變量的初始化,對(duì)結(jié)構(gòu)體中每個(gè)數(shù)據(jù)初始化,用逗號(hào)隔開(kāi),并用花括號(hào)包裹起來(lái),舉例來(lái)看:struct person zangsan=“Zang San”, 24, “”;還可以將結(jié)構(gòu)體定義,結(jié)構(gòu)體變量聲明和初始化放在一起來(lái)完成,如:struct personchar name20;int age;ch

5、ar email50;zangsan=“Zang San”, 24, “”, *pzs=&zangsan;14.1.4 訪問(wèn)結(jié)構(gòu)體成員習(xí)慣上將諸如字符串name、int變量age和字符串email等稱(chēng)為結(jié)構(gòu)體person及其聲明變量的“數(shù)據(jù)成員”,簡(jiǎn)稱(chēng)“成員”。聲明了一個(gè)結(jié)構(gòu)體變量后,可以使用成員操作符(.)來(lái)訪問(wèn)各個(gè)成員(內(nèi)部存儲(chǔ)的數(shù)據(jù)),如,zangsan.age和zangsan.emal分別代表zangsan這個(gè)變量(結(jié)構(gòu)體變量)中存儲(chǔ)的姓名、年齡和email等信息,來(lái)看一段示例:代碼 訪問(wèn)結(jié)構(gòu)體變量中的數(shù)據(jù)成員StructSample14.1.5 結(jié)構(gòu)體

6、定義的位置讀者可以做個(gè)有趣的嘗試:將中結(jié)構(gòu)體定義的部分轉(zhuǎn)移到main函數(shù)的后面,重新編譯運(yùn)行,會(huì)發(fā)生什么?編譯器會(huì)報(bào)一大堆的錯(cuò)誤,正如“使用變量前必須先對(duì)其聲明”一樣,在使用結(jié)構(gòu)體類(lèi)型聲明結(jié)構(gòu)體變量之前,必須要先進(jìn)行結(jié)構(gòu)體的定義,編譯器據(jù)此才知道如何為結(jié)構(gòu)體中的數(shù)據(jù)成員分配內(nèi)存空間,才能聲明結(jié)構(gòu)體變量。除了如的定義方式外,結(jié)構(gòu)體還可以定義在函數(shù)(包括main函數(shù))中,兩種定義方式的區(qū)別在于結(jié)構(gòu)體可見(jiàn)域不同,如果定義在函數(shù)外,從定義處到本文件結(jié)束,結(jié)構(gòu)體都可見(jiàn),可用結(jié)構(gòu)體聲明結(jié)構(gòu)體變量,但如果定義在特定函數(shù)中,只有定義處到該函數(shù)結(jié)束,結(jié)構(gòu)體可見(jiàn),如果在函數(shù)外使用結(jié)構(gòu)體聲明結(jié)構(gòu)體變量,可能會(huì)引發(fā)錯(cuò)

7、誤。一種推薦的寫(xiě)法是將結(jié)構(gòu)體定義在頭文件中,只要某文件A包含了此頭文件,便可在A中自由聲明結(jié)構(gòu)體變量。14.1.6 結(jié)構(gòu)體變量賦值C語(yǔ)言不允許使用一個(gè)數(shù)組直接為另一個(gè)數(shù)組賦值,但使用一個(gè)結(jié)構(gòu)體變量為另一個(gè)結(jié)構(gòu)體變量賦值是合法的,可以使用賦值操作符(=)將一個(gè)結(jié)構(gòu)變量B賦值給另一個(gè)結(jié)構(gòu)變量A,這樣,結(jié)構(gòu)變量A中的每個(gè)成員都將被設(shè)置成結(jié)構(gòu)變量B中相應(yīng)成員的值,即使成員是數(shù)組類(lèi)型也不例外,這種賦值方式被成為成員賦值,見(jiàn)示:14.2 特殊結(jié)構(gòu)體 上一節(jié)中討論的person結(jié)構(gòu)相對(duì)簡(jiǎn)單,只包含了3個(gè)數(shù)據(jù)成員:name、age和email,如果面對(duì)的是更為復(fù)雜的結(jié)構(gòu),將所有的數(shù)據(jù)成員并排似乎不是個(gè)高效的方

8、法,那能否使用結(jié)構(gòu)體嵌套,一層層管理數(shù)據(jù)呢?14.2.1 結(jié)構(gòu)體嵌套顧名思義,結(jié)構(gòu)體嵌套就是“結(jié)構(gòu)體套結(jié)構(gòu)體”,某個(gè)結(jié)構(gòu)的數(shù)據(jù)成員也是一個(gè)結(jié)構(gòu)體變量,這樣,可以按層次結(jié)構(gòu)合理組織數(shù)據(jù),舉例來(lái)說(shuō):struct studentchar name20;struct scorestruct/*結(jié)構(gòu)體scorestruct的定義*/int math;int English;score;/*聲明結(jié)構(gòu)體變量score*/struct infostruct/*結(jié)構(gòu)體infostruct的定義*/float height;float weight;info;/*聲明結(jié)構(gòu)體變量info*/;14.2.2 匿名結(jié)構(gòu)

9、體C語(yǔ)言允許定義匿名結(jié)構(gòu),所謂匿名結(jié)構(gòu),就是不指定結(jié)構(gòu)體的名稱(chēng),但一定要在結(jié)構(gòu)體定義的同時(shí)聲明至少一個(gè)結(jié)構(gòu)體變量,否則,這種用法沒(méi)有意義,如:structchar name20;int age;wangwu, lisi;這樣便聲明創(chuàng)建了兩個(gè)結(jié)構(gòu)體變量wangwu和lisi,可以通過(guò)諸如“”等形式來(lái)訪問(wèn)其成員,但這種類(lèi)型沒(méi)有名稱(chēng),因此無(wú)法在以后的程序中聲明這種類(lèi)型的變量。14.3 共用體 共用體也是一種特殊的數(shù)據(jù)組織方式,C語(yǔ)言使用關(guān)鍵字union來(lái)定義一個(gè)共用體結(jié)構(gòu),所以,在某些書(shū)籍中也將共用體稱(chēng)為“聯(lián)合”。和結(jié)構(gòu)體類(lèi)似,共用體的使用也分為“共用體的定義”、“共用體變量的

10、聲明、初始化和使用”兩大部分。14.3.1 什么是共用體 和結(jié)構(gòu)一樣,共用體也是由數(shù)據(jù)成員組成的,但在結(jié)構(gòu)中,編譯器為每個(gè)數(shù)據(jù)成員都分配內(nèi)存地址空間,但對(duì)共用體來(lái)說(shuō),所有的數(shù)據(jù)成員共用一塊內(nèi)存,這個(gè)“共用”似乎有些費(fèi)解,理解方式應(yīng)當(dāng)是“在某個(gè)確定的時(shí)刻,共用體只能表示一種成員類(lèi)型”。14.3.2 共用體的定義共用體可采用如下形式定義:union 共用體名稱(chēng)(或稱(chēng)標(biāo)識(shí))存儲(chǔ)數(shù)據(jù)列表(或稱(chēng)成員變量列表);注意,結(jié)束花括號(hào)后的分號(hào)(;)不要遺漏,這種定義形式是一個(gè)完整的C+語(yǔ)句。舉例來(lái)說(shuō):union computerInfo/*定義一個(gè)共用體computerInfo*/char typeid20;f

11、loat price;某個(gè)部門(mén)要登記所有的電腦,如果是品牌機(jī),就登記型號(hào)(typeid),如果是組裝機(jī),就登記價(jià)格(price),因此,型號(hào)和價(jià)格只取其一,這時(shí)使用共用體最為合適。14.3.3 聲明共用體變量 和結(jié)構(gòu)體的使用方式一樣,定義了共用體后,共用體名可以看成是一種類(lèi)型,用其可聲明共用體變量,基本格式為: union 共用體名 共用體變量; 在定義共用體的同時(shí)也可以完成一個(gè)或多個(gè)共用體變量的聲明,舉例來(lái)說(shuō): union computerInfo/*定義一個(gè)共用體computerInfo*/ char typeid20; float price; comp1, comp2;14.3.4 共

12、用體變量的初始化在聲明一個(gè)共用體比昂兩的同時(shí),可以完成其初始化,與結(jié)構(gòu)變量的初始化不同的是,只能對(duì)共用體變量列表中的一個(gè)變量進(jìn)行初始化,對(duì)前面定義的共用體computerInfo來(lái)說(shuō),下列語(yǔ)句是合法的:computerInfo com1=Asus X80;computerInfo com1=6000;與結(jié)構(gòu)類(lèi)似,可以把共用體定義、共用體變量聲明及其初始化放在一起,如:union computerInfo/*定義一個(gè)共用體computerInfo*/char typeid20;float price;comp1= Asus X80;14.3.5 共用體成員訪問(wèn)不論共用體在定義時(shí)成員列表中有多少項(xiàng)

13、,在某個(gè)確定時(shí)刻,共用體變量只能存儲(chǔ)一個(gè)成員,來(lái)看一個(gè)示例: 14.3.6 共用體賦值 從本質(zhì)上理解,共用體實(shí)際上是為不同的成員分配一塊共用內(nèi)存,編譯器并不會(huì)約束存入這塊內(nèi)存的值,關(guān)鍵在于程序員如何解析這塊內(nèi)存,如何使用存入的內(nèi)容。 C語(yǔ)言允許共用體變量間的賦值,且無(wú)論是結(jié)構(gòu)體變量的賦值還是共用體變量的賦值,實(shí)際上都是內(nèi)存單元的照搬復(fù)制。 14.4 結(jié)構(gòu)體和共用體的內(nèi)存差異 結(jié)構(gòu)體變量和共用體變量是兩種復(fù)合類(lèi)型的變量,對(duì)C語(yǔ)言內(nèi)置的基本數(shù)據(jù)類(lèi)型,我們都明確知道其占用的內(nèi)存空間大小,但結(jié)構(gòu)體變量和共用體變量占據(jù)多大的內(nèi)存空間呢??jī)煞N變量在內(nèi)存中的表示形式有何差別?這是本節(jié)討論的問(wèn)題。14.4.1

14、 結(jié)構(gòu)體變量和共用體變量?jī)?nèi)存形式的不同前面以及提到,編譯器會(huì)為結(jié)構(gòu)體變量中的每個(gè)數(shù)據(jù)成員分配不同的地址空間,也就是說(shuō),結(jié)構(gòu)體變量中的數(shù)據(jù)程序是并列關(guān)系,而編譯器為共用體變量中的數(shù)據(jù)成員分配的是同一塊內(nèi)存,每個(gè)時(shí)刻只有一個(gè)數(shù)據(jù)成員有意義,從地址的角度來(lái)看兩者的差異,形象地表明了這一點(diǎn)。14.4.2 結(jié)構(gòu)體變量的內(nèi)存大小直觀上理解,結(jié)構(gòu)體變量占據(jù)的內(nèi)存單元的個(gè)數(shù)應(yīng)當(dāng)是其內(nèi)部所有數(shù)據(jù)成員占據(jù)內(nèi)存單元數(shù)的和,但實(shí)際情況卻并非如此,來(lái)看一段:14.4.3 字節(jié)對(duì)齊 出于效率的考慮,C語(yǔ)言引入了字節(jié)對(duì)齊機(jī)制,一般來(lái)說(shuō),不同的編譯器字節(jié)對(duì)齊機(jī)制有所不同,但還是有以下3條通用準(zhǔn)則: (1)結(jié)構(gòu)體變量的首地址能

15、夠被其最寬基本類(lèi)型成員的大小所整除; (2)結(jié)構(gòu)體每個(gè)成員相對(duì)于結(jié)構(gòu)體首地址的偏移量(offset)都是成員大小的整數(shù)倍,如有需要編譯器會(huì)在成員之間加上填充字節(jié)(internal adding); (3)結(jié)構(gòu)體的總大小為結(jié)構(gòu)體最寬基本類(lèi)型成員大小的整數(shù)倍,如有需要編譯器會(huì)在最末一個(gè)成員之后加上填充字節(jié)(trailing padding)。14.4.4 最寬基本類(lèi)型字節(jié)對(duì)齊第3條準(zhǔn)則提及最寬基本類(lèi)型的概念,所謂基本類(lèi)型是指像char、short、int、float、double這樣的內(nèi)置數(shù)據(jù)類(lèi)型?!皵?shù)據(jù)寬度”就是指其sizeof的大小。諸如結(jié)構(gòu)體、共用體和數(shù)組等都不是基本數(shù)據(jù)類(lèi)型,來(lái)看一段示例:

16、14.4.5 共用體的大小原則上,共用體的大小取決于占據(jù)最多內(nèi)存的成員的長(zhǎng)度,如:union Example char c;short s;float f; 則sizeof(Example)的結(jié)果為4,但字節(jié)對(duì)齊準(zhǔn)則3,“結(jié)構(gòu)體的總大小為結(jié)構(gòu)體最寬基本類(lèi)型成員大小的整數(shù)倍,如有需要編譯器會(huì)在最末一個(gè)成員之后加上填充字節(jié)(trailing padding)”仍然成立,來(lái)看下面的共用體定義:union Examplechar c9;double d; 14.5 枚舉類(lèi)型 從字面上理解,枚舉是“列舉所有情況”的意思,C語(yǔ)言中,枚舉類(lèi)型也是這么用的,枚舉類(lèi)型是種用戶自定義的類(lèi)型,在定義枚舉類(lèi)型時(shí),需指

17、明其取值集合,用枚舉類(lèi)型聲明枚舉變量時(shí),只能取集合中的某項(xiàng)作為其值,這在一定程度上保證了取值的安全性。14.5.1 枚舉類(lèi)型的定義C語(yǔ)言提供了關(guān)鍵字Enum定義枚舉類(lèi)型,基本格式為:enum 枚舉類(lèi)型名 枚舉常量1=整型常數(shù),枚舉常量2=整型常數(shù),;作為一條完整的C語(yǔ)句,不要忘記結(jié)尾的分號(hào)。枚舉類(lèi)型的定義包括以下要素:枚舉類(lèi)型名,有效的C語(yǔ)言標(biāo)識(shí)符。枚舉表,即“枚舉常量1=整型常數(shù),枚舉常量2=整型常數(shù),”部分,枚舉表是枚舉常量的集合,枚舉表中每項(xiàng)后的“=整型常數(shù)”是給枚舉常量賦初值,方括號(hào)代表賦初值的操作可以省略。如果不給枚舉常量賦初值,編譯器會(huì)為每一個(gè)枚舉常量賦一個(gè)不同的整型值,第一個(gè)為0

18、,第二個(gè)為1,等等。當(dāng)枚舉表中某個(gè)常量賦值后,其后的成員則按依次加1的規(guī)則確定其值。來(lái)看一個(gè)簡(jiǎn)單的例子: enum day Sunday,Monday,Tuesday,Wednesday,Thursday,F(xiàn)riday,Saturday;14.5.2 聲明枚舉變量 定義了枚舉類(lèi)型day后,便可聲明day型枚舉變量,如: enum day today; 上述語(yǔ)句聲明了day型變量today。注意,today只能取枚舉表中的某項(xiàng)作為其值,枚舉變量在其枚舉表成員之外取值是不允許的。 可在枚舉類(lèi)型定義的同時(shí)聲明該類(lèi)型的變量,如: enum day Sunday,Monday,Tuesday,Wedne

19、sday,Thursday,F(xiàn)riday,Saturday toay;14.5.3 枚舉常量是什么在上面定義的枚舉類(lèi)型day中,諸如Monday、Tuesday等稱(chēng)為枚舉常量,有個(gè)疑問(wèn):枚舉常量到底是什么?來(lái)看一段示例:代碼 枚舉常量EnumConst#include /*使用printf要包含的頭文件*/#include enum color Red,Green,Blue,Black,White;/*枚舉類(lèi)型的定義*/void main(void)/*主函數(shù)*/enum color c1=Blue;printf(Blue is %d,c1);/*枚舉常量是整型*/getch();/*等待,按

20、任意鍵繼續(xù)*/輸出結(jié)果為Blue is 214.6 給類(lèi)型取個(gè)別名typedef 可以給某個(gè)已經(jīng)存在的類(lèi)型取個(gè)別名,使其更易寫(xiě)、更易記,C語(yǔ)言中提供了兩種方法,一是使用“#define”語(yǔ)句,另一個(gè)方法是使用typedef語(yǔ)句,兩者之間存在細(xì)微的差別。14.6.1 typedef基本用法 先來(lái)看一個(gè)直觀的例子: typedef double* DP; typedef為double* 引入了一個(gè)新的助記符DP,在程序中可使用DP聲明一個(gè)指向double型變量的指針,如: DP pDouble1, pDouble2; 上述代碼聲明了兩個(gè)double型的指針變量pDouble1和pDouble2。14.6.2 #define用法#define語(yǔ)句稱(chēng)為預(yù)定義語(yǔ)句,是預(yù)處理指令,在編譯預(yù)處理時(shí)進(jìn)行簡(jiǎn)單的替換,不做正

溫馨提示

  • 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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論