《程序設(shè)計(jì)基礎(chǔ)》課件第9章_第1頁(yè)
《程序設(shè)計(jì)基礎(chǔ)》課件第9章_第2頁(yè)
《程序設(shè)計(jì)基礎(chǔ)》課件第9章_第3頁(yè)
《程序設(shè)計(jì)基礎(chǔ)》課件第9章_第4頁(yè)
《程序設(shè)計(jì)基礎(chǔ)》課件第9章_第5頁(yè)
已閱讀5頁(yè),還剩84頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

第9章結(jié)構(gòu)體、共用體和枚舉類型9.1結(jié)構(gòu)體

9.2單鏈表

9.3共用體和枚舉類型

9.4typedef定義類型

習(xí)題 9.1結(jié)構(gòu)體

在實(shí)際應(yīng)用中,一組數(shù)據(jù)往往具有不同的數(shù)據(jù)類型。例如在學(xué)生登記表中,學(xué)號(hào)、姓名、性別、年齡、電話號(hào)碼和家庭地址的數(shù)據(jù)類型不完全相同。顯然不能用數(shù)組來存放這一組數(shù)據(jù),因?yàn)閿?shù)組中各元素的類型和長(zhǎng)度都必須一致。為了解決這個(gè)問題,C語(yǔ)言中給出了另一種構(gòu)造數(shù)據(jù)類型——結(jié)構(gòu)體。結(jié)構(gòu)體是一種構(gòu)造類型,它是由若干“成員”組成的。每一個(gè)成員可以是一個(gè)基本數(shù)據(jù)類型,或者是另一個(gè)構(gòu)造類型。結(jié)構(gòu)體既然是一種“構(gòu)造”而成的數(shù)據(jù)類型,那么在說明和使用之前必須先定義結(jié)構(gòu)體類型。9.1.1結(jié)構(gòu)體的類型定義

結(jié)構(gòu)體是由程序設(shè)計(jì)者自己定義的類型。因此,除了結(jié)構(gòu)體變量需要定義之外,結(jié)構(gòu)體類型本身也必須定義。定義結(jié)構(gòu)體類型的一般形式如下:

struct結(jié)構(gòu)體名

{

數(shù)據(jù)類型1成員1;

數(shù)據(jù)類型2成員2;

數(shù)據(jù)類型n成員n;

};說明:

(1)?struct是定義結(jié)構(gòu)體類型的關(guān)鍵字,不能省略。

(2)結(jié)構(gòu)體名遵循標(biāo)識(shí)符的命名規(guī)則。

(3)結(jié)構(gòu)體有若干數(shù)據(jù)成員,用{}括起來,分別屬于各自的數(shù)據(jù)類型。結(jié)構(gòu)體成員名同樣遵循標(biāo)識(shí)符的命名規(guī)則。

(4)定義結(jié)構(gòu)體類型,就是定義一種數(shù)據(jù)類型,與基本數(shù)據(jù)類型是一樣的,只不過結(jié)構(gòu)體類型是一種復(fù)雜的數(shù)據(jù)類型,是基本數(shù)據(jù)類型的組合。應(yīng)注意,使用結(jié)構(gòu)體類型時(shí),“struct結(jié)構(gòu)體名”是作為一個(gè)類型名來對(duì)待的,它與標(biāo)準(zhǔn)類型(如int、char等)具有相同的地位和作用。

(5)定義結(jié)構(gòu)體類型后,C系統(tǒng)并不分配存儲(chǔ)空間,只有定義了該結(jié)構(gòu)體類型的變量后,系統(tǒng)才為此變量分配存儲(chǔ)空間。

例9-1

定義一個(gè)學(xué)生信息的結(jié)構(gòu)體類型。structstudent

{

intnum;

charname[19];

charsex;

intage;

chartel[20];

charaddr[40];

};說明:

(1)“structstudent”是結(jié)構(gòu)體類型名。struct是關(guān)鍵字,在定義和使用時(shí)均不能省略。

(2)該結(jié)構(gòu)體類型由6個(gè)成員組成。這6個(gè)成員分別屬于不同的數(shù)據(jù)類型,各個(gè)成員之后的分號(hào)“;”不能省略。應(yīng)特別注意的是,最后的分號(hào)是必不可少的。9.1.2結(jié)構(gòu)體數(shù)據(jù)的定義和引用

1.先聲明結(jié)構(gòu)體類型再定義變量名

如上面已經(jīng)定義了一個(gè)結(jié)構(gòu)體類型structstudent,可以用它來定義變量。如:

structstudentstu1,stu2;

定義了兩個(gè)變量stu1和stu2,為structstudent類型的變量。在定義了結(jié)構(gòu)體變量之后,系統(tǒng)會(huì)為之分配內(nèi)存單元。例如stu1和stu2在內(nèi)存中所占的字節(jié)是structstudent類型中各個(gè)成員所占字節(jié)數(shù)之和,即4+19+1+4+20+40=88字節(jié)。2.在聲明結(jié)構(gòu)體類型的同時(shí)定義變量

例如:

structstudent

{

intnum;

charname[19];

charsex;

intage;

chartel[20];

charaddr[40];

}stu1,stu2;它的作用與第一種方法相同,即定義了兩個(gè)structstudent類型的變量stu1和stu2。這種在聲明結(jié)構(gòu)體類型的同時(shí)定義結(jié)構(gòu)體變量一般形式為:

struct結(jié)構(gòu)名

{

成員表列;

}變量名表列;3.直接定義結(jié)構(gòu)類型變量

例如:

struct

{

intnum;

charname[19];

charsex;

intage;

chartel[20];

charaddr[40];

}stu1,stu2;其一般形式為:

struct

{

成員表列;

}變量名表列;說明:

(1)結(jié)構(gòu)體類型和結(jié)構(gòu)體變量是不同的概念,不要混淆。在定義時(shí)一般先定義一個(gè)結(jié)構(gòu)體類型,然后再定義該結(jié)構(gòu)體類型的變量。注意:只能對(duì)結(jié)構(gòu)體變量賦值、運(yùn)算、輸出,而不能對(duì)結(jié)構(gòu)體類型賦值、運(yùn)算、輸出。

(2)在編譯時(shí),對(duì)結(jié)構(gòu)體類型不分配空間,只對(duì)變量分配空間。

(3)一個(gè)結(jié)構(gòu)體變量所占存儲(chǔ)空間是各個(gè)成員所占存儲(chǔ)空間之和。例如,上面定義的stu1,stu2所占存儲(chǔ)空間的大小為4+19+1+4+20+40,共計(jì)88個(gè)字節(jié)。

(4)結(jié)構(gòu)體中的成員也可以是另一個(gè)結(jié)構(gòu)體類型的變量,例如:

structdate

{

intyear;

intmonth;

intday;

};

structstudent

{

intnum;

charname[19];

charsex;

intage;

chartel[20];

charaddr[40];

structdatebirthday;

};注意:結(jié)構(gòu)體成員的類型不能是正在定義的結(jié)構(gòu)體類型(遞歸定義,結(jié)構(gòu)體類型大小不能確定),但可以是正在定義的結(jié)構(gòu)體類型的指針。

4.結(jié)構(gòu)體變量的初始化

對(duì)結(jié)構(gòu)體變量的各個(gè)成員賦初值,稱為初始化。初始化的方法有以下幾種。

(1)定義結(jié)構(gòu)體變量時(shí)賦初值。例如:struct

{

intnum;

charname[19];

charsex;

intage;

chartel[20];

charaddr[40];

}stu1={};注意:變量后面的一組數(shù)據(jù)應(yīng)該用“{}”括起來,其順序也應(yīng)該與結(jié)構(gòu)體中的成員順序保持一致。

(2)定義結(jié)構(gòu)體變量后直接賦值。例如:

stu1.num=10036;

strcpy(,"zhangsan");

stu1.sex='M';

(3)用scanf()函數(shù)對(duì)結(jié)構(gòu)體變量的成員賦值。例如:

scanf("%d%s%c%d%s",&stu1.num,,&stu1

.sex,&stu1.age,stu1.tel);

5.結(jié)構(gòu)體變量的引用

在定義結(jié)構(gòu)體變量以后,不能直接引用該變量,而應(yīng)引用該變量的成員,格式如下:

結(jié)構(gòu)體變量名.成員名

其中“.”是成員運(yùn)算符,它在所有運(yùn)算符中優(yōu)先級(jí)最高,與()是同一個(gè)級(jí)別。

說明:

(1)不允許將結(jié)構(gòu)體變量整體輸入和輸出,只能對(duì)結(jié)構(gòu)體變量中的各個(gè)成員分別進(jìn)行輸入和輸出。例如:

scanf("%d%s%c%d%s",&stu1.num,,

&stu1.sex,&stu1.age,stu1.tel);

printf("%d,%s,%c,%d,%s\n",stu1.num,,

stu1.sex,stu1.age,stu1.tel);

(2)只能對(duì)最低級(jí)的成員進(jìn)行賦值、存取以及運(yùn)算。例如:

stu1.birthday.year=1980;

(3)對(duì)結(jié)構(gòu)體變量的成員可以像普通變量一樣進(jìn)行各種運(yùn)算。同時(shí)也可以把結(jié)構(gòu)體變量的成員看做簡(jiǎn)單變量來使用。例如:stu1.age可以等價(jià)于一個(gè)int型變量,如:

stu1.age++;

sum=stu1.age+stu2.age;

(4)同一種類型的結(jié)構(gòu)體變量之間可以直接賦值(整體賦值,實(shí)質(zhì)上是對(duì)對(duì)應(yīng)成員逐個(gè)依次賦值的)。例如:

stu2=stu1;

6.結(jié)構(gòu)體數(shù)組

數(shù)組是具有相同類型的一組元素的集合。結(jié)構(gòu)體數(shù)組中的每一個(gè)元素都是結(jié)構(gòu)體類型。結(jié)構(gòu)體數(shù)組的定義方法與結(jié)構(gòu)體變量的定義方法類似,結(jié)構(gòu)體數(shù)組元素的使用也和一般數(shù)組元素的使用類似。在實(shí)際應(yīng)用中,經(jīng)常采用結(jié)構(gòu)體數(shù)組來表示具有相同數(shù)據(jù)結(jié)構(gòu)的一個(gè)群體,例如一個(gè)班的學(xué)生檔案,一個(gè)車間的職工信息等。/*源程序9-1*/

#include"stdio.h"

main()

{

structstudent

{

intnum;

charname[19];

charsex;

intage;

chartel[20];

charaddr[40];

};

structstudentst[2]={{2001101,"wangchen",'M',23,

,"nanjing"},{2001105,"zhangsan",'F',21,,"xi'an"}};

printf("%d,%s,%c,%d,%s,%s\n",st[1].num,st[1].name,

st[1].sex,st[1].age,st[1].tel,st[1].addr);

}程序運(yùn)行結(jié)果如下:

注意:上面的源程序中定義了結(jié)構(gòu)體數(shù)組st,其元素為st[0]和st[1]??梢圆捎谩皵?shù)組元素.成員名”這種格式來使用結(jié)構(gòu)體數(shù)組中某個(gè)元素的成員,例如,st[0].num和st[1].age。

7.結(jié)構(gòu)體指針變量

結(jié)構(gòu)體指針變量和一般指針變量的作用是一致的。結(jié)構(gòu)體指針變量的值是結(jié)構(gòu)體變量在內(nèi)存中的起始地址。

(1)定義:

struct結(jié)構(gòu)體名*結(jié)構(gòu)體指針變量名;

例如:

structstudentstu;

structstudent*s=&stu;

structstudentst[3];

structstudent*p,*q;

p=st,q=&st[1];

(2)通過結(jié)構(gòu)體指針變量訪問結(jié)構(gòu)體變量的成員方法為:

(*結(jié)構(gòu)體指針變量名).成員名

或者

結(jié)構(gòu)體指針變量名->成員名

其中“->”稱為指向運(yùn)算符。例如:

(*s).sex='M';

s->age=23;

結(jié)構(gòu)體指針變量完整的應(yīng)用程序舉例如下:/*源程序9-2*/

#include"stdio.h"

main()

{

structstudent

{

intnum;

charname[19];

charsex;

intage;

chartel[20];

charaddr[40];

};

structstudentstu={2001101,"wangchen",'M',23,

,"nanjing"};

structstudent*s=&stu;

printf("%d,%s,%c,%d,%s,%s\n",stu.num,(*s).name,s->sex,s->age,(*s).tel,stu.addr);

}

程序運(yùn)行結(jié)果如下: 9.2單鏈表

9.2.1動(dòng)態(tài)存儲(chǔ)分配

1.malloc函數(shù)

格式:void*malloc(unsignedintsize);

功能:在內(nèi)存的動(dòng)態(tài)存儲(chǔ)區(qū)中分配1個(gè)長(zhǎng)度為size的連續(xù)空間。

函數(shù)的返回值:申請(qǐng)存儲(chǔ)空間成功,返回申請(qǐng)的存儲(chǔ)空間的起始地址;申請(qǐng)不成功,返回NULL。

2.calloc函數(shù)

格式:void*calloc(unsignedn,unsignedintsize);

功能:在內(nèi)存的動(dòng)態(tài)存儲(chǔ)區(qū)中分配n個(gè)長(zhǎng)度為size的連續(xù)空間。

函數(shù)的返回值:申請(qǐng)存儲(chǔ)空間成功,返回申請(qǐng)的存儲(chǔ)空間的起始地址;申請(qǐng)不成功,返回NULL。

3.free函數(shù)

格式:voidfree(void*p);

功能:釋放由指針p指向的內(nèi)存區(qū),使這部分內(nèi)存區(qū)能被其他變量使用。

free函數(shù)無返回值。9.2.2單鏈表概述

鏈表是一種重要的數(shù)據(jù)結(jié)構(gòu),它可以根據(jù)需要?jiǎng)討B(tài)地開辟內(nèi)存單元,進(jìn)行相應(yīng)的操作(形象地講,就像是根據(jù)人數(shù)登記房間住宿)。鏈表就像一列火車,有車頭,有車尾,每節(jié)車廂里都放有一定數(shù)量的貨物,而且從中增加、刪除若干節(jié)車廂后,還要保證前后的連接。

(1)鏈表有一個(gè)“頭指針”變量,它存放鏈表第一個(gè)結(jié)點(diǎn)的地址。

(2)鏈表中每一個(gè)元素稱為一個(gè)結(jié)點(diǎn),每個(gè)結(jié)點(diǎn)都包括兩部分:數(shù)據(jù)域和指針域。數(shù)據(jù)域用來存放用戶數(shù)據(jù),指針域用來存放下一個(gè)結(jié)點(diǎn)的地址。

(3)鏈表的最后一個(gè)結(jié)點(diǎn)的指針域常常設(shè)置為NULL(空),表示鏈表到此結(jié)束。

(4)常常用結(jié)構(gòu)體變量作為鏈表中的結(jié)點(diǎn)。

單鏈表的結(jié)構(gòu)如圖9-1所示。圖9-1單鏈表的結(jié)構(gòu)9.2.3單鏈表的基本操作

1.建立動(dòng)態(tài)鏈表

建立動(dòng)態(tài)鏈表是指在程序執(zhí)行過程中根據(jù)需要從無到有地建立一個(gè)鏈表,即不斷地一個(gè)一個(gè)開辟結(jié)點(diǎn)空間并輸入各結(jié)點(diǎn)數(shù)據(jù),同時(shí)建立各個(gè)結(jié)點(diǎn)的前后相連關(guān)系。/*源程序9-3*/

#include"stdio.h"

#include"malloc.h"

#defineLENsizeof(structstudent)

intn;

structstudent

{

intnum;

charname[20];

structstudent*next;};

structstudent*creat()

{

structstudent*head;//head為頭指針,指向鏈表的第一個(gè)結(jié)點(diǎn)

structstudent*p1,*p2;//p1指向當(dāng)前申請(qǐng)的空間,p2指向鏈表的最后結(jié)點(diǎn)

n=0;

head=NULL;

p1=(structstudent*)malloc(LEN);

p2=p1;

scanf("%d,%s",&p1->num,p1->name);

while(p1->num!=0)

{

n=n+1;

if(n==1)head=p1;

elsep2->next=p1;

p2=p1;

p1=(structstudent*)malloc(LEN);

scanf("%d,%s",&p1->num,p1->name);

}

p2->next=NULL;

returnhead;

}程序說明:

(1)定義一個(gè)結(jié)構(gòu)體,包含數(shù)據(jù)域(學(xué)號(hào)、姓名)和指針域(指向結(jié)構(gòu)體變量的指針)。定義全局變量n,統(tǒng)計(jì)結(jié)點(diǎn)的個(gè)數(shù)。

(2)動(dòng)態(tài)申請(qǐng)一個(gè)結(jié)點(diǎn),輸入學(xué)生數(shù)據(jù)到此結(jié)點(diǎn)空間,并使p1和p2共同指向它。

(3)輸入學(xué)生數(shù)據(jù)到p1所指向的空間。

(4)在循環(huán)控制下,動(dòng)態(tài)再申請(qǐng)一個(gè)存儲(chǔ)空間,使p1指向它,然后輸入學(xué)生數(shù)據(jù),結(jié)點(diǎn)個(gè)數(shù)增1,n=n+1。

(5)執(zhí)行p2->next=p1;語(yǔ)句,實(shí)現(xiàn)鏈表的鏈接。

(6)?p1指向當(dāng)前申請(qǐng)的結(jié)點(diǎn),p2始終指向鏈表的最后結(jié)點(diǎn)。

(7)循環(huán)執(zhí)行(4)~(6),實(shí)現(xiàn)結(jié)點(diǎn)的動(dòng)態(tài)創(chuàng)建。

(8)循環(huán)的條件是申請(qǐng)的存儲(chǔ)空間中輸入的學(xué)號(hào)不等于0。

(9)循環(huán)結(jié)束,使最后一個(gè)結(jié)點(diǎn)的指針域?yàn)镹ULL。

建立單鏈表的過程如圖9-2所示。圖9-2單鏈表的建立過程

2.輸出動(dòng)態(tài)鏈表

輸出鏈表就是將鏈表各個(gè)結(jié)點(diǎn)的數(shù)據(jù)在循環(huán)控制下,依次從單鏈表頭輸出到鏈表尾。/*源程序9-4*/

voidprint(structstudent*head)

{

structstudent*p;

printf("\nNow,There%drecordsare:\n",n);

p=head;

if(head!=NULL)

do

{

printf("%-6d%-10s\n",p->num,p->name);

p=p->next;

}while(p!=NULL);

}程序說明:

(1)首先定義一個(gè)結(jié)構(gòu)體指針p,并使p指向鏈表的第一個(gè)結(jié)點(diǎn)。

(2)在鏈表非空的情況下,輸出p所指向的結(jié)點(diǎn)的數(shù)據(jù)。

(3)使p指針移到下一個(gè)結(jié)點(diǎn),通過語(yǔ)句p=p->next;?實(shí)現(xiàn)。

(4)循環(huán)執(zhí)行(2)、(3),循環(huán)條件是p所指向的結(jié)點(diǎn)不為NULL,即p!=NULL。

3.鏈表的插入操作

鏈表的插入指的是將某個(gè)結(jié)點(diǎn)插入到一個(gè)按照學(xué)號(hào)已經(jīng)有序的鏈表中,插入后鏈表仍然保持有序。/*源程序9-5*/

structstudent*insert(structstudent*head,structstudent*stu)

{

structstudent*p0,*p1,*p2;

p1=head;

p0=stu;

if(head==NULL)

{

head=p0;

p0->next=NULL;

}

else

{

while((p0->num>p1->num)&&(p1->next!=NULL))

{

p2=p1;

p1=p1->next;

}

if(p0->num<p1->num)

{ if(head==p1)

head=p0;

else

p2->next=p0;

p0->next=p1;

}

else

{ p1->next=p0;

p0->next=NULL;

}

}

n=n+1;

returnhead;

}程序說明:

(1)此鏈表的插入操作前提是鏈表已經(jīng)按照學(xué)號(hào)(num)的大小關(guān)系由小到大排好序。

(2)先用指針變量p0指向待插入的結(jié)點(diǎn),p1指向當(dāng)前結(jié)點(diǎn),初始情況為鏈表的第1個(gè)結(jié)點(diǎn)。

(3)在空表中插入結(jié)點(diǎn),或者如果要插入結(jié)點(diǎn)比第1個(gè)結(jié)點(diǎn)學(xué)號(hào)還小,則直接執(zhí)行head=p0;p0->next=p1;。

(4)將要插入結(jié)點(diǎn)學(xué)號(hào)與當(dāng)前結(jié)點(diǎn)學(xué)號(hào)進(jìn)行比較。在循環(huán)控制下,逐個(gè)比較if(p0->num>p1->num),如果成立,則向后查找合適位置p2=p1;,p1指針下移一個(gè)結(jié)點(diǎn)p1=p1->next;如果不成立,則插入,執(zhí)行p2->next=p0;p0->next=p1;,即將p0指向的結(jié)點(diǎn)插入到當(dāng)前結(jié)點(diǎn)之前。

(5)如果要插入的結(jié)點(diǎn)學(xué)號(hào)比最后一個(gè)結(jié)點(diǎn)(p1->next=

=NULL)學(xué)號(hào)還大,則插在最后一個(gè)結(jié)點(diǎn)之后,p1->next=p0;p0->next=NULL;。

4.鏈表的刪除操作

鏈表的刪除是指將某個(gè)結(jié)點(diǎn)從一個(gè)有序的鏈表中分離出來,刪除后鏈表仍然保持有序。/*源程序9-6*/

structstudent*del(structstudent*head,intno)

{

structstudent*p1,*p2;

if(head==NULL)

{

printf("\nlistnull!\n");

returnhead;

}

p1=head;

while(p1->num!=no&&p1->next!=NULL){

p2=p1;

p1=p1->next;

}

if(p1->num==no)

{

if(p1==head)

head=p1->next;

else

p2->next=p1->next;

printf("delete:%d\n",no);

n=n-1;

}

else

printf("%dnotbeenfound!\n",no);

returnhead;

}程序說明:

(1)設(shè)兩個(gè)指針變量p1和p2,使p1指向鏈表的第一個(gè)結(jié)點(diǎn)。

(2)如果該鏈表為空鏈表,則無需做任何操作,提前結(jié)束刪除。

(3)如果要?jiǎng)h除的不是第一個(gè)結(jié)點(diǎn),則在循環(huán)控制下,逐個(gè)比較檢查。

while((p1->num!=no)&&(p1->next!=NULL)),如果成立,p2=p1;則使p2指向剛才檢查過的那個(gè)結(jié)點(diǎn),便于刪除;p1指針下移一個(gè)結(jié)點(diǎn),p1=p1->next;。如果不成立,則退出循環(huán),表示找到了或者整個(gè)鏈表全部檢查完都沒找到。

(4)如果要?jiǎng)h的是第一個(gè)結(jié)點(diǎn),則應(yīng)將p1->next賦給head,這時(shí)head指向原來第二個(gè)結(jié)點(diǎn),原來第一個(gè)結(jié)點(diǎn)已與鏈表脫離而“丟失”;如果要?jiǎng)h的不是第一個(gè)結(jié)點(diǎn),則將p1->next賦給p2->next。

(5)如果鏈表中找不到要?jiǎng)h除的結(jié)點(diǎn),則輸出錯(cuò)誤信息提示。

5.鏈表的綜合應(yīng)用

例9-2

將以上建立、輸出、插入、刪除的函數(shù)組織在一個(gè)程序中,并在main()函數(shù)中進(jìn)行調(diào)用,以實(shí)現(xiàn)鏈表的綜合應(yīng)用。/*源程序9-7*/

main()

{

structstudent*head,*stu;

intdel_num;

printf("inputrecords:\n");

head=creat();

print(head);

printf("\ninputthedeletednumber:\n");

scanf("%d",&del_num);

while(del_num!=0)

{

head=del(head,del_num);

print(head);

printf("inputthedeletednumber:\n");

scanf("%d",&del_num);

}

printf("\ninputtheinsertedrecord:\n");

stu=(structstudent*)malloc(LEN);

scanf("%d,%s",&stu->num,stu->name);

while(stu->num!=0)

{

head=insert(head,stu);

print(head);

printf("inputtheinsertedrecord:\n");

stu=(structstudent*)malloc(LEN);

scanf("%d,%s",&stu->num,stu->name);

}

}程序運(yùn)行結(jié)果如下: 9.3共用體和枚舉類型

9.3.1共用體

1.定義

共用體就是將不同類型的數(shù)據(jù)項(xiàng)存放于同一段內(nèi)存單元的一種構(gòu)造數(shù)據(jù)類型。與結(jié)構(gòu)體類似,在共用體內(nèi)可以定義多種不同數(shù)據(jù)類型的成員。兩者之間的區(qū)別在于:共用體類型變量所有成員共用一塊內(nèi)存單元,雖然每個(gè)成員都可以被賦值,但只有最后一次賦予的成員值能夠保存且有意義,前面賦予的成員值被后面賦予的成員值所覆蓋;結(jié)構(gòu)體中各個(gè)成員占有各自的內(nèi)存空間,各個(gè)成員的賦值互不影響。2.定義共用體類型變量的一般形式

定義共用體類型變量的一般形式如下:

union共用體名

{

類型1成員1;

類型2成員2;

類型n成員n;

}變量表列;例如:

uniondata

{

inti;

floatf;

charch;

}data1,data2;

3.說明

(1)結(jié)構(gòu)體變量所占內(nèi)存長(zhǎng)度是各個(gè)成員占的內(nèi)存長(zhǎng)度之和,每個(gè)成員分別占有各自獨(dú)立的內(nèi)存單元;而共用體變量所占的內(nèi)存長(zhǎng)度等于最長(zhǎng)的成員的長(zhǎng)度。

(2)在共用體中,同一內(nèi)存段可以用來存放不同類型的成員,但是每一瞬時(shí)只能存放其中的一種(也只有一種有意義)。

(3)共用體變量的地址和其成員的地址都是同一地址。

(4)不能對(duì)共用體變量名賦值,也不能企圖引用共用體變量名得到一個(gè)值。同時(shí),也不能在定義共用體變量時(shí)對(duì)其進(jìn)行初始化(系統(tǒng)不清楚是為哪個(gè)成員賦初值)。

(5)不能把共用體變量作為函數(shù)參數(shù),也不能使函數(shù)帶回共用體變量,但可以使用指向共用體變量的指針。

(6)共用體和結(jié)構(gòu)體可以相互嵌套。

例9-3

統(tǒng)計(jì)學(xué)校的人員數(shù)據(jù)。教師的數(shù)據(jù)包括:編號(hào)、姓名、性別、職業(yè)、職稱;學(xué)生的數(shù)據(jù)包括:編號(hào)、姓名、性別、職業(yè)、班級(jí)。如果將兩種數(shù)據(jù)放在同一個(gè)表格中,那么其中有一欄,對(duì)于教師登記教師的“職稱”,對(duì)于學(xué)生則登記學(xué)生的“班級(jí)”(同一人員不可能既是教師又是學(xué)生)。解決此問題的程序如下:/*源程序9-8*/

#include<stdio.h>

unionuniondata

{

charclasses[20];

charposition[20];

};

structdata

{

intnum;

charname[20];charsex;

charjob;

unionuniondatasharedata;

};

voidmain()

{

structdataperson[2];

inti;

for(i=0;i<2;i++)

{

scanf("%d%s%c%c",&person[i].num,&person[i].name,

&person[i].sex,&person[i].job);

if(person[i].job=='S')

scanf("%s",person[i].sharedata.classes);

elseif(person[i].job=='T')

scanf("%s",person[i].sharedata.position);

else

printf("Inputerror!");

}

printf("\n");

for(i=0;i<2;i++)

{

if(person[i].job=='S')

printf("No:%-6dName:%-10ssex:%cjob:%csharedata:

%-8s\n",person[i].num,

person[i].name,person[i].sex,person[i].job,person

[i].sharedata.classes);

else

printf("No:%-6dName:%-10ssex:%cjob:%csharedata:

%-8s\n",person[i].num,

person[i].name,person[i].sex,person[i].job,person[i].

sharedata.position);

}

}程序運(yùn)行結(jié)果如下:9.3.2枚舉類型

(1)枚舉類型是指將變量的值一一列舉出來,變量的值只限于列舉出來的值的范圍。

(2)聲明枚舉類型的格式:

enum枚舉類型名{枚舉常量1,枚舉常量2,…,枚舉常量n};

例如:

enumweekday{sun,mon,tue,wed,thu,fri,sat};

(3)定義枚舉類型變量。

①定義枚舉類型的同時(shí)定義變量:

enum枚舉類型名{枚舉常量1,…}枚舉變量名;

②先定義類型后定義變量:

enum枚舉類型名枚舉變量名;

③匿名枚舉類型:

enum{枚舉常量列表}枚舉變量列表;

(4)說明:

①enum是標(biāo)識(shí)枚舉類型的關(guān)鍵字,定義枚舉類型時(shí)用enum開頭。

②枚舉常量是符號(hào),由程序設(shè)計(jì)者自己指定,命名規(guī)則同標(biāo)識(shí)符。使用枚舉常量可以提高程序的可讀性。枚舉類型在可視化編程時(shí)常使用。

③枚舉元素在編譯時(shí),按定義時(shí)的排列順序取值0,1,2,…(類似整型常數(shù))。在定義枚舉類型時(shí),可以給這些枚舉常量指定整型常數(shù)值(未指定值的枚舉常量的值是前一個(gè)枚舉常量的值加1)。④枚舉元素是常量,不是變量??梢詫⒚杜e元素賦值給枚舉變量,但是不能給枚舉常量賦值。

⑤枚舉常量不是字符串。

⑥枚舉變量、常量一般可以參與整數(shù)可以參與的運(yùn)算,如算術(shù)/關(guān)系/賦值等運(yùn)算。

例如:

enumweekday{sun=7,mon=1,tue,wed,thu,fri,sat};

9.4typedef定義類型

C語(yǔ)言不僅提供了標(biāo)準(zhǔn)的數(shù)據(jù)類型名,而且還允許由用戶為已經(jīng)存在的數(shù)據(jù)類型名取“別名”。用typedef對(duì)已有的數(shù)據(jù)類型名取“別名”的一般格式為:

typedef數(shù)據(jù)類型名數(shù)據(jù)類型的別名;

數(shù)據(jù)類型的別名一般用大寫表示,例如:

typedefintINTEGER;

INTEGERa,b;

以上語(yǔ)句等效于:

inta,b;說明:typedef并沒有建立新的數(shù)據(jù)類型,僅僅是對(duì)已有類型命名別名。使用typedef定義類型可以增加程序可讀性,簡(jiǎn)化書寫。

用typedef對(duì)已有的數(shù)據(jù)類型名取“別名”的一般方法為:

①先按定義變量的方法寫出定義體(如:inti)。

②將變量名換成新類型名(如:將i換成COUNT)。

③在最前面加typedef(例如:typedefintCOUNT)。

④然后可以用此類型別名去定義變量。例如:

typedefcharNAME[20];

NAME代表了字符數(shù)組類型,數(shù)組長(zhǎng)度為20。然后可以用NAME定義變量,如:

NAMEa1,a2,s1,s2;

以上命令等效于:

chara1[20],a2[20],s1[20],s2[20];例如:

typedefstructstudent

{

intnum;

charname[19];

charsex;

intage;

}STU;

STU代表了上面的一個(gè)結(jié)構(gòu)體類型,然后可以用STU來定義此結(jié)構(gòu)變量,如:

STUstudent1,student2;

以上命令等效于:

structstudentstudent1,student2;

例如:

typedefchar*STRING;

STRING代表了字符指針類型,然后可以用STRING來定義字符指針類型的變量,如:

STRINGc;

以上命令等效于:

char*c;

習(xí)題

1.學(xué)生的記錄由學(xué)號(hào)和成績(jī)組成,共N名學(xué)生。編寫函數(shù)fun(STU*a,STU*b,intlow,inthight)。它的功能是:把a(bǔ)數(shù)組中指定分?jǐn)?shù)范圍內(nèi)的學(xué)生數(shù)據(jù)放在b所指的數(shù)組中,分?jǐn)?shù)范圍內(nèi)的學(xué)生人數(shù)由函數(shù)值返回。分?jǐn)?shù)范圍從最低分的low開始,到最高分hight結(jié)束,并且包含這兩個(gè)上下界限。typedefstruct

{

charnum[10];

ints;

}STU;

intfun(STU*a,STU*b,intlow,inthight)

{}

2.學(xué)生的記錄由學(xué)號(hào)和學(xué)習(xí)成績(jī)構(gòu)成,共N名學(xué)生。編寫函數(shù)fun。函數(shù)的功能是:找出成績(jī)最低的學(xué)生記錄,通過形參返回主函數(shù)(規(guī)定只有一個(gè)最低分)。

typedefstructss

{

charnum[10];

int

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝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ù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 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)論