c語言從入門到精通第7章_第1頁
c語言從入門到精通第7章_第2頁
c語言從入門到精通第7章_第3頁
c語言從入門到精通第7章_第4頁
c語言從入門到精通第7章_第5頁
已閱讀5頁,還剩66頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、第17章結(jié)構(gòu)體和聯(lián)合體p 結(jié)構(gòu)體 p 結(jié)構(gòu)體數(shù)組 p 結(jié)構(gòu)體指針 p 結(jié)構(gòu)體與函數(shù) p 聯(lián)合體 p 結(jié)構(gòu)體和聯(lián)合體的區(qū)別與聯(lián)系 p 綜合應(yīng)用計算學生成績 p 跟我上機 第17章結(jié)構(gòu)體和聯(lián)合體 結(jié)構(gòu)體 p 結(jié)構(gòu)體數(shù)組 p 結(jié)構(gòu)體指針 p 結(jié)構(gòu)體與函數(shù) p 聯(lián)合體 p 結(jié)構(gòu)體和聯(lián)合體的區(qū)別與聯(lián)系 p 綜合應(yīng)用計算學生成績 p 跟我上機 第17章結(jié)構(gòu)體和聯(lián)合體 結(jié)構(gòu)體 結(jié)構(gòu)體數(shù)組 p 結(jié)構(gòu)體指針 p 結(jié)構(gòu)體與函數(shù) p 聯(lián)合體 p 結(jié)構(gòu)體和聯(lián)合體的區(qū)別與聯(lián)系 p 綜合應(yīng)用計算學生成績 p 跟我上機 第17章結(jié)構(gòu)體和聯(lián)合體 結(jié)構(gòu)體 結(jié)構(gòu)體數(shù)組 結(jié)構(gòu)體指針 p 結(jié)構(gòu)體與函數(shù) p 聯(lián)合體 p 結(jié)構(gòu)體和聯(lián)合體

2、的區(qū)別與聯(lián)系 p 綜合應(yīng)用計算學生成績 p 跟我上機 第17章結(jié)構(gòu)體和聯(lián)合體 結(jié)構(gòu)體 結(jié)構(gòu)體數(shù)組 結(jié)構(gòu)體指針 結(jié)構(gòu)體與函數(shù) p 聯(lián)合體 p 結(jié)構(gòu)體和聯(lián)合體的區(qū)別與聯(lián)系 p 綜合應(yīng)用計算學生成績 p 跟我上機 第17章結(jié)構(gòu)體和聯(lián)合體 結(jié)構(gòu)體 結(jié)構(gòu)體數(shù)組 結(jié)構(gòu)體指針 結(jié)構(gòu)體與函數(shù) 聯(lián)合體 p 結(jié)構(gòu)體和聯(lián)合體的區(qū)別與聯(lián)系 p 綜合應(yīng)用計算學生成績 p 跟我上機 第17章結(jié)構(gòu)體和聯(lián)合體 結(jié)構(gòu)體 結(jié)構(gòu)體數(shù)組 結(jié)構(gòu)體指針 結(jié)構(gòu)體與函數(shù) 聯(lián)合體 結(jié)構(gòu)體和聯(lián)合體的區(qū)別與聯(lián)系 p 綜合應(yīng)用計算學生成績 p 跟我上機 第17章結(jié)構(gòu)體和聯(lián)合體 結(jié)構(gòu)體 結(jié)構(gòu)體數(shù)組 結(jié)構(gòu)體指針 結(jié)構(gòu)體與函數(shù) 聯(lián)合體 結(jié)構(gòu)體和聯(lián)合體的區(qū)

3、別與聯(lián)系 綜合應(yīng)用計算學生成績 p 跟我上機 第17章結(jié)構(gòu)體和聯(lián)合體 結(jié)構(gòu)體 結(jié)構(gòu)體數(shù)組 結(jié)構(gòu)體指針 結(jié)構(gòu)體與函數(shù) 聯(lián)合體 結(jié)構(gòu)體和聯(lián)合體的區(qū)別與聯(lián)系 綜合應(yīng)用計算學生成績 跟我上機 結(jié)構(gòu)體和聯(lián)合體事物往往是具有多方面的屬性,例如描述一個學生的信息,可能要包括學號、姓名、性別、年齡、成績、班級等方面。對此,C中提供了能夠描述此類數(shù)據(jù)的構(gòu)造數(shù)據(jù)類型,這就是本章要介紹的結(jié)構(gòu)體和聯(lián)合體。17.1 結(jié)構(gòu)體 17.1.1 結(jié)構(gòu)體類型17.1.2 定義結(jié)構(gòu)體變量17.1.3 初始化結(jié)構(gòu)體變量17.1.4 結(jié)構(gòu)體變量的引用17.1 結(jié)構(gòu)體前面學習的字符型、整型、單精度浮點型等基本數(shù)據(jù)類型,都是由C編譯系統(tǒng)事

4、先定義好的,可以直接用來聲明變量;而結(jié)構(gòu)體類型是一種由用戶根據(jù)實際需要自己構(gòu)造的數(shù)據(jù)類型,所以必須要“先定義,后使用”。也就是說,用戶必須首先構(gòu)造一個結(jié)構(gòu)體類型,然后才能使用這個結(jié)構(gòu)體類型來定義變量或數(shù)組。17.1.1 結(jié)構(gòu)體類型結(jié)構(gòu)體類型”是一種構(gòu)造數(shù)據(jù)類型,它由若干“成員”組成,每一個成員可以是相同、部分相同、或完全不同的數(shù)據(jù)類型,對每個特定的結(jié)構(gòu)體都需要根據(jù)實際情況進行結(jié)構(gòu)體類型的定義,也就是構(gòu)造它,以明確該結(jié)構(gòu)體的成員及其所屬數(shù)據(jù)類型。C語言中提供的定義結(jié)構(gòu)體類型的語句格式為:struct 結(jié)構(gòu)體類型名 數(shù)據(jù)類型1 成員名1; 數(shù)據(jù)類型2 成員名2; 數(shù)據(jù)類型n 成員名n;17.1.1

5、 結(jié)構(gòu)體類型其中,struct是C語言中的關(guān)鍵字,表明是在進行一個結(jié)構(gòu)體類型的定義。結(jié)構(gòu)體類型名是一個合法的C語言標識符,對它的命名要盡量做到“見名知義”。比如,描述一個學生的信息可以用 “stu”,描述一本圖書的信息可以使用“bookcard”等。由定義格式可以看出,結(jié)構(gòu)體數(shù)據(jù)類型由若干個數(shù)據(jù)成員組成,每個數(shù)據(jù)成員可以是任意數(shù)據(jù)類型。最后的分號表示結(jié)構(gòu)體類型定義的結(jié)束。例如,定義一個學生成績的結(jié)構(gòu)體數(shù)據(jù)類型如下:struct student char no8;/*學號*/ char name8;/*姓名*/ float eng; /*英語成績*/ float math;/*數(shù)學成績*/ fl

6、oat ave ;/*平均成績 */;在這個結(jié)構(gòu)體中有6個數(shù)據(jù)成員,分別是no、name、eng、math和ave,前2個是字符數(shù)組,分別存放學生的學號和姓名信息;eng、math、ave是單精度實型,分別存放英語、數(shù)學以及平均成績。17.1.1 結(jié)構(gòu)體類型另外,結(jié)構(gòu)體可以嵌套定義,即一個結(jié)構(gòu)體內(nèi)部的成員的數(shù)據(jù)類型可以是另一個已經(jīng)定義過的結(jié)構(gòu)體類型。例如:struct date int year; int month; int day;struct student char name10; char sex/*定義性別,m代表男,f代表女*/; struct date birthday; in

7、t age; float score;在上述代碼段中,先定義了一個結(jié)構(gòu)體類型struct date,然后在定義第二個結(jié)構(gòu)體類型時,其成員birthday被聲明為struct date結(jié)構(gòu)體類型。這就是結(jié)構(gòu)體的嵌套定義。17.1.1 結(jié)構(gòu)體類型關(guān)于結(jié)構(gòu)體說明如下。 結(jié)構(gòu)體的成員名可以與程序中其它定義為基本類型的變量名同名,同一個程序中不同結(jié)構(gòu)體的成員名也可以相同,它們代表的是不同的對象,不會出現(xiàn)沖突。 如果結(jié)構(gòu)體類型的定義在函數(shù)內(nèi)部,則這個類型名的作用域僅為該函數(shù);如果是定義在所有函數(shù)外部,則可以在整個程序中使用。17.1.2 定義結(jié)構(gòu)體變量結(jié)構(gòu)體類型的定義只是由用戶構(gòu)造了一個結(jié)構(gòu)體,但定義結(jié)構(gòu)

8、體類型時系統(tǒng)并不為其分配存儲空間。結(jié)構(gòu)體類型定義好后可以像C中提供的基本數(shù)據(jù)類型一樣使用,即可以用它來定義變量、數(shù)組等,稱為結(jié)構(gòu)體變量或結(jié)構(gòu)體數(shù)組,系統(tǒng)會為該變量或數(shù)組分配相應(yīng)的存儲空間。在C語言中定義結(jié)構(gòu)體類型變量有以下3種方法:17.1.2 定義結(jié)構(gòu)體變量1. 先定義結(jié)構(gòu)體類型后定義變量例如,先定義一個結(jié)構(gòu)體類型: struct student char no8 ;/*學號*/ char name8; /*姓名*/ float eng; /*英語成績*/ float math; /*數(shù)學成績*/ float ave ;/*平均成績 */ ;我們可以用定義好的結(jié)構(gòu)體類型struct stud

9、ent來定義變量,該變量就可以用來存儲一個學生的信息了,定義如下:struct student stu30; /*定義結(jié)構(gòu)體類型的數(shù)組*/這里定義了一個包含30個元素的數(shù)組,每個數(shù)組元素都是一個結(jié)構(gòu)體類型的數(shù)據(jù),可以保存30個學生的信息。struct student stu1;/*定義一個結(jié)構(gòu)體類型的變量*/說明:當一個程序中多個函數(shù)內(nèi)部需要定義同一結(jié)構(gòu)體類型的變量時,應(yīng)采用此方法,而且結(jié)構(gòu)體類型應(yīng)定義為全局類型。17.1.2 定義結(jié)構(gòu)體變量2. 定義結(jié)構(gòu)體類型的同時定義變量語法形式如下:struct 結(jié)構(gòu)體標識符 數(shù)據(jù)類型1 成員名1; 數(shù)據(jù)類型2 成員名2; 數(shù)據(jù)類型n 成員名n; 變量1

10、, 變量2,變量n;其中變量1, 變量2,變量n為變量列表,遵循變量的定義規(guī)則,彼此之間通過逗號分割。說明:在實際的應(yīng)用中,定義結(jié)構(gòu)體同時定義結(jié)構(gòu)體變量適合于定義局部使用的結(jié)構(gòu)體類型或結(jié)構(gòu)體類型變量,例如在一個文件內(nèi)部或函數(shù)內(nèi)部。17.1.2 定義結(jié)構(gòu)體變量3. 直接定義結(jié)構(gòu)體類型變量這種定義方式是不指出具體的結(jié)構(gòu)體類型名,直接定義結(jié)構(gòu)體成員和結(jié)構(gòu)體類型的變量,此方法的語法形式如下:struct 數(shù)據(jù)類型1 成員名1; 數(shù)據(jù)類型2 成員名2; 數(shù)據(jù)類型n 成員名n; 變量1, 變量2,變量n;這種定義的實質(zhì)是先定義一個匿名結(jié)構(gòu)體之后,再定義相應(yīng)的變量。由于此結(jié)構(gòu)體沒有標識符,所以無法采用定義結(jié)

11、構(gòu)體變量的第一種方法來定義變量。17.1.3 初始化結(jié)構(gòu)體變量定義結(jié)構(gòu)體變量的同時就對其成員賦初值的操作就是對結(jié)構(gòu)體變量的初始化。結(jié)構(gòu)體變量的初始化方式與數(shù)組的初始化類似,在定義結(jié)構(gòu)體變量的同時把賦給各個成員的初始值用“ ”括起來,稱為初始值表,其中各個數(shù)據(jù)以逗號分割,具體的形式如下:struct 結(jié)構(gòu)體標識符 數(shù)據(jù)類型1 成員名1; 數(shù)據(jù)類型2 成員名2; 數(shù)據(jù)類型n 成員名n; 變量名=初始化值1,初始化值2,, 初始化值n ;17.1.3 初始化結(jié)構(gòu)體變量struct studentchar name10; /*學生姓名*/ char sex;/*定義性別,m代表男,f代表女*/ int

12、 age; /*學生年齡*/ float score;/*分數(shù)*/ stu30,stu1“zhangsan”,1,20,88.8,stu2;上述代碼,在定義結(jié)構(gòu)體類型struct student的同時定義了結(jié)構(gòu)體數(shù)組和兩個結(jié)構(gòu)體變量,并對變量stu1進行了初始化,變量stu1的4個成員分別得到了一個對應(yīng)的值,即name數(shù)組中初始化了一個學生的姓名“zhangsan”,sex中初始化了一個學生的性別“1”,age中初始化了一個學生的年齡20,score中初始化了學生的成績88.8,這樣,變量stu1中就存放了一個學生的信息。17.1.4 結(jié)構(gòu)體變量的引用結(jié)構(gòu)體變量的引用分為結(jié)構(gòu)體成員變量的引用和

13、將結(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)成員的引用表達式在任何地方出現(xiàn)都是一個整體,如stu1.age,stu1.score等。嵌套的結(jié)構(gòu)體定義中成員的引用也一樣,例如,有以下代碼:17.1.4 結(jié)構(gòu)體變量的引用struct date int year;/*年*/ int month;/*月*/ int day;/*日*/;struct student char name10; char sex

14、; struct date birthday; int age; float score;stu1;其中,結(jié)構(gòu)體變量stu1的成員birthday也是一個結(jié)構(gòu)體類型的變量,這是嵌套的結(jié)構(gòu)體定義。對該成員的引用要用結(jié)構(gòu)體成員運算符進行分級運算,也就是說,對成員變量birthday的引用是這樣的:stu.birthday.year,stu.birthday.month,stu.birthday.day。17.1.4 結(jié)構(gòu)體變量的引用結(jié)構(gòu)體成員變量和普通變量一樣使用,比如,可以對結(jié)構(gòu)體成員變量進行賦值操作,如下列代碼都是合法的。scanf(“%s”,);stu1.sex=1;stu

15、1.age=20; stu.birthday.year=1999;17.1.4 結(jié)構(gòu)體變量的引用2. 對結(jié)構(gòu)體變量本身的引用結(jié)構(gòu)體變量本身的引用是否遵循基本數(shù)據(jù)類型變量的引用規(guī)則呢?我們先來看一下對結(jié)構(gòu)體變量的賦值運算。struct student char name10; char sex; int age; float score;struct student stu1=“zhangsan”,1,20,88.8,stu2;c語言規(guī)定,同類型的結(jié)構(gòu)體變量之間可以進行賦值運算,因此這樣賦值是允許的:stu2=stu1;此時,系統(tǒng)將按成員一一對應(yīng)賦值。也就是說,上述賦值語句執(zhí)行完后,stu2中的

16、4各成員變量分別得到數(shù)值zhangsan”, 1, 20 , 88.8。17.1.4 結(jié)構(gòu)體變量的引用但是,在C語言中規(guī)定,不允許將一個結(jié)構(gòu)體變量作為整體進行輸入或輸出操作。因此以下語句是錯誤的:scanf(“%s,%d,%d,%f”,&stu1);printf(“%s,%d,%d,%f”,stu1); 17.1.4 結(jié)構(gòu)體變量的引用將結(jié)構(gòu)體變量作為操作對象時,還可以進行以下2種運算。 用sizeof運算符計算結(jié)構(gòu)體變量所占內(nèi)存空間。定義結(jié)構(gòu)體變量時,編譯系統(tǒng)會為該變量分配內(nèi)存空間,結(jié)構(gòu)體變量所占內(nèi)存空間的大小等于其各成員所占內(nèi)存空間之和。C中提供了sizeof運算符來計算結(jié)構(gòu)體變量所

17、占內(nèi)存空間的大小,其一般使用形式如下:sizeof(結(jié)構(gòu)體變量名)或sizeof(結(jié)構(gòu)體類型名)17.1.4 結(jié)構(gòu)體變量的引用 用&運算符對結(jié)構(gòu)體變量進行取址運算。前面介紹過對普通變量的取址,例如,&a可以得到變量a的首地址,對結(jié)構(gòu)體變量的取址運算也是一樣的,例如,上面定義了一個結(jié)構(gòu)體變量stu1,那么利用&stu1就可以得到stu1的首地址,后面介紹用結(jié)構(gòu)體指針作函數(shù)的參數(shù)以及使用結(jié)構(gòu)體指針操作結(jié)構(gòu)體變量的成員時,就需要用到對結(jié)構(gòu)體變量的取址運算。17.2 結(jié)構(gòu)體數(shù)組17.2.1 定義結(jié)構(gòu)體數(shù)組17.2.2 初始化結(jié)構(gòu)體數(shù)組17.2.3 結(jié)構(gòu)體數(shù)組元素的引用17.2

18、結(jié)構(gòu)體數(shù)組數(shù)組是一組具有相同數(shù)據(jù)類型變量的有序集合,可以通過下標獲得其中的任意元素。結(jié)構(gòu)體類型數(shù)組與基本類型數(shù)組的定義與引用規(guī)則是相同的,區(qū)別在于結(jié)構(gòu)體數(shù)組中的所有元素均為結(jié)構(gòu)體變量。 17.2.1 定義結(jié)構(gòu)體數(shù)組結(jié)構(gòu)體數(shù)組的定義和結(jié)構(gòu)體變量的定義一樣,有三種方式:1. 先定義結(jié)構(gòu)體類型,再定義結(jié)構(gòu)體數(shù)組struct 結(jié)構(gòu)體標識符 數(shù)據(jù)類型1 成員名1; 數(shù)據(jù)類型2 成員名2; 數(shù)據(jù)類型n 成員名n;;struct 結(jié)構(gòu)體標識符 數(shù)組名數(shù)組長度;17.2.1 定義結(jié)構(gòu)體數(shù)組2. 定義結(jié)構(gòu)體類型的同時,定義結(jié)構(gòu)體數(shù)組:struct 結(jié)構(gòu)體標識符 數(shù)據(jù)類型1 成員名1; 數(shù)據(jù)類型2 成員名2; 數(shù)

19、據(jù)類型n 成員名n; 數(shù)組名數(shù)組長度;17.2.1 定義結(jié)構(gòu)體數(shù)組3. 不給出結(jié)構(gòu)體類型名,直接定義結(jié)構(gòu)體數(shù)組:struct 數(shù)據(jù)類型1 成員名1; 數(shù)據(jù)類型2 成員名2; 數(shù)據(jù)類型n 成員名n; 數(shù)組名數(shù)組長度;其中“數(shù)組名”為數(shù)組名稱,遵循變量的命名規(guī)則;“數(shù)組長度”為數(shù)組的長度,要求為大于零的整型常量。例如:定義長度為10的struct student類型數(shù)組stu10的方法有如下三種形式:17.2.1 定義結(jié)構(gòu)體數(shù)組方式1:struct student char name10; char sex; int age; float score;struct student stu10;方式

20、2:struct student char name10; char sex; int age; float score;stu10;方式3:struct char name10; char sex; int age; float score;stu10;17.2.1 定義結(jié)構(gòu)體數(shù)組結(jié)構(gòu)體數(shù)組定義好后,系統(tǒng)即為其分配相應(yīng)的內(nèi)存空間,數(shù)組中的各元素在內(nèi)存中連續(xù)存放,每個數(shù)組元素都是結(jié)構(gòu)體類型,分配相應(yīng)大小的存儲空間。上例中的stu在內(nèi)存中的存放順序如圖所示。 stu0stu1name10sexagescorename10sexagescore.17.2.2 初始化結(jié)構(gòu)體數(shù)組結(jié)構(gòu)體類型數(shù)組的初始化

21、遵循基本數(shù)據(jù)類型數(shù)組的初始化規(guī)律,在定義數(shù)組的同時,對其中的每一個元素進行初始化。例如:struct student/*定義結(jié)構(gòu)體struct student*/ char Name20;/*姓名*/ float Math;/*數(shù)學*/ float English;/*英語*/ float Physical;/*物理*/stu2=“zhang”,78,89,95,“wang”,87,79,92;在定義結(jié)構(gòu)體類型的同時定義長度為2的結(jié)構(gòu)體數(shù)組stu2,并分別對每個元素進行初始化。17.2.2 初始化結(jié)構(gòu)體數(shù)組說明:在定義數(shù)組并同時進行初始化的情況下,可以省略數(shù)組的長度,系統(tǒng)根據(jù)初始化數(shù)據(jù)的多少來

22、確定數(shù)組的長度。例如:struct key char name20; int count;key1=“break”,0,“case”,0,“void”,0;系統(tǒng)自動確認結(jié)構(gòu)體數(shù)組key1的長度為3。17.2.3 結(jié)構(gòu)體數(shù)組元素的引用前面已經(jīng)介紹過數(shù)組的使用,我們知道,對于數(shù)組元素的引用,其實質(zhì)為簡單變量的引用。對結(jié)構(gòu)體類型的數(shù)組元素的引用也是一樣的,其語法形式如下:數(shù)組名數(shù)組下標;和前面介紹的基本類型的數(shù)組定義一樣,“ ”為下標運算符,數(shù)組下標的取值范圍為(0,1,2,.,n-1),n為數(shù)組長度。對于結(jié)構(gòu)體數(shù)組來說,每一個數(shù)組元素都是一個結(jié)構(gòu)體類型的變量,對結(jié)構(gòu)體數(shù)組元素的引用遵從對結(jié)構(gòu)體變量

23、的引用規(guī)則。17.2.3 結(jié)構(gòu)體數(shù)組元素的引用【范例17-1】 結(jié)構(gòu)體數(shù)據(jù)元素的輸入輸出。要求從鍵盤輸入5名學生的姓名、性別、年齡和分數(shù),輸出其中所有女同學的信息。17.2.3 結(jié)構(gòu)體數(shù)組元素的引用01 #include stdio.h02 void main()03 04 struct student/*定義結(jié)構(gòu)體類型*/05 06 char name10; 07 char sex; /*定義性別,m代表男,f代表女*/08 int age;09 float score;10 stu5;/*定義結(jié)構(gòu)體數(shù)組*/11 int i;12 printf(輸入數(shù)據(jù):姓名 性別 年齡 分數(shù)n);/*提示

24、信息*/13 /*輸入結(jié)構(gòu)體數(shù)組各元素的成員值*/14 for(i=0;i5;i+) 15 scanf(%s %c %d %f,,&stui.sex,&stui.age,&stui.score);16 printf(輸出數(shù)據(jù):姓名 年齡 分數(shù)n);/*提示信息*/17 /*輸出結(jié)構(gòu)體數(shù)組元素的成員值*/18 for(i=0;i”運算符通過指針變量訪問目標變量,如:p-a、p-b。說明:結(jié)構(gòu)體指針在程序中使用很頻繁,為了簡化引用形式,C提供了結(jié)構(gòu)成員運算符“-”,利用它可簡化用指針引用結(jié)構(gòu)成員的形式。并且結(jié)構(gòu)成員運算符“-”和“.”的優(yōu)先級相同,在c中屬

25、于最高級運算符。17.3.3 使用指針訪問成員【范例17-2】 利用結(jié)構(gòu)體指針訪問結(jié)構(gòu)體變量的成員。01 #include stdio.h02 void main()03 04 struct ucode/*聲明結(jié)構(gòu)體類型*/05 06 char u1; 07 int u2; 08 a=c,89,*p=&a;/*聲明結(jié)構(gòu)體類型指針變量p并初始化*/09 printf(%c %dn,(*p).u1,(*p).u2);/*輸出結(jié)構(gòu)體成員變量a的值*/10 17.3.4 指向結(jié)構(gòu)體數(shù)組的指針結(jié)構(gòu)體指針變量的使用,和其他普通變量的指針使用方法和特性都是一樣的。結(jié)構(gòu)體變量指針除了指向結(jié)構(gòu)體變量,還

26、可以用來指向一個結(jié)構(gòu)體數(shù)組,此時,指向結(jié)構(gòu)體數(shù)組的結(jié)構(gòu)體指針變量加1的結(jié)果是指向結(jié)構(gòu)體數(shù)組的下一個元素,那么結(jié)構(gòu)體指針變量的地址值的增量大小是“sizeof(結(jié)構(gòu)體類型)”的字節(jié)數(shù)。例如,有以下代碼:struct ucode char u1; int u2; tt4,*p=tt;這里定義了一個結(jié)構(gòu)體類型的指針p指向結(jié)構(gòu)體數(shù)組tt的首地址,即初始時是指向數(shù)組的第一個元素,那么(*p).u1等價于tt0.u1,(*p)u2等價于tt0.u2。如果對p進行加1運算,則指針變量p指向數(shù)組的第二個元素,即tt1,那么那么(*p).u1等價于tt1.u1,(*p)u2等價于tt1.u2。總之,指向結(jié)構(gòu)體類

27、型數(shù)組的結(jié)構(gòu)體指針變量,使用起來并不復(fù)雜,但要注意區(qū)分以下情況:17.3.4 指向結(jié)構(gòu)體數(shù)組的指針p-u1+/*等價于 (p-u1)+,先取成員u1的值,再使u1自增1*/+p-u1/*等價于+(p-u1),先對成員u1進行自增1,再取u1的值*/(p+)-u1/*等價于先取成員u1的值,用完后再使指針p加1*/(+p) -u1/*等價于先使指針p加1,然后再取成員u1的值*/17.3.4 指向結(jié)構(gòu)體數(shù)組的指針【范例17-3】 指向結(jié)構(gòu)體數(shù)組的指針的應(yīng)用。01 #include stdio.h02 void main()03 04 struct ucode05 06 char u1; 07 i

28、nt u2; 08 tt4=a,97,b,98,c,99,d,100;/*聲明結(jié)構(gòu)體類型的數(shù)組并初始化*/09 struct ucode *p=tt;10 printf(%c %dn,p-u1,p-u2);/*輸出語句*/11 printf(%cn,(p+)-u1);/*輸出語句*/12 printf(%c %dn,p-u1, p-u2+); /*輸出語句*/13 printf(%dn,p-u2);/*輸出語句*/14 printf(%c %dn,(+p)-u1,p-u2);/*輸出語句*/15 p+;/*結(jié)構(gòu)體指針變量增1*/16 printf(%c %dn,+p-u1,p-u2);/*輸出

29、語句*/u17首先,p指向tt0,08行輸出結(jié)果為a 97;09行的輸出項(p+)-u1是先取成員u1的值,再使指針p增1,因此是輸出a,p指向tt1;12行p-u2+與(p-u2)+等價,輸出tt1的成員u2的值,再使u2增1,因此輸出結(jié)果是:b 98,同時u2的值增1后變?yōu)?9;第13行即輸出結(jié)果99;14行(+p)-u1先使p自增1,此時指向tt2,輸出結(jié)果為:c 99;15行p自增1,指向tt3;16行的+p-u1等價于+(p-u1),成員u1的值增加1,因此,輸出結(jié)果為:e 100。17.4 結(jié)構(gòu)體與函數(shù)17.4.1 結(jié)構(gòu)體作為函數(shù)的參數(shù)17.4.2 結(jié)構(gòu)體作為函數(shù)的返回值17.4.

30、1 結(jié)構(gòu)體作為函數(shù)的參數(shù)結(jié)構(gòu)體作為函數(shù)的參數(shù),有以下兩種形式。1在函數(shù)之間直接傳遞結(jié)構(gòu)體類型的數(shù)據(jù)傳值調(diào)用方式由于結(jié)構(gòu)體變量之間可以進行賦值,所以可以把結(jié)構(gòu)體變量作為函數(shù)的參數(shù)使用。具體應(yīng)用中,把函數(shù)的形參定義為結(jié)構(gòu)體變量,函數(shù)調(diào)用時,將主調(diào)函數(shù)的實參傳遞給被調(diào)函數(shù)的形參?!痉独?7-4】 利用結(jié)構(gòu)體變量作函數(shù)的參數(shù)的傳值調(diào)用方式計算三角形的面積。17.4.1 結(jié)構(gòu)體作為函數(shù)的參數(shù)2在函數(shù)之間傳遞結(jié)構(gòu)體指針傳址調(diào)用方式運用指向結(jié)構(gòu)體類型的指針變量作為函數(shù)的參數(shù),將主調(diào)函數(shù)的結(jié)構(gòu)體變量的指針(實參)傳遞給被調(diào)函數(shù)的結(jié)構(gòu)體指針(形參),利用作為形參的結(jié)構(gòu)體指針來操作主調(diào)函數(shù)中的結(jié)構(gòu)體變量及其成員,

31、達到數(shù)據(jù)傳遞的目的。17.4.1 結(jié)構(gòu)體作為函數(shù)的參數(shù)【范例17-5】 利用結(jié)構(gòu)體指針變量作函數(shù)的參數(shù)的傳址調(diào)用方式計算三角形的面積 17.4.2 結(jié)構(gòu)體作為函數(shù)的返回值通常情況下,一個函數(shù)只能有一個返回值。但是如果函數(shù)確實需要帶回多個返回值的話,根據(jù)我們前面的學習,可以利用全局變量或指針來進行解決。而學習了結(jié)構(gòu)體以后,就可以在被調(diào)函數(shù)中利用return語句將一個結(jié)構(gòu)體類型的數(shù)據(jù)結(jié)果返回到主調(diào)函數(shù)中,從而得到多個返回值,將更有利于對這個問題的解決。【范例17-6】 編寫一個程序給出三角形的三邊計算三角形的半周長和面積,要求在自定義函數(shù)中用結(jié)構(gòu)體變量返回多個值。17.5 聯(lián)合體17.5.1 聯(lián)合

32、體類型17.5.2 聯(lián)合體變量的定義17.5.3 聯(lián)合體變量的初始化17.5.4 聯(lián)合體變量的引用17.5.1 聯(lián)合體類型聯(lián)合體也是一種構(gòu)造數(shù)據(jù)類型,和結(jié)構(gòu)體類型一樣,它也是由各種不同類型的數(shù)據(jù)組成,這些數(shù)據(jù)叫做聯(lián)合體的成員。所不同的是,在聯(lián)合體中,C語言編譯系統(tǒng)使用了覆蓋技術(shù),使聯(lián)合體的所有成員在內(nèi)存中具有相同的首地址,共占同一段內(nèi)存空間,這些數(shù)據(jù)可以相互覆蓋,因此聯(lián)合體也常常被稱作是共用體,在不同的時間保存不同的數(shù)據(jù)類型和不同長度的成員的值。也就是說,在某一時刻,只有最新存儲的數(shù)據(jù)是有效的。運用此種類型數(shù)據(jù)的優(yōu)點是節(jié)省存儲空間。聯(lián)合體類型定義的一般形式為: union 聯(lián)合體名 數(shù)據(jù)類型1

33、 成員名1; 數(shù)據(jù)類型2 成員名2; 數(shù)據(jù)類型n 成員名n; ;其中,union是c語言中的關(guān)鍵字,表明是在進行一個聯(lián)合體類型的定義。聯(lián)合體類型名是一個合法的C語言標識符;聯(lián)合體類型成員的數(shù)據(jù)類型可以是C語言中的任何數(shù)據(jù)類型。最后的分號表示聯(lián)合體定義的結(jié)束。例如:17.5.1 聯(lián)合體類型union ucode char u1; int u2; long u3;;這里定義了一個名為union ucode的聯(lián)合體類型,它包括3個成員,分別是字符型、整型和長整型。說明:聯(lián)合體類型的定義只是由用戶構(gòu)造了一個聯(lián)合體,定義好后可以像C中提供的基本數(shù)據(jù)類型一樣使用,即可以用它來定義變量、數(shù)組等,但定義聯(lián)合體

34、類型時系統(tǒng)并不為其分配存儲空間,而是為由該聯(lián)合體類型定義的變量、數(shù)組等分配存儲空間。17.5.2 聯(lián)合體變量的定義在一個程序中,一旦定義了一個聯(lián)合體類型,也就可以用這種數(shù)據(jù)類型定義聯(lián)合體變量。和定義結(jié)構(gòu)體變量一樣,定義聯(lián)合體類型變量有以下3種方法。1. 定義聯(lián)合體類型后定義變量一般形式如下:union 聯(lián)合體名 數(shù)據(jù)類型1 成員名1; 數(shù)據(jù)類型2 成員名2; 數(shù)據(jù)類型n 成員名n; ;union 聯(lián)合體名 變量名1,變量名2變量名n;17.5.2 聯(lián)合體變量的定義2. 定義聯(lián)合體類型的同時定義變量一般形式如下:union 聯(lián)合體名 數(shù)據(jù)類型1 成員名1; 數(shù)據(jù)類型2 成員名2; 數(shù)據(jù)類型n 成

35、員名n; 變量名1,變量名2變量名n;說明:在實際的應(yīng)用中,定義聯(lián)合體同時定義聯(lián)合體變量適合于定義局部使用的聯(lián)合體類型或聯(lián)合體類型變量,例如在一個文件內(nèi)部或函數(shù)內(nèi)部。17.5.2 聯(lián)合體變量的定義3. 直接定義聯(lián)合體類型變量這種定義方式是不指出具體的聯(lián)合體類型名,直接定義聯(lián)合體成員和聯(lián)合體類型的變量,一般形式如下:union 數(shù)據(jù)類型1 成員名1; 數(shù)據(jù)類型2 成員名2; 數(shù)據(jù)類型n 成員名n; 變量名1,變量名2變量名n;其實質(zhì)是定義如下:union 數(shù)據(jù)類型1 成員名1; 數(shù)據(jù)類型2 成員名2; 數(shù)據(jù)類型n 成員名n;定義類型的匿名聯(lián)合體之后,再定義相應(yīng)的變量。由于此聯(lián)合體沒有標識符,所以

36、無法采用定義聯(lián)合體變量的第一種方法來定義變量。 在實際的應(yīng)用中,此方法適合于臨時定義局部使用的聯(lián)合體類型變量。說明如下:17.5.2 聯(lián)合體變量的定義 當一個聯(lián)合體變量被定義后, 編譯程序會自動給變量分配存儲空間,其長度為聯(lián)合體的數(shù)據(jù)成員中所占內(nèi)存空間最大的成員的長度。 聯(lián)合體可以嵌套定義,即一個聯(lián)合體的成員可以是另一個聯(lián)合體類型的變量;另外,聯(lián)合體和結(jié)構(gòu)體也可以相互嵌套。17.5.3 聯(lián)合體變量的初始化定義聯(lián)合體變量的同時對其成員賦初值就是對聯(lián)合體變量的初始化。那么,對聯(lián)合體變量初始化可以和結(jié)構(gòu)體變量一樣在定義時直接對其各個成員進行賦初值嗎?看下面這段程序代碼:union ucode cha

37、r u1; int u2;/*定義聯(lián)合體類型*/union ucode a=a,45;/*定義聯(lián)合體類型的變量a并初始化*/編譯時卻提示錯誤:“too many initializers”,這是為什么呢?因為,和結(jié)構(gòu)體變量的存儲結(jié)構(gòu)不同,聯(lián)合體變量中的成員是共用一個首地址,共占同一段內(nèi)存空間,所以在任意時刻只能存放其中一個成員的值,也就是說,每一瞬時只能有一個成員起作用,所以,在對聯(lián)合體類型的變量定義并初始化時只能是對第一個成員進行賦初值,初值需要用“”括起來。17.5.3 聯(lián)合體變量的初始化【范例17-7】 聯(lián)合體類型的應(yīng)用舉例。01 #include stdio.h02 void main

38、()03 04 union05 06 long u1; 07 char u2;08 a=0 x974161;/*定義聯(lián)合體類型的變量a*/09 printf(%ld %cn,a.u1,a.u2); 10 程序中定義的聯(lián)合體類型包含兩個成員u1和u2,分別是四個字節(jié)的長整型和一個字節(jié)的字符型,編譯系統(tǒng)會按其中占用空間較多的長整型變量給結(jié)構(gòu)體類型的變量a分配4個字節(jié)的存儲空間。賦初值十六進制的974161進行初始化后存儲情況如下:輸出時,a.u1輸出它得到的初始值0 x974161,以十進制長整型輸出9912673;a.u2并沒有得到初值,但由于它和a.u1共用首地址,共用內(nèi)存,所以在輸出時,它取

39、其中低位的一個字節(jié)并把它以字符的形式輸出a。再把上面的程序稍作改動,即把聯(lián)合體中第一個成員u1定義為整型,把u2定義為字符型。0110 00010100 00011001 011117.5.3 聯(lián)合體變量的初始化【范例17-8】 聯(lián)合體類型的應(yīng)用舉例。u01 #include stdio.hu02 void main()u03 u04 union ucodeu05 u06 char u1; u07 long u2; u08 a=0 x974161;u09 printf(%c %ldn,a.u1,a.u2);u10 程序中定義的聯(lián)合體類型包含兩個成員u1和u2,分別是一個字節(jié)的字符型和四個字節(jié)的長整型,編譯系統(tǒng)會按其中占用空間較多的長整型變量給結(jié)構(gòu)體類型的變量a分配4個字節(jié)的存儲空間。賦初值進行初始化后,由于第一個成員是字符型,僅用一個字節(jié),所以對于初值十六進制的974161,只能接受0 x61,其他高位部分被舍去。存儲情況如下:輸出時

溫馨提示

  • 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論