版權(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 柳州職業(yè)技術(shù)學(xué)院《動(dòng)畫劇本與分鏡設(shè)計(jì)》2023-2024學(xué)年第一學(xué)期期末試卷
- 江西中醫(yī)藥大學(xué)《畫法幾何與土建制圖》2023-2024學(xué)年第一學(xué)期期末試卷
- 新蘇教版一年級(jí)下冊(cè)數(shù)學(xué)第1單元第1課時(shí)《9加幾》教案
- 華僑大學(xué)《思想道德修養(yǎng)》2023-2024學(xué)年第一學(xué)期期末試卷
- 湖北科技職業(yè)學(xué)院《Web應(yīng)用與開發(fā)》2023-2024學(xué)年第一學(xué)期期末試卷
- 河南中醫(yī)藥大學(xué)《音樂基礎(chǔ)理論2》2023-2024學(xué)年第一學(xué)期期末試卷
- 重慶輕工職業(yè)學(xué)院《辦公空間設(shè)計(jì)》2023-2024學(xué)年第一學(xué)期期末試卷
- 駐馬店職業(yè)技術(shù)學(xué)院《馬克思主義中國(guó)化》2023-2024學(xué)年第一學(xué)期期末試卷
- 浙江萬里學(xué)院《金融風(fēng)險(xiǎn)分析師(FRM)專題(雙語(yǔ))》2023-2024學(xué)年第一學(xué)期期末試卷
- 浙江工貿(mào)職業(yè)技術(shù)學(xué)院《證券投資常識(shí)》2023-2024學(xué)年第一學(xué)期期末試卷
- 開展課外讀物負(fù)面清單管理的具體實(shí)施舉措方案
- 中國(guó)骨關(guān)節(jié)炎診療指南(2024版)解讀
- 2025年內(nèi)蒙古包鋼集團(tuán)公司招聘筆試參考題庫(kù)含答案解析
- 企業(yè)內(nèi)訓(xùn)師培訓(xùn)師理論知識(shí)考試題庫(kù)500題(含各題型)
- 2025年云南中煙工業(yè)限責(zé)任公司招聘420人高頻重點(diǎn)提升(共500題)附帶答案詳解
- 2024年山西省晉中市公開招聘警務(wù)輔助人員(輔警)筆試專項(xiàng)訓(xùn)練題試卷(2)含答案
- 2023九年級(jí)歷史上冊(cè) 第二單元 5《羅馬城邦和羅馬帝國(guó)》教學(xué)實(shí)錄 新人教版
- 仁愛英語(yǔ)八年級(jí)上冊(cè)詞匯練習(xí)題全冊(cè)
- 報(bào)價(jià)單模板及范文(通用十二篇)
- 鈑金部品質(zhì)控制計(jì)劃
- 標(biāo)準(zhǔn)內(nèi)包骨架油封規(guī)格及公差
評(píng)論
0/150
提交評(píng)論