《結(jié)構(gòu)和聯(lián)合》ppt課件_第1頁
《結(jié)構(gòu)和聯(lián)合》ppt課件_第2頁
《結(jié)構(gòu)和聯(lián)合》ppt課件_第3頁
《結(jié)構(gòu)和聯(lián)合》ppt課件_第4頁
《結(jié)構(gòu)和聯(lián)合》ppt課件_第5頁
已閱讀5頁,還剩42頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、第8章 構(gòu)造和結(jié)合8.1 構(gòu)造的定義以及構(gòu)造變量的定義和運(yùn)用8.2 構(gòu)造數(shù)組與構(gòu)造指針8.3 構(gòu)造在函數(shù)間的傳送8.8 綜合舉例8.1 構(gòu)造的定義以及構(gòu)造變量的定義和運(yùn)用 8.1.1 8.1.1 構(gòu)造的定義構(gòu)造的定義 構(gòu)造是由不同數(shù)據(jù)類型的數(shù)據(jù)組成的。組成構(gòu)造的構(gòu)造是由不同數(shù)據(jù)類型的數(shù)據(jù)組成的。組成構(gòu)造的每個(gè)數(shù)據(jù)稱為該結(jié)每個(gè)數(shù)據(jù)稱為該結(jié)構(gòu)的成員項(xiàng),簡稱成員。在程序中運(yùn)用構(gòu)造時(shí),首先要對(duì)構(gòu)構(gòu)的成員項(xiàng),簡稱成員。在程序中運(yùn)用構(gòu)造時(shí),首先要對(duì)構(gòu)造的組成進(jìn)造的組成進(jìn)行描畫,這稱為構(gòu)造的定義。構(gòu)造定義的普通方式如下:行描畫,這稱為構(gòu)造的定義。構(gòu)造定義的普通方式如下: s t r u c t s t r

2、u c t 構(gòu)造名構(gòu)造名 數(shù)據(jù)類型數(shù)據(jù)類型 成員名成員名1 1; 數(shù)據(jù)類型數(shù)據(jù)類型 成員名成員名2 2; . 數(shù)據(jù)類型數(shù)據(jù)類型 成員名成員名n n; ;例如,為了處置雇員的數(shù)據(jù),在程序中可以定義如下的構(gòu)造:struct Employee char name20; char sex; int old; int wage;該構(gòu)造名字是Employee,它由四個(gè)成員項(xiàng)組成。第一個(gè)成員項(xiàng)是字符型數(shù)據(jù)name ,它用于保管姓名字符串;第二個(gè)成員項(xiàng)是字符型數(shù)據(jù)sex,它用于保管性別字符;第三個(gè)成員項(xiàng)是int型整數(shù)old,它用于保管年齡數(shù)據(jù);最后一個(gè)成員項(xiàng)是int型整數(shù)wage,它用于工資數(shù)據(jù)。(1) 構(gòu)造

3、的定義以關(guān)鍵字struct作為標(biāo)識(shí)符,其后是定義的構(gòu)造名,它們兩者構(gòu)成了特定構(gòu)造的類型標(biāo)識(shí)符。構(gòu)造名由用戶命名,命名原那么與變量名等一樣。構(gòu)造名是這一組數(shù)據(jù)集合體的名字,可以像根本數(shù)據(jù)類型名一樣,用來闡明詳細(xì)的構(gòu)造變量。(2) 在構(gòu)造名下面的一對(duì)大括號(hào)中包圍的是組成該構(gòu)造的各個(gè)成員項(xiàng)。每個(gè)成員項(xiàng)由其數(shù)據(jù)類型和成員名組成。每個(gè)成員項(xiàng)后用分號(hào)“;作為終了符。整個(gè)構(gòu)造的定義也用分號(hào)作為終了符,留意不要忘記這個(gè)分號(hào)。(3)構(gòu)造的定義明確地描畫了該構(gòu)造的組織方式。在程序執(zhí)行時(shí),構(gòu)造的定義并不引起系統(tǒng)為該構(gòu)造分配內(nèi)存空間。構(gòu)造的定義僅僅是定義了一種特定的數(shù)據(jù)構(gòu)造類型,它指定了這種構(gòu)造運(yùn)用內(nèi)存的方式。在定義

4、時(shí)沒有指明運(yùn)用這種構(gòu)造詳細(xì)對(duì)象在構(gòu)造的闡明時(shí)將指明這點(diǎn)。如上述構(gòu)造Employee的定義,僅僅指定了在運(yùn)用這種構(gòu)造時(shí)應(yīng)該按以下圖所示的配置情況占用內(nèi)存,但這時(shí)并沒有實(shí)踐占用內(nèi)存空間。 name20 sex old wage 20字節(jié) 1字節(jié) 2字節(jié) 2字節(jié) struct employee . . . . . 圖 構(gòu)造變量的定義構(gòu)造變量的定義 程序一旦定義了一個(gè)構(gòu)造體,就相當(dāng)于定義了一個(gè)新的程序一旦定義了一個(gè)構(gòu)造體,就相當(dāng)于定義了一個(gè)新的構(gòu)造類型,那么就可以把構(gòu)造名當(dāng)作像構(gòu)造類型,那么就可以把構(gòu)造名當(dāng)作像int、double等關(guān)鍵等關(guān)鍵字一樣運(yùn)用,用闡明語句定義該方式構(gòu)造體的詳

5、細(xì)構(gòu)造變字一樣運(yùn)用,用闡明語句定義該方式構(gòu)造體的詳細(xì)構(gòu)造變量,其格式為:量,其格式為: struct 構(gòu)造名構(gòu)造名 構(gòu)造變量名;構(gòu)造變量名; 構(gòu)造變量的定義在程序的數(shù)聽闡明部分給出。例如,下構(gòu)造變量的定義在程序的數(shù)聽闡明部分給出。例如,下列闡明:列闡明: struct Employee wang;這個(gè)闡明指出了構(gòu)造變量這個(gè)闡明指出了構(gòu)造變量wang運(yùn)用運(yùn)用Employee構(gòu)造,也就是構(gòu)造,也就是說,構(gòu)造變量說,構(gòu)造變量wang是由前述的是由前述的Employee的四個(gè)成員項(xiàng)組成,的四個(gè)成員項(xiàng)組成,每個(gè)成員項(xiàng)的類型和名字都與每個(gè)成員項(xiàng)的類型和名字都與Employee構(gòu)造定義中給出的構(gòu)造定義中給出

6、的一樣。一樣。(1) 構(gòu)造變量的定義將引起系統(tǒng)按照構(gòu)造定義時(shí)制定的內(nèi)存方式,為被定義的構(gòu)造變量分配一定的內(nèi)存空間。例如,上述構(gòu)造變量wang在內(nèi)存中將占據(jù)與圖8.1所示配置一樣的內(nèi)存空間。 當(dāng)多個(gè)構(gòu)造變量運(yùn)用構(gòu)造時(shí),它們可以在一同定義。例如:struct Employee wang, li,zhang;被定義的三個(gè)構(gòu)造變量wang、li和zhang都具有Employee定義的構(gòu)造。 (2)構(gòu)造變量運(yùn)用內(nèi)存空間,所以它們也具有一定的存儲(chǔ)類型。構(gòu)造變量的存儲(chǔ)類型概念、它的壽命、可見性及運(yùn)用范圍與普通變量、數(shù)組完全一致。(3) 在程序中,構(gòu)造變量的定義在該構(gòu)造的定義之后,對(duì)于尚未定義的構(gòu)造,不能用它

7、對(duì)任何構(gòu)造進(jìn)行闡明。(4)在一些簡單的程序設(shè)計(jì)中,構(gòu)造的定義和構(gòu)造變量的定義也可以同時(shí)進(jìn)展,在這種情況下,有時(shí)省略構(gòu)造名。這時(shí),被定義的構(gòu)造變量直接在構(gòu)造定義的大括號(hào)后給出,例如:struct Employee char name20; char sex; int old; int wage;wang ,song ,zhou;這種方式與前面給出的構(gòu)造定義和構(gòu)造闡明分開進(jìn)展時(shí)功能一樣。 (5)一個(gè)構(gòu)造變量占用內(nèi)存的實(shí)踐大小,可以利用sizeof運(yùn)算求出。sizeof運(yùn)算的功能是計(jì)算出給定的運(yùn)算量占用內(nèi)存空間的字節(jié)數(shù),它的運(yùn)算表達(dá)式普通方式如下: sizeof(運(yùn)算量)其中運(yùn)算量可以是變量、數(shù)組或

8、構(gòu)造變量,也可以是數(shù)據(jù)類型的稱號(hào),如int、double、struct Employee 等。8.1.3 構(gòu)造變量的運(yùn)用方式和初始化構(gòu)造變量的運(yùn)用方式和初始化 C提供了兩種類型的聚合數(shù)據(jù)類型:數(shù)組和構(gòu)造。提供了兩種類型的聚合數(shù)據(jù)類型:數(shù)組和構(gòu)造。數(shù)組數(shù)組是一樣類型的元素的集合,它的每個(gè)元素是經(jīng)過下是一樣類型的元素的集合,它的每個(gè)元素是經(jīng)過下標(biāo)援用或標(biāo)援用或指針間接訪問選擇的。但在構(gòu)造中情況并非如此,指針間接訪問選擇的。但在構(gòu)造中情況并非如此,由于構(gòu)造由于構(gòu)造的成員能夠長度不同,所以不能運(yùn)用下標(biāo)來訪問它的成員能夠長度不同,所以不能運(yùn)用下標(biāo)來訪問它們。相們。相反,每個(gè)構(gòu)呵斥員都有本人的名字,它們是

9、經(jīng)過名反,每個(gè)構(gòu)呵斥員都有本人的名字,它們是經(jīng)過名字來訪問字來訪問的。此外,在構(gòu)造闡明的同時(shí)可以給各個(gè)成員項(xiàng)賦的。此外,在構(gòu)造闡明的同時(shí)可以給各個(gè)成員項(xiàng)賦初值,即初值,即構(gòu)造的初始化。構(gòu)造的初始化。1、構(gòu)造的運(yùn)用方式 構(gòu)造是不同數(shù)據(jù)類型的假設(shè)干數(shù)據(jù)的集合體。在程序中使用構(gòu)造時(shí),普通情況下不能把構(gòu)造作為一整體參與數(shù)據(jù)處理,而參與各種運(yùn)算和操作的是構(gòu)造的各個(gè)成員項(xiàng)數(shù)據(jù)。結(jié)構(gòu)的成員項(xiàng)用以下普通方式表示: 構(gòu)造變量名.成員名 例如,上節(jié)給出的構(gòu)造變量wang具有以下四個(gè)成員項(xiàng): ,wang.sex,wang.old, wang.wage 它們分別表示構(gòu)造變量wang的四個(gè)組成數(shù)據(jù)。

10、在指明構(gòu)呵斥員項(xiàng)時(shí)運(yùn)用的“.符號(hào)是C言語的一個(gè)運(yùn)算符,它規(guī)定的運(yùn)算是訪問構(gòu)造的成員。例如,wang.old本質(zhì)上是一個(gè)運(yùn)算表達(dá)式,它的運(yùn)算是訪問構(gòu)造wang的成員old。因此,它代表了構(gòu)造變量wang中名字為old的成員項(xiàng)。訪問成員運(yùn)算“.是第一運(yùn)算優(yōu)先級(jí)中的一種運(yùn)算,它的結(jié)合規(guī)律是從左向右。明確這一點(diǎn),對(duì)于分析包括有訪問成員運(yùn)算的復(fù)雜運(yùn)算表達(dá)式中各種運(yùn)算的先后順序有很大協(xié)助。 當(dāng)構(gòu)造的成員項(xiàng)是指針變量時(shí),要留意它的運(yùn)用方式上的特點(diǎn)。例如:struct Employee1 char *name; char sex; int old; int wage; zhou; 定義的Employee1構(gòu)造

11、中的成員項(xiàng)name是一個(gè)char型指針。假設(shè)構(gòu)造變量zhou被闡明為Employee1構(gòu)造,那么zhou的成員項(xiàng) 是一個(gè)char型指針。那么下面的運(yùn)用方式 * 表示是該指針指向的目的變量,它的意義可以從運(yùn)算表達(dá)式的角度進(jìn)分析。上述表達(dá)式中有兩種運(yùn)算:*訪問目的和訪問成員。運(yùn)算優(yōu)先于*運(yùn)算。所以,訪問成員運(yùn)算在先,而訪問目的運(yùn)算在后。上面的表達(dá)式等價(jià)于: *()例例8.1 構(gòu)造在程序中的運(yùn)用方式構(gòu)造在程序中的運(yùn)用方式#include struct Employee /構(gòu)造的定義構(gòu)造的定義 char *name; char sex; int o

12、ld; char *; char *adr;void main() struct Employee wang,gao; /構(gòu)造變量的定構(gòu)造變量的定 / 義義 =“wang hai; /構(gòu)造變量的構(gòu)造變量的成成 /員賦值員賦值 wang.sex=M; wang.old=34; wang. wang.adr=beijing; =gao yang; gao.sex=F; gao.old=42; gao. gao.adr=shanghai; /顯示構(gòu)造變量的成員內(nèi)容 printf( name sex old ad

13、dressn ); printf( n); printf(%-14s%-4c%-4d%-10s%- 20sn,,wang.sex,wang.old, wang.,wang.adr); printf(%-14s%-4c%-4d%-10s%- 20sn,,gao.sex,gao.old, gao.,gao.adr); 運(yùn)轉(zhuǎn)結(jié)果如下: name sex old adrwang hai m 34beijinggao yang f 42shanghai 在文件的開場部分定義構(gòu)造Employee,在函數(shù)main的闡明

14、部分闡明了運(yùn)用該構(gòu)造的兩個(gè)構(gòu)造變量wang和gao。程序的執(zhí)行部分由數(shù)據(jù)賦值和輸出兩大部分組成。在賦值部分中可以清楚地看到每個(gè)成員項(xiàng)的運(yùn)用形式和運(yùn)用特性。例如,其中的賦值語句: =wang jun; 由于是一個(gè)char型指針變量,所以可以用一個(gè)字符串常量直接向它賦值。再者,從數(shù)據(jù)輸出中看出,輸出項(xiàng)對(duì)應(yīng)輸出轉(zhuǎn)換闡明符是%s,所以輸出結(jié)果是指針?biāo)赶虻淖址S纱丝芍?,?gòu)造的成員項(xiàng)無論其表示方式多么復(fù)雜,它的類型和運(yùn)用特性最終落實(shí)到成員名上。例如,成員名name在Employee構(gòu)造定義時(shí)定義為char指針型,那么無論是wan

15、、還是都是char指針型。它們?cè)诔绦蛑羞\(yùn)用時(shí),與運(yùn)用一個(gè)普通的字符指針完全一樣,視作一個(gè)整體。2、構(gòu)造的初始化 在構(gòu)造闡明的同時(shí),可以給這個(gè)構(gòu)造的每個(gè)成員賦初值,這稱為構(gòu)造的初始化。構(gòu)造初始化的普通方式如下: struct 構(gòu)造名 構(gòu)造變量=初始數(shù)據(jù);其中大括號(hào)中包圍的初始數(shù)據(jù)之間用逗號(hào)分隔,初始數(shù)據(jù)的個(gè)數(shù)與構(gòu)呵斥員項(xiàng)的個(gè)數(shù)應(yīng)該一樣,它們是按先后順序一一對(duì)應(yīng)賦值。此外,每個(gè)初始數(shù)據(jù)必需符合與其對(duì)應(yīng)的成員項(xiàng)的數(shù)據(jù)類型。例如,前述Employee構(gòu)造的構(gòu)造變量wang在闡明時(shí)可以初始化如下:struct Employee wang=wang hai,M,34,123-1

16、111,beijing;它所實(shí)現(xiàn)的功能,與程序中以下賦值一樣:=wang hai;wang.sex=M;wang.old=34;wang.wang.adr=beijing;8.2 構(gòu)造數(shù)組與構(gòu)造指針8.2.1 構(gòu)造數(shù)組構(gòu)造數(shù)組 在在C言語中,具有一樣數(shù)據(jù)類型的數(shù)據(jù)言語中,具有一樣數(shù)據(jù)類型的數(shù)據(jù)可以組成數(shù)組,可以組成數(shù)組,指向一樣類型的指針可以組成指針數(shù)組。根指向一樣類型的指針可以組成指針數(shù)組。根據(jù)同樣的原那么,據(jù)同樣的原那么,具有一樣構(gòu)造的構(gòu)造也可以組成數(shù)組,稱它具有一樣構(gòu)造的構(gòu)造也可以組成數(shù)組,稱它們?yōu)闃?gòu)造數(shù)組。們?yōu)闃?gòu)造數(shù)組。構(gòu)造數(shù)組的每一個(gè)元素

17、都是構(gòu)造變量。構(gòu)造數(shù)組的每一個(gè)元素都是構(gòu)造變量。 構(gòu)造數(shù)組的闡明方式如下:構(gòu)造數(shù)組的闡明方式如下: struct 構(gòu)造名構(gòu)造名 構(gòu)造數(shù)組名構(gòu)造數(shù)組名元素個(gè)數(shù)元素個(gè)數(shù) = 初值表初值表 ;例如,struct Employee man3; 闡明了構(gòu)造數(shù)組man ,它有三個(gè)元素man0、man1和man2,它們都是具有Employee構(gòu)造的構(gòu)造變量。 構(gòu)造數(shù)組適宜于處置由假設(shè)干具有一樣關(guān)系的數(shù)據(jù)組成的數(shù)據(jù)集合體。與數(shù)組一樣,在定義構(gòu)造數(shù)組的同時(shí)可以用初始化列表給它的每個(gè)元素賦初值。 在對(duì)構(gòu)造數(shù)組進(jìn)展初始化時(shí),方括號(hào) 中的元素個(gè)數(shù)可以缺省。 構(gòu)造數(shù)組也具有數(shù)組的屬性,構(gòu)造數(shù)組名是構(gòu)造數(shù)組存儲(chǔ)首地址,如

18、例中的man表示該構(gòu)造數(shù)組存儲(chǔ)首地址。例8.2 構(gòu)造數(shù)組的運(yùn)用#include #define STUDENT 3 /*用符號(hào)常量STUDENT表示學(xué)生人數(shù) struct Data /定義一個(gè)構(gòu)造 char name20; / 姓名 short age; / 年齡 char adr30; / 地址 long ; / 號(hào)碼 ;void main( ) struct Data manSTUDENT = /*定義一個(gè)構(gòu)造數(shù)組并初始化 王偉, 20, 東八舍416室, 87543641, 李玲, 21, 南三舍219室, 87543945, 張利, 19, 東八舍419室, 87543645; int

19、 i; / 輸出顯示表頭提示信息 printf(“編號(hào)t姓名t年齡t地 址t電 話nn); /輸出構(gòu)造數(shù)組的數(shù)據(jù) for(i = 0; i STUDENT; i+) printf(% -dt%-st%-dt%-st%Ldn, i + 1, , mani.age, mani.adr, mani.); / 每個(gè)輸出項(xiàng)都左對(duì)齊,編號(hào)從1開場 printf(n構(gòu)造類型Data的數(shù)據(jù)長度 : %d 字節(jié)。n, sizeof(struct Data);該程序的輸出結(jié)果為:編號(hào) 姓名 年齡 地 址 電 話1 王偉 20 東八舍416室 875436412 李玲 21 南三舍219室 875

20、439453 張利 19 東八舍419室 87543645構(gòu)造類型Data的數(shù)據(jù)長度 : 56字節(jié)。例8.3:選舉,對(duì)候選人得票進(jìn)展統(tǒng)計(jì),設(shè)有4個(gè)候選人,N個(gè)人參與選舉,每次輸入一個(gè)得票的候選人的名字,要求最后輸出個(gè)人的得票結(jié)果。程序如下:#include #include #define N 10 /宏定義,定義參與選舉人的個(gè)數(shù)struct person /構(gòu)造定義 char name20; int count;void main() /構(gòu)造數(shù)組定義及初始化 struct person leader4=wang,0,zhang,0,zhou,0, gao,0; char name20,i,j

21、; /模擬選舉過程,循環(huán)一次代表一次選舉 for(i=0;iN;i+) gets(name); /從鍵盤輸入候選人的名字 for(j=0;j4;j+) /在候選人中查找匹配的人 if(strcmp(name,)=0) leaderj.count+; /被投票的候選人的票數(shù)加1 break; printf(n); for(j=0;j4;j+) /輸出選舉結(jié)果 printf(%s:%dn,,leaderj.count); 該程序的運(yùn)轉(zhuǎn)結(jié)果為:wangwangzhangzhangzhangzhangzhouzhougaogao /輸入wang:2zha

22、ng:4zhou:2gao:2 /輸出8.2.2 構(gòu)造指針構(gòu)造指針 在在C言語中對(duì)于構(gòu)造的數(shù)據(jù)可以運(yùn)用指針言語中對(duì)于構(gòu)造的數(shù)據(jù)可以運(yùn)用指針進(jìn)展處置。我進(jìn)展處置。我們把指向構(gòu)造的指針稱為構(gòu)造指針。們把指向構(gòu)造的指針稱為構(gòu)造指針。 指向構(gòu)造的指針變量稱為構(gòu)造指針,它指向構(gòu)造的指針變量稱為構(gòu)造指針,它與其他各類指針與其他各類指針在特性和運(yùn)用方法上完全一樣。構(gòu)造指針的在特性和運(yùn)用方法上完全一樣。構(gòu)造指針的運(yùn)算仍按地址計(jì)運(yùn)算仍按地址計(jì)算規(guī)那么進(jìn)展,其定義格式為:算規(guī)那么進(jìn)展,其定義格式為: struct 構(gòu)造名構(gòu)造名 * 構(gòu)造指針名構(gòu)造指針名 = 初始地址值初始地址值 ; 其中構(gòu)造名必需是曾經(jīng)定義過的構(gòu)

23、造類型。其中構(gòu)造名必需是曾經(jīng)定義過的構(gòu)造類型。例如:例如: struct Employee * pman; struct Employee * pd; 存儲(chǔ)類型是構(gòu)造指針變量本身的存儲(chǔ)類型。編譯系統(tǒng)按指定的存儲(chǔ)類型為構(gòu)造指針pman和pd分配內(nèi)存空間。 由于構(gòu)造指針是指向整個(gè)構(gòu)造體而不是某個(gè)成員,因此構(gòu)造指針的增減量運(yùn)算,例如: “pman+;將跳過一個(gè)構(gòu)造變量的整體,指向內(nèi)存中下一個(gè)結(jié)構(gòu)變量或構(gòu)造數(shù)組中下一個(gè)元素,構(gòu)造指針本身的物理地址增量值取決于它所指的構(gòu)造變量或構(gòu)造類型的數(shù)據(jù)長度。 構(gòu)造體可以嵌套,即構(gòu)造體成員又是一個(gè)構(gòu)造變量或結(jié)構(gòu)指針。例如:struct student char na

24、me20; short age; char adr30; struct Date BirthDay; struct Date StudyDate; studt300;其中成員項(xiàng)BirthDay、StudyDate是具有Date構(gòu)造類型的結(jié)構(gòu)變量,稱student為外層構(gòu)造體,Date為內(nèi)層構(gòu)造體。 在構(gòu)造嵌套中,當(dāng)構(gòu)造體的成員項(xiàng)具有與該構(gòu)造體一樣構(gòu)造類型的構(gòu)造變量或構(gòu)造指針時(shí),就構(gòu)成了構(gòu)造體的自我嵌套。這種構(gòu)造體稱為遞歸構(gòu)造體。例如:struct Node int num; / 數(shù)據(jù)場,節(jié)點(diǎn)序號(hào) struct Node * next; / 指針場,指向下一個(gè)節(jié)點(diǎn)的構(gòu)造指針 ;該構(gòu)造體中的成員項(xiàng)

25、next是指向本身構(gòu)造類型Node的構(gòu)造指針,構(gòu)成了遞歸構(gòu)造體,鏈表、樹和有向圖等數(shù)據(jù)構(gòu)造中廣泛采用遞歸構(gòu)造體。 運(yùn)用構(gòu)造指針對(duì)構(gòu)呵斥員進(jìn)展援用時(shí),有兩種方式:(1)運(yùn)用運(yùn)算符“.,這時(shí)指針指向構(gòu)造的成員項(xiàng)普通表示形式是: (*構(gòu)造指針名).成員名 由于成員選擇運(yùn)算符.的優(yōu)先級(jí)比取內(nèi)容運(yùn)算符*“高,所以需求運(yùn)用圓括號(hào)。 在C言語程序中構(gòu)造指針運(yùn)用相當(dāng)頻繁,所以C中提供了一種直觀的特殊運(yùn)算符:構(gòu)造指針運(yùn)算符“-橫線加大于號(hào)。在C言語程序中經(jīng)常采用下面的方式。(2)運(yùn)用運(yùn)算符-“ 構(gòu)造指針名-成員名 它與前一種表示方法在意義上是完全等價(jià)的。例如,前面給出的pman指向的構(gòu)造中的成員項(xiàng)old可以表示

26、如下: pman-old在這種表示方法中,-減號(hào)和大于號(hào)也是一種運(yùn)算符,它在第一運(yùn)算優(yōu)先級(jí)中。它表示的運(yùn)算意義是,訪問指針指向的構(gòu)造中的成員項(xiàng)。例例8.48.4:構(gòu)造指針的運(yùn)用:構(gòu)造指針的運(yùn)用#include #include struct Date /struct Date /定義一個(gè)構(gòu)造定義一個(gè)構(gòu)造 int month; int month; int day; int day; int year; int year;void main()void main() struct Date today, struct Date today,* *date_p; /date_p; /定義一個(gè)構(gòu)造變

27、量和構(gòu)造指針變量定義一個(gè)構(gòu)造變量和構(gòu)造指針變量 date_p =&today; /date_p =&today; /將構(gòu)造指針指向一個(gè)構(gòu)造變量將構(gòu)造指針指向一個(gè)構(gòu)造變量 date_p-month =4; /date_p-month =4; /采用構(gòu)造指針給目的變量賦值采用構(gòu)造指針給目的變量賦值 date_p-day =15;date_p-day =15; date_p-year =1990; date_p-year =1990; / /采用構(gòu)造指針輸出目的變量的數(shù)據(jù)采用構(gòu)造指針輸出目的變量的數(shù)據(jù) printf(Today is %d/%d/%dn, date_p-month,d

28、ate_p-day , date_p-year );printf(Today is %d/%d/%dn, date_p-month,date_p-day , date_p-year ); 程序運(yùn)轉(zhuǎn)結(jié)果:程序運(yùn)轉(zhuǎn)結(jié)果:Today is 4/15/1990Today is 4/15/1990例例8.5:構(gòu)造指針運(yùn)算:構(gòu)造指針運(yùn)算#include struct Key /定義一個(gè)構(gòu)造定義一個(gè)構(gòu)造char *keyword;int keyno;void main() /定義一個(gè)構(gòu)造數(shù)組定義一個(gè)構(gòu)造數(shù)組 struct Key kd=are,123,my,456,you,789; struct Key *

29、p; /定義一個(gè)構(gòu)造指針變量定義一個(gè)構(gòu)造指針變量 int a; char chr; p=kd; /將構(gòu)造數(shù)組的首地址賦給構(gòu)造指針將構(gòu)造數(shù)組的首地址賦給構(gòu)造指針p a=p-keyno; printf(p=%d,a=%dn,p,a); a=+p-keyno; / 相當(dāng)于相當(dāng)于chr=+(p-keyno), /構(gòu)造指針無變化構(gòu)造指針無變化 printf(p=%d,a=%dn,p,a); /構(gòu)造指針指向構(gòu)造數(shù)組的下一個(gè)元素,構(gòu)造指針發(fā)生變構(gòu)造指針指向構(gòu)造數(shù)組的下一個(gè)元素,構(gòu)造指針發(fā)生變 /化;給化;給a賦值是指針變化后所指向目的的成員數(shù)據(jù)賦值是指針變化后所指向目的的成員數(shù)據(jù) a=(+p)-keyno;

30、 printf(p=%d,a=%dn,p,a); /給給a賦值是指針變化前所指向目的的成員數(shù)據(jù);構(gòu)造指賦值是指針變化前所指向目的的成員數(shù)據(jù);構(gòu)造指 /針值發(fā)生變化,構(gòu)造指針指向構(gòu)造數(shù)組的下一個(gè)元素針值發(fā)生變化,構(gòu)造指針指向構(gòu)造數(shù)組的下一個(gè)元素 a=(p+)-keyno; printf(p=%d,a=%dn,p,a); p=kd; /重新將構(gòu)造數(shù)組的首地址賦給構(gòu)造指針p chr=*p-keyword;/相當(dāng)于chr=*(p-keyword) printf(p=%d,chr=%c(adr=%d)n,p,chr,p-keyword); /相當(dāng)于chr=*(p-keyword)+,賦值之后,keywo

31、rd指針發(fā) /生變化 chr=*p-keyword+; printf(p=%d,chr=%c(adr=%d)n,p,chr,p-keyword); /相當(dāng)于chr=*(p-keyword)+,給chr賦值的是 /*(p-keyword),所以/r(前面keyword指針指向r); /賦值之后*(p-keyword)進(jìn)展加1變?yōu)閟 chr=(*p-keyword)+; printf(p=%d,chr=%c(adr=%d)n,p,chr,p-keyword); /給chr賦值是指針變化前所指向目的的成員數(shù)據(jù),chr=s; /構(gòu)造指針值發(fā)生變化,構(gòu)造指針指向構(gòu)造數(shù)組的下一個(gè) /元素, chr=*p+

32、-keyword; printf(p=%d,chr=%c(adr=%d)n,p,chr,p-keyword); /相當(dāng)于chr=*(+(p-keyword),構(gòu)造指針值無變化,將 /my中的y賦給chr chr=*+p-keyword; printf(p=%d,chr=%c(adr=%d)n,p,chr,p-keyword);程序運(yùn)轉(zhuǎn)結(jié)果:p=158,a=123p=158,a=124p=162,a=456p=166,a=456p=158,chr=a(adr=170)p=158,chr=a(adr=171)p=158,chr=r(adr=171)p=162,chr=s(adr=174)p=162

33、,chr=y(adr=175)留意輸出結(jié)果值中地址值每次運(yùn)轉(zhuǎn)時(shí)能夠有所不同,但地址的相對(duì)值不變。例例8.68.6:指向構(gòu)造數(shù)組的指針的運(yùn):指向構(gòu)造數(shù)組的指針的運(yùn)用用#include #include struct student /struct student /定義定義一個(gè)構(gòu)造一個(gè)構(gòu)造 int No; int No; char name20; char name20; char sex; char sex; int age; int age;void main()void main() / /定義一個(gè)構(gòu)造數(shù)組并初始化定義一個(gè)構(gòu)造數(shù)組并初始化 struct student stu3= stru

34、ct student stu3= 10101,Li 10101,Li Lin,Lin,M M,18,18, 10102,Zhang 10102,Zhang fan,fan,M M,19,19, 10104,Wang 10104,Wang Min,Min,F F,20;,20; /定義一個(gè)構(gòu)造指針變量 struct student *p; printf(No. Name Sex Agen); for( p=stu ; pNo,p-name,p-sex,p-age);程序運(yùn)轉(zhuǎn)結(jié)果:No. Name Sex Age10101 Li Lin M 1810102 Zhang fan M 1910104

35、Wang Min F 208.3 構(gòu)造在函數(shù)間的傳送 將一個(gè)構(gòu)造體變量的值傳送給另一個(gè)函數(shù),有3種方法:(1)用構(gòu)造體變量的成員作參數(shù),用法和用普通變量作實(shí)參是一樣的,屬于“值傳送方式。該當(dāng)留意實(shí)參和形參的類型堅(jiān)持一致。由于構(gòu)造是不同數(shù)據(jù)類型的數(shù)據(jù)的集合體,采用這種方法,無適用價(jià)值,實(shí)踐運(yùn)用時(shí),較少采用。(2)用構(gòu)造體變量作實(shí)參。ANSI C支持在調(diào)用函數(shù)時(shí),把構(gòu)造作為參數(shù)傳遞給函數(shù),采取的是“值傳送的方式,將構(gòu)造體變量所占的內(nèi)存單元的內(nèi)容全部順序傳送給形參。形參也必需是同類型的構(gòu)造體變量。在函數(shù)調(diào)用期間,形參也要占用內(nèi)存單元。(3)用構(gòu)造變量的地址或構(gòu)造數(shù)組的首地址作為實(shí)參,用指向一樣構(gòu)造類

36、型的構(gòu)造指針作為函數(shù)的形參來接受該地址值。用構(gòu)造指針作為函數(shù)的形參與用指針變量作為形參在函數(shù)間傳送一樣,即采用地址傳送方式,把構(gòu)造變量的存儲(chǔ)首地址或構(gòu)造數(shù)組名作為實(shí)參向函數(shù)傳送,函數(shù)的形參是指向一樣構(gòu)造類型的指針接納該地址值。例例8.7, 8.7, 采用值傳送在函數(shù)間傳送構(gòu)造變量,計(jì)算雇傭天數(shù)和采用值傳送在函數(shù)間傳送構(gòu)造變量,計(jì)算雇傭天數(shù)和工資。工資。#include #include struct Date struct Date int day; int day; int month; int month; int year; int year; int yearday; int year

37、day; char mon_name4; char mon_name4;int day_of_year(struct Date pd);int day_of_year(struct Date pd);void main( )void main( ) struct Date HireDate; struct Date HireDate; float laborage; / float laborage; / 存放每天的雇傭工資存放每天的雇傭工資 printf(printf(請(qǐng)輸入每天的工資請(qǐng)輸入每天的工資 : );: ); scanf(%f, & laborage); scanf(%f,

38、 & laborage); printf( printf(請(qǐng)輸入年份請(qǐng)輸入年份 : );: ); scanf(%d, & HireDate.year); scanf(%d, & HireDate.year); printf( printf(請(qǐng)輸入月份請(qǐng)輸入月份 : );: ); scanf(%d, & HireDate.month); scanf(%d, & HireDate.month); printf( printf(請(qǐng)輸入日請(qǐng)輸入日 : );: ); scanf(%d, & HireDate.day); scanf(%d, & Hi

39、reDate.day); HireDate.yearday = day_of_year( HireDate); HireDate.yearday = day_of_year( HireDate); printf( printf(從從%d%d年元月年元月1 1日到日到%d%d年年%d%d月月%d%d日的雇傭期限日的雇傭期限 : : %d %d天,天,nn應(yīng)付給他的工錢應(yīng)付給他的工錢: %-.2f: %-.2f元。元。n, n, HireDate.year, HireDate.year,HireDate.month, HireDate.day, HireDate.yearday, laborage

40、 * HireDate.yearday);/ 計(jì)算某年某月某日是這一年的第幾天int day_of_year(struct Date pd) int day_tab213 = 0,31,28,31,30,31,30,31,31,30,31,30,31, / 非閏年的每月 /天數(shù) 0,31,29,31,30,31,30,31,31,30,31,30,31; / 閏年的每月 天數(shù)/* 為了與月份一致,列號(hào)不運(yùn)用為零的下標(biāo)號(hào)。行號(hào)為0是非閏年的每月天數(shù),為1是閏年的每月天數(shù) */ int i, day, leap; / leap為0是非閏年,為1是閏年 day = pd.day; / 將當(dāng)月的天數(shù)參

41、與 leap = pd. year % 4 = 0 & / 能被4整除的年份根本上是閏年 pd. year % 100 != 0 | / 能被100整除的年份不是閏年 pd. year % 400 = 0; / 能被400整除的年份又是閏年 / 求從元月1日算起到這一天的累加天數(shù) for(i = 1 ; i pd .month ; i+) day += day_tableapi; return day;該程序的運(yùn)轉(zhuǎn)結(jié)果為:請(qǐng)輸入每天的工資 : 38.5(CR)請(qǐng)輸入年份 : 2000(CR)請(qǐng)輸入月份 : 10(CR)請(qǐng)輸入日 : 1(CR)從2000年元月1日到2000年10月1日的

42、雇傭期限 : 275天,應(yīng)付給他的工錢 : 10587.50元。例8.8 通訊錄的建立和顯示程序(采用地址方式傳送構(gòu)造變量)#include #define MAX 3 /用符號(hào)常量MAX表示建立通訊錄人數(shù)最 /大記錄數(shù)struct Address /定義一個(gè)通訊錄的構(gòu)造,包括姓名、地址 /和 char name20; char addr50; char 15;int input(struct Address *pt); /通訊錄錄入函數(shù)原型void display(struct Address *pt,int n); /通訊錄顯示函數(shù)原型void main() struct Address

43、manMAX; /定義一個(gè)構(gòu)造數(shù)組, /存放學(xué)生通訊錄數(shù)據(jù) int i; for(i=0;iname); if(pt-name0=0)return 0; /輸入空字符串,停頓錄 /入,前往0 printf(Address?); gets(pt-addr); printf(Telephone?); gets(pt-); return 1; /正常前往1 /*通訊錄顯示函數(shù),顯示整個(gè)通訊錄的數(shù)據(jù),*/void display(struct Address *pt,int n) int i; printf( name address n); printf(- -n); for(i=0 ; iname

44、,pt-addr,pt-);該程序運(yùn)轉(zhuǎn)結(jié)果為:Name?王偉Address?東八舍416室Telephone? 87543641Name?李玲Address?南三舍219室Telephone? 87543945Name?張利Address?東八舍419室Telephone?87543645 /輸入/以下為輸出name address -王偉 東八舍416室 87543641李玲 南三舍219室 87543945張利 東八舍419室 87543645闡明: 1該程序由三個(gè)函數(shù)組成,其中input( )函數(shù)用于以人機(jī)對(duì)話方式輸入數(shù)據(jù),它的方式參數(shù)pt是構(gòu)造指針,用來接納構(gòu)造地址。在main( )函

45、數(shù)中調(diào)用input( )函數(shù)時(shí),實(shí)參數(shù)是&mani,它是構(gòu)造數(shù)組man 中的第i個(gè)構(gòu)造的地址。程序中看出,main( )的for循環(huán)中,經(jīng)過i的遞增依次把man 中的各個(gè)構(gòu)造地址傳送到input( ),在input( )中給該構(gòu)造的各個(gè)成員項(xiàng)輸入數(shù)據(jù)。在輸入過程中,對(duì)name輸入零時(shí),整個(gè)輸入過程終了。2輸入數(shù)據(jù)后,調(diào)用display( )函數(shù)顯示輸入結(jié)果。在調(diào)用display( )時(shí),實(shí)參數(shù)是構(gòu)造數(shù)組man 的首地址,從而把整個(gè)構(gòu)造數(shù)組傳送到函數(shù)中。display( )函數(shù)用構(gòu)造指針pt接納傳送來的地址。然后經(jīng)過pt的加一運(yùn)算,依次處置各個(gè)構(gòu)造的數(shù)據(jù)。例8.9 前往構(gòu)造變量的函數(shù)/*

46、該例題中調(diào)用了一個(gè)名為str_add_int的函數(shù),該函數(shù)前往的是一個(gè)構(gòu)造類型變量,在這個(gè)例題中,同時(shí)引見了數(shù)字串與浮點(diǎn)數(shù)轉(zhuǎn)換的方法*/#include #include #include struct Record /定義一個(gè)構(gòu)造 char str20; int num;struct Record str_add_int(struct Record x); /函數(shù)原型聲明void main() struct Record p,s=“31.45,20; /*定義構(gòu)造 變量p,s,并對(duì)s初始化*/*以傳送值的方式,將構(gòu)造變量s傳送給函數(shù)str_add_int,經(jīng)過該函數(shù)對(duì)s的復(fù)制值加工處置后,再

47、將結(jié)果經(jīng)過return語句前往給main中的另一構(gòu)造變量p*/ p=str_add_int(s); printf(%s %dn,s.str,s.num); printf(%s %dn,p.str,p.num);struct Record str_add_int(struct Record x) /形參x和實(shí)參s的類型一致 float e; e=atof(x.str); /將字符串x.str轉(zhuǎn)換為浮 /點(diǎn)數(shù)并賦給e e=e+x.num; /浮點(diǎn)數(shù)與整數(shù)相加 gcvt(e,5,x.str); /將浮點(diǎn)數(shù)e再轉(zhuǎn)換為字 /符串,并賦給x.str return x; /將處置后的結(jié)果構(gòu)造 /變量前往給調(diào)

48、用函數(shù)程序運(yùn)轉(zhuǎn)結(jié)果:31.45 2051.45 20例8.10:前往構(gòu)造變量的地址即構(gòu)造指針型函數(shù)C言語中,構(gòu)造的存儲(chǔ)首地址可以作為函數(shù)的返值傳送給調(diào)用它的函數(shù)。返值為構(gòu)造地址的函數(shù)就是構(gòu)造指針型函數(shù)。/*此題中調(diào)用了一個(gè)名為find的函數(shù),根據(jù)小汽車的代號(hào)不為0在一個(gè)構(gòu)造數(shù)組中來查找該種汽車數(shù)據(jù)的位置,該函數(shù)前往的是一個(gè)構(gòu)造類型指針,該指針指向所找到的構(gòu)造變量,如未找到,前往NULL*/#include #define NULL 0struct Sample /定義一個(gè)構(gòu)造,包括小汽車代號(hào)、顏色和 /類型等成員 int num; char color; char type;struct Sa

49、mple *find(struct Sample *pd,int n); /查找函數(shù)原型void main() int num; struct Sample *result; /定義一個(gè)構(gòu)造指針變量,接納被調(diào) /用函數(shù)的前往值 /定義一個(gè)構(gòu)造數(shù)組并初始化,存放了一切樣品汽車數(shù)據(jù) struct Sample car=101,G,c,210,Y,m,105,R,l, 222,B,s,308,P,b,0,0,0; printf(Enter the number:); scanf(%d,&num); /輸入要查找樣品的代號(hào) /*以傳送地址的方式,將構(gòu)造數(shù)組名car和查找代號(hào)num傳送給函數(shù)fi

50、nd,該函數(shù)前往查找的結(jié)果,找到,前往代號(hào)所對(duì)應(yīng)的樣品汽車數(shù)據(jù)的地址,否那么,前往NULL*/ result=find(car,num); if(result-num!=NULL) /找到,顯示相關(guān)汽車數(shù)據(jù) printf(number :%dn,result-num); printf(color :%cn,result-color); printf(type :%cn,result-type); else printf(not found); /未找到,給出提示信息struct Sample *find(struct Sample *pd,int n) int i; for(i=0 ; pdi

51、.num!=0 ;i+) if(pdi.num=n)break; /找到,退出循環(huán) if(pdi.num!=NULL) return pd+i; /前往查找結(jié)果 else return NULL;該程序的運(yùn)轉(zhuǎn)結(jié)果為:Enter the number:101 /輸入number:101 /輸出color:Gtype:c 該程序是查找構(gòu)造數(shù)組car 中的有關(guān)數(shù)據(jù)。鍵盤輸入一個(gè)整數(shù)后,調(diào)用find( )函數(shù)進(jìn)展查找。然后把查到的構(gòu)造地址作為返值前往。因此,find( )函數(shù)定義為struct sample *型。在main( )中用指向一樣結(jié)構(gòu)的指針result接納函數(shù)返值。在car 構(gòu)造數(shù)組中,用

52、一個(gè)全零構(gòu)造作為構(gòu)造數(shù)組的終了標(biāo)志汽車代號(hào)不為0。采用這種方法便于程序處理??梢钥闯觯瑯?gòu)造數(shù)組中的構(gòu)造數(shù)目無論如何變化,函數(shù)都不需求做任何修正。 構(gòu)造指針型函數(shù)是以地址傳送方式向調(diào)用它的函數(shù)前往構(gòu)造的數(shù)據(jù)。采用這種方式,不僅可以前往某個(gè)構(gòu)造的地址,也可以前往構(gòu)造數(shù)組的地址,從而把函數(shù)中處置的假設(shè)干構(gòu)造的數(shù)據(jù)前往給調(diào)用它的函數(shù)中。8.8 綜合舉例例8.14 編程處置某班N個(gè)學(xué)生4門課的成果,它們是數(shù)學(xué)、物理、英語和計(jì)算機(jī),按編號(hào)從小到大的順序依次輸入學(xué)生的姓名、性別和四門課的成果。計(jì)算每個(gè)學(xué)生的平均分,并以明晰的打印格式從高分到低分的順序打印平均分高于全班總平均成果的男生的成果單。分析:從標(biāo)題的

53、要求來看,該問題可以分成三個(gè)功能塊:輸分析:從標(biāo)題的要求來看,該問題可以分成三個(gè)功能塊:輸入數(shù)據(jù)、排序,求總平均成果和輸出,我們把它規(guī)劃成四個(gè)入數(shù)據(jù)、排序,求總平均成果和輸出,我們把它規(guī)劃成四個(gè)函數(shù)。再來看主要的數(shù)據(jù)類型或數(shù)據(jù)構(gòu)造的選擇,由于學(xué)生函數(shù)。再來看主要的數(shù)據(jù)類型或數(shù)據(jù)構(gòu)造的選擇,由于學(xué)生的姓名、性別、各門功課的成果及平均成果具有一定的關(guān)聯(lián)的姓名、性別、各門功課的成果及平均成果具有一定的關(guān)聯(lián)性,作為集合數(shù)據(jù),將其規(guī)劃為一個(gè)構(gòu)造體:性,作為集合數(shù)據(jù),將其規(guī)劃為一個(gè)構(gòu)造體:struct studentstruct student char name20; /char name20; /姓名姓名char sex; /char sex; /性別,性別,mm代表男,代表男,ff代表女代表女float score4; /float score4; /學(xué)生的各科成果學(xué)生的各科成果float aver; /float aver; /平均成果平均成果; 這樣學(xué)生的數(shù)據(jù)就可以存放在一個(gè)構(gòu)造數(shù)組中。有了上面的分析結(jié)果,我們就可以規(guī)劃出三個(gè)函數(shù)的原型:(1)輸入數(shù)據(jù):void input(struct student *p,int n);第一個(gè)參數(shù)用來接納存儲(chǔ)

溫馨提示

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