第10章構(gòu)造數(shù)據(jù)類型_第1頁
第10章構(gòu)造數(shù)據(jù)類型_第2頁
第10章構(gòu)造數(shù)據(jù)類型_第3頁
第10章構(gòu)造數(shù)據(jù)類型_第4頁
第10章構(gòu)造數(shù)據(jù)類型_第5頁
已閱讀5頁,還剩44頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第10章構(gòu)造數(shù)據(jù)類型

本章教學(xué)目標(biāo):理解結(jié)構(gòu)型的涵義,掌握結(jié)構(gòu)型的定義、結(jié)構(gòu)型變量的定義和使用;理解共用型的涵義,掌握共用型的定義、共用型變量的定義和使用;理解枚舉型的涵義,掌握枚舉型的定義、枚舉型變量的定義和使用;理解typedef作用,掌握typedef的使用方法;能綜合運用上述方法和技術(shù)進(jìn)行較復(fù)雜的程序設(shè)計。

第7章構(gòu)造數(shù)據(jù)類型10.1結(jié)構(gòu)類型與結(jié)構(gòu)變量10.2結(jié)構(gòu)變量的引用和初始化

10.3結(jié)構(gòu)和數(shù)組10.4結(jié)構(gòu)和函數(shù)10.5結(jié)構(gòu)的嵌套10.6共用體(union)10.7枚舉類型10.8類型定義10.9結(jié)構(gòu)和共用體的綜合應(yīng)用

10.1結(jié)構(gòu)類型與結(jié)構(gòu)變量實際生活中的事物,往往具有多種屬性,如“學(xué)生”這個實體,它有:

“學(xué)號”“姓名”“性別”“成績”等屬性,一般來說這些屬性是一些不同類型的量,如“學(xué)號”是長整型量“姓名”、“性別”是字符型的量“成績”是實型量等因此,要描述“學(xué)生”這種實體,數(shù)組是無能為力的,必須使用另外的數(shù)據(jù)類型,這就是結(jié)構(gòu)型(structure)。結(jié)構(gòu)型將多種元素組合在一起形成一個整體,與數(shù)組不同的是,數(shù)組中的元素都是同一類型,而結(jié)構(gòu)型中的元素可以是不同的類型。另外,數(shù)組定義的是一個具體的實體,而結(jié)構(gòu)型定義的是實體的類型,是一種數(shù)據(jù)抽象機制,定義結(jié)構(gòu)型之后,可以用結(jié)構(gòu)型定義多個這種類型的實體,稱為結(jié)構(gòu)型變量。

10.1.1結(jié)構(gòu)類型的定義結(jié)構(gòu)體是若干個類型相同或不同數(shù)據(jù)項的集合。定義一個結(jié)構(gòu)類型的一般形式為:

struct結(jié)構(gòu)類型名 {數(shù)據(jù)類型數(shù)據(jù)項1; 數(shù)據(jù)類型數(shù)據(jù)項2; …… 數(shù)據(jù)類型數(shù)據(jù)項n; };

structstudent{charno[15];/*學(xué)號*/

charname[15];/*姓名*/

floatyw,sx,yy;/*三門課的成績*/

floattotal;/*總成績*/};其中,結(jié)構(gòu)類型名是student,而no[15]、name[15]、yw、sx、yy和total被稱為結(jié)構(gòu)的成員變量。nonameywsxyytotal200012201NameOne39.【例10.1】假若一個學(xué)生的基本情況包含以下數(shù)據(jù)項:學(xué)號(no)、姓名(name)、語文(yw)、數(shù)學(xué)(sx)、英語(yy)三門課程成績和總成績。如圖10-1所示,那么,我們可以用如下結(jié)構(gòu)類型描述學(xué)生的基本情況。圖10-1

上述語句定義了一個名為student(學(xué)生)的結(jié)構(gòu)類型。①struct

是關(guān)鍵字,標(biāo)志結(jié)構(gòu)類型。struct后面跟的是所定義的結(jié)構(gòu)體類型的名字。“結(jié)構(gòu)體類型名”的命名與變量的命名規(guī)則相同。②結(jié)構(gòu)體的各個“數(shù)據(jù)項”用括號括起來,“數(shù)據(jù)項”的定義和命名規(guī)則與變量的相同。類型相同的數(shù)據(jù)項,既可以逐個、逐行分別定義,也可以合并成一行定義。③結(jié)構(gòu)體的“數(shù)據(jù)類型”可以是基本類型,也可以是構(gòu)造類型,如數(shù)組;還可以是結(jié)構(gòu)體類型(參見§10.5結(jié)構(gòu)的嵌套)。④結(jié)構(gòu)體的一個“數(shù)據(jù)項”稱結(jié)構(gòu)體類型的一個成員(或分量)。例如,本例中:學(xué)號(no)、姓名(name)、語文(yw)、數(shù)學(xué)(sx)、英語(yy)和總成績(total)是student的成員。結(jié)構(gòu)型的定義僅僅是給出了該結(jié)構(gòu)型的組成情況,系統(tǒng)并不為其分配實際的存儲單元,為了使用它,必須定義結(jié)構(gòu)型變量:

struct

student

ZhangFan,LiYing,*p;|||||關(guān)鍵字結(jié)構(gòu)型名結(jié)構(gòu)型變量結(jié)構(gòu)型指針

上面的語句定義了student結(jié)構(gòu)型變量ZhangFan(張帆)、LiYing(李英)和結(jié)構(gòu)型指針p。10.1.2結(jié)構(gòu)變量的定義

1.間接定義法———先定義結(jié)構(gòu)類型,再定義結(jié)構(gòu)型變量

struct結(jié)構(gòu)類型名變量名;

例如,用例10.1定義的結(jié)構(gòu)類型structstudent,就可用來定義結(jié)構(gòu)變量。語句:

structstudentzhanshan;就把zhanshan定義為structstudent類型結(jié)構(gòu)變量。2.直接定義法———在定義結(jié)構(gòu)型的同時定義結(jié)構(gòu)型變量

struct[結(jié)構(gòu)類型名]/*此時,結(jié)構(gòu)類型名可缺省*/ {數(shù)據(jù)類型數(shù)據(jù)項1; 數(shù)據(jù)類型數(shù)據(jù)項2; ………… 數(shù)據(jù)類型數(shù)據(jù)項n; }變量表;

注意(1)結(jié)構(gòu)類型與結(jié)構(gòu)變量是不同的概念,不能混淆。結(jié)構(gòu)類型的定義只說明了結(jié)構(gòu)的組織形式,本身并不占用儲存空間,只有當(dāng)定義了結(jié)構(gòu)變量時,才占用儲存空間。(2)結(jié)構(gòu)類型的定義與變量相似,也有作用域問題。如果結(jié)構(gòu)類型的定義出現(xiàn)在函數(shù)內(nèi)部,則它的作用范圍是局部的,只在該函數(shù)內(nèi)部利用該類型定義相應(yīng)的結(jié)構(gòu)變量;如果結(jié)構(gòu)類型的定義位于函數(shù)的外面,則它的作用范圍是全局的,從它的定義位置起到所在文件末尾的所有函數(shù)都可以利用它定義相應(yīng)的結(jié)構(gòu)變量。一般情況下,結(jié)構(gòu)類型的定義都位于一個文件的首部(3)在不同結(jié)構(gòu)類型里,成員名可以相同,但它們各自代表不同的對象,互不相干。思考題:你認(rèn)為那種定義方式較好,為什么?10.2結(jié)構(gòu)變量的引用和初始化

雖然結(jié)構(gòu)型變量是作為一個整體被定義的,但不能將一個結(jié)構(gòu)型變量作為一個整體進(jìn)行輸入輸出,只能通過結(jié)構(gòu)型變量的成員來訪問它。

10.2.1結(jié)構(gòu)變量的引用1.簡單結(jié)構(gòu)變量的引用一般形式如下:結(jié)構(gòu)變量名.成員名其中,“.”是結(jié)構(gòu)成員運算符,它在所有運算符中優(yōu)先級最高。因此,上述引用結(jié)構(gòu)成員的寫法可以作為一個整體看待。例如,結(jié)構(gòu)變量student1中的成員可表示為:

student1.no,,student1.yw,student1.sx,student1.yy,student1.total。

【例10.2】利用例10.1中定義的結(jié)構(gòu)類型structstudent,定義兩個結(jié)構(gòu)變量,用于存儲兩名學(xué)生的信息。要求從鍵盤輸入數(shù)據(jù),并輸出總分較高的學(xué)生信息。main(){structstudent{ charno[15]; charname[15]; floatyw,sx,yy,total;}stu1,stu2;printf(“\nInputthefirststudentdata:”);gets(stu1.no);gets();scanf(“%f%f%f”,&stu1.yw,&stu1.sx,&stu1.yy);stu1.total=stu1.yw+stu1.sx+stu1.yy;printf(“\nInputthesecondstudentdata:“);gets(stu2.no);gets();scanf(“%f%f%f”,&stu2.yw,&stu2.sx,&stu2.yy);stu2.total=stu2.yw+stu2.sx+stu2.yy;if(stu1.total>stu2.total)printf(“\n%s,%s,%f,%f,%f,%f”,stu1.no,,stu1.yw,stu1.sx,stu1.yy,stu1.total);elseprintf(“\n%s,%s,%f,%f,%f,%f”,stu2.no,,stu2.yw,stu2.sx,stu2.yy,stu2.total);}2.同類型結(jié)構(gòu)變量間的引用ANSIC新標(biāo)準(zhǔn)允許將一個結(jié)構(gòu)類型的變量,作為一個整體賦給另一個具有相同結(jié)構(gòu)類型的變量。如有定義:structstudentstud1,stud2;假若要把已賦值好stud1的各成員值復(fù)制給stud2對應(yīng)的各成員,則可用賦值語句:stud2=stud1;實現(xiàn)。特別注意:結(jié)構(gòu)變量不能作為一個整體進(jìn)行輸入和輸出。

10.2.2結(jié)構(gòu)變量的初始化

在定義結(jié)構(gòu)型變量的同時可以對結(jié)構(gòu)型變量進(jìn)行初始化,方式類似于數(shù)組的初始化

例如:

structstudentstud1={“200012201”,“NameOne”,60,70,80,210};這樣結(jié)構(gòu)變量stud1被初始化,它描述了某一個學(xué)生的信息,具體地說,該學(xué)生:學(xué)號:200012201,姓名:NameOne,三科成績分別為60,70,80,總成績210如果初值數(shù)量少于成員數(shù)量,則無初值的成員自動被置0(數(shù)值型成員)或空(字符型成員)?!纠?0.3】

用初始化方法,實現(xiàn)例10.2的功能。

main(){structstudent{charno[15];/*學(xué)號*/

charname[15];/*姓名*/

floatyw,sx,yy;/*三門課的成績*/

floattotal;/*總成績*/}stu1={“20001203”,“NameThree”,70.0,80.0,90.0};stu.total=stu.yw+stu.sx+stu.yy;/*計算總成績*/printf(“\n學(xué)號=%s,姓名=%s”,stu.no,);/*輸出結(jié)果*/printf(“\n語文=%5.1f,數(shù)學(xué)=%5.1f,英語=%5.1f,總分=%5.1f”,stu.yw,stu.sx,stu.yy,stu.total);}10.2.2結(jié)構(gòu)變量的初始化

10.3結(jié)構(gòu)和數(shù)組數(shù)組元素為結(jié)構(gòu)型變量的數(shù)組稱為結(jié)構(gòu)型數(shù)組。10.3.1結(jié)構(gòu)數(shù)組的定義結(jié)構(gòu)型數(shù)組的定義、初始化以及使用方法與普通數(shù)組相仿。例如,下面的例子先定義結(jié)構(gòu)型.再定義結(jié)構(gòu)型數(shù)組并同時進(jìn)行元素的初始化:

structstudent{charno[15];charname[15];floatyw,sx,yy;/*三門課的成績*/

floattotal;/*總成績*/};structstudentstu[40];就定義了一個數(shù)據(jù)stu,其元素為structstudent類型數(shù)據(jù),數(shù)組有40個元素。

10.3.2結(jié)構(gòu)數(shù)組的引用和初始化結(jié)構(gòu)數(shù)組元素也是通過數(shù)組名和下標(biāo)來引用的,但其元素是結(jié)構(gòu)體類型的數(shù)據(jù),因此,對結(jié)構(gòu)體數(shù)組元素的引用與對結(jié)構(gòu)體變量的引用一樣,也是逐級引用,只能對最低級的成員進(jìn)行存取和運算。 一般的引用形式為:

數(shù)組名[下標(biāo)].成員名

例如,對上面定義的數(shù)組stu而言,下面的引用是合法的:①stu[i].no表示第I個學(xué)生的學(xué)號(I=0,1,2,…39)②stu[i].name表示第I個學(xué)生的姓名(I=0,1,2,…39)③stu[i].total表示第I個學(xué)生的總成績(I=0,1,2,…39)

與普通數(shù)組一樣,結(jié)構(gòu)數(shù)組也可以在定義時進(jìn)行初始化,其方法是在定義結(jié)構(gòu)數(shù)組的之后緊跟等號和初始化數(shù)據(jù)。 其一般形式是:struct結(jié)構(gòu)體類型結(jié)構(gòu)數(shù)組名[n]={{初值表1},…,{初值表n}};對結(jié)構(gòu)數(shù)組的初始化時,類似于數(shù)組初始化,根據(jù)缺省原則也可以對方括號中表示元素個數(shù)的項省略。由于結(jié)構(gòu)體是由不同類型的數(shù)據(jù)組成的,所以特別注意初始化數(shù)據(jù)的順序、類型與結(jié)構(gòu)類型說明時相匹配。如兩個學(xué)生:structstudentstud2[]={“200012201”,“NameOne”,60,70,80,210, “200012202”,“NameTwe”,70,80,90,240};或structstudentstud2[]={{“200012201”,“NameOne”,60,70,80,210}, {“200012202”,“NameTwe”,70,80,90,240}};【例10.5】編寫統(tǒng)計候選人得票程序。設(shè)有4名候選人,以輸入得票的候選人名方式模擬倡票,最后輸出倡票結(jié)果。算法設(shè)計:(1)定義結(jié)構(gòu)數(shù)組,并初始化候選人相關(guān)的信息:姓名和得票,由于4名候選人是已知的,并且初值得票為0,所以,可以用初始化方法定義。

structperson {charname[15]; intcount; }leader[4]={{“l(fā)i”,0},{“wang”,0},{“zhan”,0},{“shen”,0}};(2)輸入一個得票的候選人名,模擬倡票scanf(“%s”,name); for(j=0;j<4;j++) if(strcmp(name,leader[j].name)==0)leader[j].count++;(3)輸出各候選人得票for(j=0;j<4;j++)printf(“\n%s=%d”,leader[j].name,leader[j].count);#include“string.h”……../*定義結(jié)構(gòu)數(shù)組,并初始化*/main(){inti,j;charname[15];printf(“\nInputname\n”);for(i=1;i<=10;i++) {scanf(“%s”,name); for(j=0;j<4;j++) if(strcmp(name,leader[j].name)==0)leader[j].count++; } printf(“\nresult:“);for(j=0;j<4;j++) printf(“\n%s=%d”,leader[j].name,leader[j].count);}10.4結(jié)構(gòu)和函數(shù)

結(jié)構(gòu)變量作為一個整體可以被復(fù)制、賦值、傳遞給函數(shù)以及由函數(shù)返回。10.4.1結(jié)構(gòu)變量作為函數(shù)參數(shù)可以用結(jié)構(gòu)型變量、結(jié)構(gòu)型變量的成員和結(jié)構(gòu)型指針作函數(shù)的參數(shù)。10.4.2結(jié)構(gòu)數(shù)組作為函數(shù)參數(shù)10.4.3函數(shù)的返回值是結(jié)構(gòu)類型變量函數(shù)也可以返回結(jié)構(gòu)型變量、結(jié)構(gòu)型變量的成員或結(jié)構(gòu)型指針。10.4.1結(jié)構(gòu)變量作為函數(shù)參數(shù)【例10.6】修改例10.4程序,要求將顯示總分最高的學(xué)生信息的語句,用函數(shù)完成。voidprint_max(structstudents){printf(“%s,%s,%5.1f,%5.1f,%5.1f,%5.1f”,s.no,,stu[max].yw,stu[max].sx,s.yy,s.total);}main(){...for(i=1,max=0;i<N;i++) /*求總分最高的學(xué)生之下標(biāo)*/

if(stuarr[i].total>stu[max].total)max=i;print_max(stuarr[max]);}

圖10-4結(jié)構(gòu)變量作為函數(shù)參數(shù)按C語言參數(shù)傳遞規(guī)則,將實參stuarr[max]的值復(fù)制給形參s,即將各成員變量的值進(jìn)行復(fù)制,如圖10-3所示。10.4.2結(jié)構(gòu)數(shù)組作為函數(shù)參數(shù)

結(jié)構(gòu)數(shù)組作為函數(shù)參數(shù),與數(shù)組作為函數(shù)參數(shù)的處理方式完全相同。即采用“地址傳遞”方式,形參結(jié)構(gòu)變量中各成員值的改變,對相應(yīng)實參結(jié)構(gòu)變量產(chǎn)生影響?!纠?0.7】進(jìn)一步修改例10.6,要求數(shù)據(jù)輸入和統(tǒng)計用函數(shù)實現(xiàn)。將例10.6中的數(shù)據(jù)輸入和統(tǒng)計程序段:for(i=0;i<N;i++){printf(”請輸入第%d個學(xué)生的信息:\n”,i+1);scanf("%s%s%f%f%f",stu[i].no,stu[i].name,&stuarr[i].yw,&stuarr[i].sx,&stu[i].yy);stu[i].total=stu[i].yw+stu[i].sx+stu[i].yy;}把學(xué)生數(shù)N和結(jié)構(gòu)數(shù)組作為函數(shù)的形參。在函數(shù)體內(nèi)對形參操作。voiddata_input(intk,structstudents[]){inti;for(i=0;i<k;i++) {scanf("%s%s%f%f%f",s[i].no,s[i].name,&s[i].yw,&s[i].sx,&s[i].yy);s[i].total=s[i].yw+s[i].sx+s[i].yy;}}完整程序清單請讀者完成。10.4.3函數(shù)的返回值是結(jié)構(gòu)類型變量

【例10.8】修改例10.7,將函數(shù)data_input()中的輸入語句,編一函數(shù)用于結(jié)構(gòu)變量的輸入,將其結(jié)構(gòu)變量返回給主調(diào)函數(shù)中的結(jié)構(gòu)變量。提示:我們只要把函數(shù)data_input()替換為以下兩函數(shù),其余不變,請讀者完成。structstudentelement_input(){structstudents;scanf("%s%s%f%f%f",s[i].no,s[i].name,&s[i].yw,&s[i].sx,&s[i].yy);returns;}voiddata_input(intk,structstudents[]){inti;for(i=0;i<k;i++) {s[i]=element_input(); s[i].total=s[i].yw+s[i].sx+s[i].yy; }}10.5結(jié)構(gòu)的嵌套結(jié)構(gòu)型中的成員也可以是另一結(jié)構(gòu)型變量,也就是說,結(jié)構(gòu)型可以嵌套定義

例如:structdate/*定義日期結(jié)構(gòu)型*/{intday;charmonth[10];intyear;};structstudent/*定義學(xué)生結(jié)構(gòu)型,其中有日期結(jié)構(gòu)型的成員*/{longnumber;charname[10];charsex;structdatebirthday;/*birthday為date結(jié)構(gòu)型變量*/floatenglish,mathematics;/*同類型變量可以一起定義*/}ZhangFan,LiYing,*p;

在定義結(jié)構(gòu)型時,結(jié)構(gòu)型名不是必須的,沒有名字的結(jié)構(gòu)型稱為匿名結(jié)構(gòu)型。例:structstudent{longnumber; charname[10]; charsex; struct/*定義匿名結(jié)構(gòu)型*/ {

intday;charmonth[10]; intyear; }birthday;/*birthday為匿名結(jié)構(gòu)型變量*/

floatenglish,mathematics;

}ZhangFan,LiYing,*p;【例10.9】

建立N名學(xué)生的檔案,每個學(xué)生的數(shù)據(jù)包括學(xué)號、姓名、入學(xué)時間及一門功課的成績。要求從鍵盤輸入數(shù)據(jù),并顯示最后的結(jié)果。算法設(shè)計要點:(1)定義學(xué)生的檔案的結(jié)構(gòu)類型structperson{char no[15];charname[15];入學(xué)時間;floatscore;};(2)定義“入學(xué)時間”的結(jié)構(gòu)類型日期的信息,要求包括年、月、日??梢杂靡粋€結(jié)構(gòu)描述。structent{intyear,month,day;};(3)structperson的結(jié)構(gòu)如圖10-5所示。包括了structdate型結(jié)構(gòu)變量。圖10-5nonameentscoreyearmonthdaystructdate{intyear,month,day;};structperson{char no[15];char name[15];structdateent;floatscore;};voiddata_input(structpersons[]){inti;for(i=0;i<N;i++)scanf(“%s%s%d%d%d%f”,s[i].no,s[i].name,&s[i].ent.year,&s[i].ent.month,&s[i].ent.day,&s[i].score);}voiddata_output(structpersons[]){inti;for(i=0;i<N;i++)printf(“\n%s%s%d%d%d%f”,s[i].no,s[i].name,&s[i].ent.year,&s[i].ent.month,&s[i].ent.day,&s[i].score);}main(){structpersons[N];data_input(s);data_output(s);}10.6共用體(union)

10.6.1共用體的概念

有時需將幾種不同類型的變量存放到同一段內(nèi)存單元中,例如,把一個整型變量i,一個字符變量ch和一個實型變量f放在地址為1000的起始內(nèi)存單元(如圖10-5)。以上三個變量在內(nèi)存中占的字節(jié)數(shù)不同,具體地說,i,ch,f分別占據(jù)2個,1個和4個字節(jié),可以看出,這三個變量是相互覆蓋的,因此,某一時刻只能對其中一個變量進(jìn)行操作。這種使用不同變量共占同一段內(nèi)存的結(jié)構(gòu)稱為“共用體”類型的結(jié)構(gòu)。

charch<空閑3字節(jié)>inti<空閑2字節(jié)>float圖10-5共用體

共用體變量在內(nèi)存中的起始地址1000

10.6.2共用體類型的定義

與結(jié)構(gòu)類型的定義類似,共用體的定義形式為:

union共用型類型名{類型標(biāo)識符1成員1;類型標(biāo)識符2成員2;┋類型標(biāo)識符n成員n;};

例如,上述數(shù)據(jù)類型可用共用型類型表示如下:uniondata{inti;charch;floatf;};可以看出,在形式上,共用體與結(jié)構(gòu)類似,只是把結(jié)構(gòu)的關(guān)鍵詞struct換成了共用體的關(guān)鍵詞union。

10.6.3共用體類型變量的定義

與結(jié)構(gòu)變量的定義一樣,共用體類型變量的定義也有2種:(1)間接定義——先定義類型、再定義變量語句:uniondatax,y,z;定義x,y,x同為uniondata型變量。 (2)直接定義——在定義類型的同時定義變量例如,union[data]/*共用體名可缺省*/{charch;inti;floatf;}x,y,z;

10.6.4共用體變量的引用共用體變量的引用方式與結(jié)構(gòu)變量的引用方式也非常類似。例如,前面定義了共用體變量x、y、z后,則對其成員變量的引用分別為:x.i、x.ch、x.f。C語言最初引入共用體的目的之一是為了節(jié)省存儲空間,另外一個目的是可以將一種類型的數(shù)據(jù)不通過顯式類型轉(zhuǎn)換而作為另一種類型數(shù)據(jù)使用?!纠?0.10】用共用體處理鍵盤掃描碼。#include<stdio.h>unionscancode{intkey;charvalue[2];}code;main(){charhighbyte,lowbyte;code.key=bioskey(0);/*讀鍵盤掃描碼*/

lowbyte=code.value[0];/*取出低字節(jié)*/

highbyte=code.value[1];/*取出高字節(jié)*/

printf(”高字節(jié)=0x%2x低字節(jié)=0x%2x”,highbyte,lowbyte);}說明

①共用體采用覆蓋技術(shù),實現(xiàn)不同類型的變量存放到同一內(nèi)存單元,所以在每一時刻,存放的和起作用的是最后一次存入的成員值。在引用共用體成員變量時,必需是最后存入的共用體成員變量。例如,執(zhí)行語句x.ch=‘a(chǎn)’;x.i=10;x.f=12.6;后,引用變量x的成員,只有x.f才是有效的。②共用體變量不能用作函數(shù)的參數(shù),也不能是函數(shù)返回共用體變量,同樣,在定義共用體變量時,也不能進(jìn)行初始化。③共用體變量可出現(xiàn)在結(jié)構(gòu)類型中,結(jié)構(gòu)變量也可以出現(xiàn)在共用體類型中。例如:structsystem{inti;charname;union{floatf;charp;}u;}st;訪問成員f、p,可以用st.u.f及st.u.p。10.7枚舉類型“枚舉”就是一一列舉,枚舉型用于定義名字化的數(shù)據(jù),比如,可以將顏色值定義為“red”、“yellow”、“blue”等,將日期值定義為“Sunday”、“Monday”、“Tuesday”等,以便于閱讀和理解,與#define定義的符號常量相比,枚舉型的優(yōu)點是系統(tǒng)能夠?qū)γ杜e變量進(jìn)行值的合法性判別,提高了程序的可靠性。枚舉型和枚舉變量的定義形式為:enum枚舉型名{標(biāo)識符1,標(biāo)識符2,…,標(biāo)識符n}枚舉變量列表;

enum是定義枚舉型的關(guān)鍵字,枚舉型名是由程序員自定義的新類型的名字。枚舉型定義之后就可以用它來定義這種類型的變量,花括號中的標(biāo)識符稱為枚舉元素或枚舉常量,其值為整常數(shù),在默認(rèn)情況下,整常數(shù)從0開始依次加1。它們表示該枚舉型的變量只能取花括號中所列出的標(biāo)識符1,標(biāo)識符2,…,標(biāo)識符n這n個值,取其他值都是非法的?!纠?0.11】

從鍵盤輸入一整數(shù),顯示與該整數(shù)對應(yīng)的枚舉常量的英文名稱。#include“stdio.h”main(){enumweek{sun,mon,tue,wed,thu,fri,say};enumweekweekday;inti;scanf(“%d”,&i);weekday=(enumweek)i;switch(weekday){casesun:printf(“Sunday\n”);break;...casesat:printf(“Saturday\n”);break;}}枚舉型在使用中還應(yīng)注意下列問題:(1)企圖給枚舉元素(枚舉常量)賦值,是錯誤的。(2)可以在定義枚舉型時改變枚舉常量的默認(rèn)值(有的書稱為初始化),方法是:

enumcolor{red=2,yellow,blue,white=7,black}c1;此時,red為2,yellow為3,blue為4,

white為7,black為8。(3)可以將枚舉常量賦給一個整型變量。但不能將一個整數(shù)賦給枚舉變量,必要時須進(jìn)行強制類型轉(zhuǎn)換。(4)枚舉常量和枚舉變量可以參與關(guān)系運算,如:

if(c1==red)printf(“red”);if(c1!=black)printf(“itisnotblack”);f(c1>white)printf(“itisblack");

它們是按所代表的整數(shù)進(jìn)行比較的。(5)枚舉常量不是字符串,不能用下面的方法輸出字符串“red”printf(“%s”,red);只能用下述方法輸出:

if(c1==red)printf(“red”);10.8類型定義

類型定義(typedef)

顧名思義是定義類型的意思,但它只能為已有的類型定義一個新的名字(別名),而不能定義出新的類型來。

使用typedef的好處是:可以使類型名更貼切,便于閱讀和理解;可以為復(fù)雜的類型(結(jié)構(gòu)型、共用型、數(shù)組和指針)取一個更簡潔的名字,方便使用;而最大的好處是便于程序的移植。

例如:typedefintCOUNT;這樣,COUNT就是int的新名字(別名),于是以下兩句等價:COUNTi,j;inti,j;可以使人更一目了然地知道i,j是用于計數(shù)的。

10.8.1定義基本類型的別名

聲明基本類型的形式為: typedef基本類型名

別名標(biāo)識符;例如: typedefintWORD; typedeffloatREAL; typdefunsignedcharBYTE;指定用WORD代表int類型,REAL代表float,BYTE代表unsignedchar。所以,以下兩行等價: (1)inti,k;floatx,y;unsignedchara,b; (2)WORDi,k;REALx,y;BYTEa,b;10.8.2定義自定義的數(shù)據(jù)類型的別名

聲明自定義類型的形式為: typedef自定義類型說明信息別名標(biāo)識符;例如:

typedefstructstudent {charno[15]; charname[15]; floatyw,sx,yy; floattotal; }STUDENT;這樣,在說明structstudent類型的變量stu1,stu2時,就可用如下語句實現(xiàn): STUDENTstu1,stu2;

10.8.3定義已有類型別名的一般步驟(1)按定義變量的方法,寫出定義體;(2)將變量名換成別名;(3)在定義體最前面加上typedef?!纠?0.12】給unsignedint定義一個別名DWORD。(1)按定義變量的方法,寫出定義體:unsignedinta;(2)將變量名換成別名:unsignedintDWORD;(3)在定義體最前面加上typedef:typedefunsignedintDWORD;

【例10.13】定義NUM為有5個元素的整型數(shù)組別名。(1)按定義變量的方法,寫出定義體:inta[5];(2)將變量名換成別名:intNUM[5];(3)在定義體最前面加上typedef:typedefintNUM[5];然后用NUM去定義數(shù)組變量,語句: NUMx,y;把x,y都被定義為含有5個元素的整型數(shù)組。即等價于:

intx[5],y[5];說明

(1)用typedef只是對已有的類型增加一個別名,而沒有創(chuàng)造新的類型。(2)typedef與#define有相似之處,但兩者是不同的,如:

typdefintWORD;和#defineWORDint的作用都是用WORD代表int。前者是由編譯器在編譯時處理的;后者是由編譯預(yù)處理器在編譯預(yù)處理時處理的,而且只能作簡單的字符串替換。(3)使用typedef有利于程序的通用和移植。例如,把一個C程序從一個以4個字節(jié)存放整數(shù)的計算機系統(tǒng)移植到以2個字節(jié)存放整數(shù)的計算機系統(tǒng),按一般方法需要將定義變量中的每個int改為longint,但這樣太麻煩?,F(xiàn)可以用WORD定義為int的別名:

typedefintWORD;在程序中的所有整型變量都用DWOR定義。在移植時只需要改動typedef定義體即可:

typedeflongintWORD;10.9構(gòu)造數(shù)據(jù)類型的綜合應(yīng)用:編輯器第四版

利用結(jié)構(gòu)體和共用體變量,優(yōu)化程序tedit3,并為程序tedit3添加字符串查找和替換功能,完成§9.3.7提出的設(shè)計目標(biāo),升級為第四版tedit4。10.9.1編輯器第四版tedit4在開發(fā)tedit4程序之前,我們先預(yù)演增加的功能,觀察效果。(1)啟動程序tedit4.exe,首先編輯一些字符;(2)單擊查找功能鍵F3,屏幕底部將提示用戶,要求輸入待查找的字符串,輸入完后回車,程序執(zhí)行查找,如果找到了,光標(biāo)會停留在已找到的第一個字符串處,否則將出現(xiàn)未找到的提示信息;(3)單擊替換功能鍵F4,與其它編輯器類似,輸入查找和替換的字符串后回車,編輯文本中從光標(biāo)開始以后的所有查找字符串將被替換為替換字符串。(4)按ESC鍵,退出程序。

10.9.2優(yōu)化程序tedit3

引入結(jié)構(gòu)和共用體變量,把tedit3.c中部分全局變量定義為結(jié)構(gòu)成員,用共用體處理鍵盤掃描碼。

1.定義全局的結(jié)構(gòu)變量將程序tedit3.c中的全局變量定義語句:intscrnx,scrny;intcurloc,endloc;修改為全局的結(jié)構(gòu)變量point的成員:struct{intscrnx,scrny;intcurloc,endloc;}point;2.修改對變量scrnx,scrny,curloc,endloc

溫馨提示

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

評論

0/150

提交評論