第十一章結(jié)構(gòu)體、共用體與枚舉_第1頁(yè)
第十一章結(jié)構(gòu)體、共用體與枚舉_第2頁(yè)
第十一章結(jié)構(gòu)體、共用體與枚舉_第3頁(yè)
第十一章結(jié)構(gòu)體、共用體與枚舉_第4頁(yè)
第十一章結(jié)構(gòu)體、共用體與枚舉_第5頁(yè)
已閱讀5頁(yè),還剩90頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

11.1結(jié)構(gòu)體11.2共用體11.3枚舉類(lèi)型11.4用戶定義類(lèi)型11.5程序舉例第11章結(jié)構(gòu)體、共用體與枚舉11.1結(jié)構(gòu)體數(shù)組是一組有序的同類(lèi)型數(shù)據(jù)的集合,直接由類(lèi)型標(biāo)識(shí)符定義,如:inta[5]。而結(jié)構(gòu)體一般是不同類(lèi)型數(shù)據(jù)集合,例如一個(gè)學(xué)生的信息(字符數(shù)組)(字符)(長(zhǎng)整型)(字符)(整型)(字符數(shù)組)住址民族學(xué)號(hào)性別年齡姓名注意:結(jié)構(gòu)體要先定義類(lèi)型(數(shù)據(jù)結(jié)構(gòu)),然后才能用該類(lèi)型定義實(shí)體(變量、數(shù)組、指針等)。11.1.1結(jié)構(gòu)體類(lèi)型的定義1.結(jié)構(gòu)體類(lèi)型的定義形式為:struct結(jié)構(gòu)體類(lèi)型名{成員項(xiàng)表列};struct結(jié)構(gòu)體類(lèi)型名{數(shù)據(jù)類(lèi)型數(shù)據(jù)項(xiàng)1;數(shù)據(jù)類(lèi)型數(shù)據(jù)項(xiàng)2;…………數(shù)據(jù)類(lèi)型數(shù)據(jù)項(xiàng)n;};例如:structstudent{charname[20];intage;charsex;longnum;charnation;charaddress[20];};2.結(jié)構(gòu)體類(lèi)型中成員項(xiàng)的類(lèi)型也可以相同,例如:structdate{intmonth;intday;intyear;};3.結(jié)構(gòu)體類(lèi)型中成員項(xiàng)的類(lèi)型若是結(jié)構(gòu)體類(lèi)型,就構(gòu)成結(jié)構(gòu)體類(lèi)型嵌套。structperson1{charname[20];structdatebirthday;charsex;longnum;charnation;charaddress[20];longtel;};11.1.2結(jié)構(gòu)體類(lèi)型變量的定義結(jié)構(gòu)體變量的定義有三種方法1.用已定義的結(jié)構(gòu)體類(lèi)型名定義變量,例如:

structstudentstu1,stu2;定義了兩個(gè)結(jié)構(gòu)體變量stu1和stu2,用上面的結(jié)構(gòu)體類(lèi)型還可再定義變量:

structstudentmen,women;2.在定義結(jié)構(gòu)體類(lèi)型的同時(shí)定義結(jié)構(gòu)體變量。例如:structstudent

{charname[20];

intage;

……

charaddress[20];

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

struct類(lèi)型名

{成員項(xiàng)表列;

}變量名表列;這樣定義的結(jié)構(gòu)體類(lèi)型也可多次使用,如:

structstudentmen,women;3.不定義結(jié)構(gòu)體類(lèi)型名,直接定義結(jié)構(gòu)體變量。一般形式為:struct{成員項(xiàng)表列;}變量名表列;不定義結(jié)構(gòu)體類(lèi)型名直接定義結(jié)構(gòu)體變量,該類(lèi)型只能使用一次,無(wú)法再定義同類(lèi)型的其他變量??梢?jiàn):struct

{成員項(xiàng)表列;}是表示結(jié)構(gòu)體類(lèi)型的核心。4.結(jié)構(gòu)體變量存儲(chǔ)單元的字節(jié)數(shù)系統(tǒng)為結(jié)構(gòu)體變量開(kāi)辟一段連續(xù)存儲(chǔ)單元,其字節(jié)數(shù)可以用運(yùn)算符sizeof測(cè)得:sizeof(變量名);或sizeof(類(lèi)型名);例如:sizeof(stu1);或sizeof(structstudent);結(jié)果都是50,存儲(chǔ)情況為:20B1B4B1B4B20Baddressnationnumsexagename對(duì)嵌套結(jié)構(gòu)體類(lèi)型,例如:sizeof(structperson1);結(jié)果是58,其存儲(chǔ)情況為:可見(jiàn),數(shù)據(jù)都是存放在其基本成員之中。11.1.3結(jié)構(gòu)體變量的引用1.引用結(jié)構(gòu)體成員在無(wú)嵌套的情況下,引用結(jié)構(gòu)體變量成員的形式為:結(jié)構(gòu)體變量名·成員名其中的“.”叫“結(jié)構(gòu)體成員運(yùn)算符”,結(jié)構(gòu)體成員相當(dāng)于一個(gè)普通變量,例如:student.num在有嵌套的情況下引用形式為:結(jié)構(gòu)體變量名·結(jié)構(gòu)體成員名·…·基本成員名例如:student.birthday.year注意:對(duì)結(jié)構(gòu)體成員的訪問(wèn)與普通變量或數(shù)組相同。2.結(jié)構(gòu)體變量的賦值、輸入和輸出

對(duì)結(jié)構(gòu)體變量賦常數(shù)值、輸入和輸出只能對(duì)基本成員進(jìn)行。例如:student.num=1234;gets();printf(“%d”,student.birthday.year);3.同一類(lèi)型的結(jié)構(gòu)體變量之間可相互賦值(數(shù)組之間不能整體賦值)例如:stu1=stu2;11.1.4結(jié)構(gòu)體變量的初始化

在結(jié)構(gòu)體變量定義的同時(shí)可以進(jìn)行初始化賦值,例如:structpersonstud1={“LiLin",18,'M',34011,'h',"13BejingRoad",2098877},stud2={"YuPing",19,'F',34082,'h',"25HefeiRoad",5531678};

注意初始化數(shù)據(jù)應(yīng)與類(lèi)型中的各個(gè)成員在位置上一一對(duì)應(yīng)。對(duì)于嵌套結(jié)構(gòu)體類(lèi)型變量,初始化是對(duì)各個(gè)基本類(lèi)型的成員賦初值,例如:structpersonstudent={"LiLin",12,5,1974,'M',340201,'h',"13BejingRoad",2098877};/*嵌套成員*/【例11-1】輸出結(jié)構(gòu)體數(shù)據(jù)#include<stdio.h>main(){structstudent{charname[20];struct{intmonth;intday;intyear;}bd;charsex;longnum;charnation;charaddress[20];}st={"WangLi",12,15,1974,'M',340201,’h’,"13BejingRoad"};printf("%s,%d,%d,%d,",,st.bd.year,st.bd.month,st.bd.day);printf("%c,%ld,%c,%s\n",st.sex,st.num,st.nation,st.address);}11.1.5結(jié)構(gòu)體數(shù)組1.結(jié)構(gòu)體數(shù)組的定義與結(jié)構(gòu)體變量定義相同,也有三種方法(其實(shí)可以和結(jié)構(gòu)體變量一道定義):(1)先定義結(jié)構(gòu)體類(lèi)型,再定義結(jié)構(gòu)體數(shù)組,如:structstud_type{charname[20];longnum;intage;charsex;floatscore;};structstud_typestudent[50];(2)定義結(jié)構(gòu)體類(lèi)型名的同時(shí)定義結(jié)構(gòu)體數(shù)組,如:structstud_type{……}student[50];(3)不定義結(jié)構(gòu)體類(lèi)型名,直接定義結(jié)構(gòu)體數(shù)組,如:struct{……}student[50];與一般數(shù)組相同,結(jié)構(gòu)體數(shù)組的數(shù)組名也是各元素的連續(xù)存儲(chǔ)單元的首地址,用法也相同。2.結(jié)構(gòu)體數(shù)組的初始化結(jié)構(gòu)體數(shù)組的一個(gè)元素相當(dāng)于一個(gè)結(jié)構(gòu)體變量,結(jié)構(gòu)體數(shù)組初始化即順序?qū)?shù)組元素初始化。如:structstud_typestudent[3]={{"Wangli",80101,18,'M',89.5},{"ZhangFun",89102,19,'M',90.5},{"LiLing",89103,20,'F',98}};

3.結(jié)構(gòu)體數(shù)組的引用(1)除初始化外,對(duì)結(jié)構(gòu)體數(shù)組賦常數(shù)值、輸入和輸出、各種運(yùn)算均是對(duì)結(jié)構(gòu)體數(shù)組元素的基本成員(相當(dāng)于普通變量)進(jìn)行。結(jié)構(gòu)體數(shù)組元素成員表示為:結(jié)構(gòu)體數(shù)組名[下標(biāo)].成員名在嵌套的情況下為:結(jié)構(gòu)體數(shù)組名[下標(biāo)]·結(jié)構(gòu)體成員名·…·結(jié)構(gòu)體成員名·成員名注意:當(dāng)結(jié)構(gòu)體數(shù)組元素的成員是數(shù)組時(shí),若是字符數(shù)組則可以直接引用,如:stu[i].name;若結(jié)構(gòu)體數(shù)組元素的成員是一般數(shù)組時(shí),只能引用其元素,如:stu[i].score[j](2)結(jié)構(gòu)體數(shù)組元素可相互賦值例如:student[1]=student[2];對(duì)于結(jié)構(gòu)體數(shù)組元素內(nèi)嵌的結(jié)構(gòu)體類(lèi)型成員,情況也相同。如:

student[2].birthday=student[1].birthday;

(3)其他注意事項(xiàng)也與結(jié)構(gòu)體變量相同,例如:不允許對(duì)結(jié)構(gòu)體數(shù)組元素或結(jié)構(gòu)體數(shù)組元素內(nèi)嵌的結(jié)構(gòu)體類(lèi)型成員整體賦(常數(shù))值;不允許對(duì)結(jié)構(gòu)體數(shù)組元素或結(jié)構(gòu)體數(shù)組元素內(nèi)嵌的結(jié)構(gòu)體類(lèi)型成員整體進(jìn)行輸入輸出等。另外,在處理結(jié)構(gòu)體問(wèn)題時(shí)經(jīng)常涉及字符或字符串的輸入,這時(shí)要注意:①scanf()函數(shù)用%s輸入字符串遇空格即結(jié)束,因此輸入帶空格的字符串可改用gets函數(shù)。②在輸入字符類(lèi)型數(shù)據(jù)時(shí)往往得到的是空白符(空格、回車(chē)等),甚至運(yùn)行終止,因此常作相應(yīng)處理,即在適當(dāng)?shù)牡胤皆黾觛etchar();空輸入語(yǔ)句,以消除緩沖區(qū)中的空白符。

【例11-2】已知10人(人數(shù)可以通過(guò)宏定義改變)參加選舉,共三個(gè)候選人,候選人的基本信息定義在結(jié)構(gòu)體類(lèi)型當(dāng)中,包括候選人的標(biāo)識(shí)號(hào)iID(整型),候選人的姓名chpName(字符型數(shù)組),得票數(shù)iCount(整型)。選舉時(shí)投票即輸入三個(gè)人的標(biāo)識(shí)號(hào)(iID成員項(xiàng),分別取1、2、3),統(tǒng)計(jì)每位候選人得票數(shù)。#defineNUMBER10structstudent{intiID;charchpName[20];intiCount;}lead[3]={{1,"zhang",0},{2,"tan",0},{3,"wang",0}};main(){inti,j,num;for(i=0;i<NUMBER;i++){scanf("%d",&num);switch(num){case1:lead[0].iCount++;break;case2:lead[1].iCount++;break;case3:lead[2].iCount++;break;default:printf("Errorselection\n");}}for(i=0;i<3;i++)printf("%-10s:%-d\n",lead[i].chpName,lead[i].iCount);}11.1.6結(jié)構(gòu)體指針

(1)指向結(jié)構(gòu)體變量的指針是結(jié)構(gòu)體變量所占內(nèi)存單元的首地址,指向結(jié)構(gòu)體變量的指針變量是存放該地址的變量,如:structstu_type{longnum;charname[20];floatscore[4];}student,*p;p=&student;p是指向結(jié)構(gòu)體變量student的指針變量。1.指向結(jié)構(gòu)體變量的指針變量(2)用指向結(jié)構(gòu)體變量的指針變量表示結(jié)構(gòu)體變量的成員若象上面那樣定義了指向結(jié)構(gòu)體變量的指針變量p以后,*p即表示p所指向的結(jié)構(gòu)體變量student,其成員student.num可表示為:(*p).num或者p->num第二種表示與第一種表示等價(jià),運(yùn)算符“->”與“.”優(yōu)先級(jí)相同,具有最高的優(yōu)先級(jí)。【例11-3】利用結(jié)構(gòu)體指針變量輸出結(jié)構(gòu)體數(shù)據(jù)main(){structstu_type{longnum;charname[20];floatscore[2];}student={20050101,"wang",89,77.5},*p;p=&student;printf("%ld\t%s\t%6.1f%6.1f\n",p->num,p->name,p->score[0],p->score[1]);}2.結(jié)構(gòu)體數(shù)組與結(jié)構(gòu)體指針變量一維數(shù)組的數(shù)組名代表數(shù)組的首地址,一維結(jié)構(gòu)體數(shù)組也一樣。例如數(shù)組名st≡&st[0],st+i≡&st[i],*st≡st[0],*(st+i)≡st[i]??梢詫⒁痪S結(jié)構(gòu)體數(shù)組名賦給指向結(jié)構(gòu)體變量的指針變量,該指針變量將指向下標(biāo)為0的元素,它可以在數(shù)組元素之間移動(dòng)。

【例11-4】用指向結(jié)構(gòu)體變量的指針變量輸出結(jié)構(gòu)體數(shù)組元素。main(){structstu_type{longnum;charname[20];intage;}st[3]

={{1001,"wang",19},{1002,"li",18},{1003,"zhang",20}},*p;printf("No.\tName\tAge\n");for(p=st;p<st+3;p++)printf("%ld\t%s\t%d\n",p->num,p->name,p->age);}【例11-5】輸出上例中全部學(xué)生的name信息main(){structstu_type{longnum;charname[20];intage;}st[3]={{1001,"wang",19},{1002,"li",18},{1003,"zhang",20}},*p,*q;q=(structstu_type*)st[0].name;for(p=q;p<q+3;p++)printf("%s\t",p);}上面將指向結(jié)構(gòu)體成員字符數(shù)組首地址st[0].name轉(zhuǎn)換成指向結(jié)構(gòu)體變量的指針賦給q,按q的方式移動(dòng)。11.1.7結(jié)構(gòu)體與函數(shù)1.結(jié)構(gòu)體變量和結(jié)構(gòu)體變量成員做函數(shù)參數(shù)

(1)結(jié)構(gòu)體變量基本成員作為函數(shù)的實(shí)參由于結(jié)構(gòu)體變量的基本成員存放基本類(lèi)型數(shù)據(jù),因此這種情況與基本類(lèi)型有值變量做實(shí)參相同,形參為基本類(lèi)型的變量,實(shí)現(xiàn)值傳遞。要注意實(shí)參與形參類(lèi)型的一致?!纠?1-6】打印學(xué)號(hào)為20050102學(xué)生的年齡#defineN3voidPRINT(intage)//打印年齡的函數(shù){printf("Age:%d\n",age);}main(){structstu_type{longnum;charname[20];intage;}st[N]={{20050101,"wang",19},{20050102,"li",18},{20050103,"zhao",20}};

inti;for(i=0;i<N;i++)if(st[i].num==20050102)PRINT(st[i].age);//調(diào)用函數(shù)輸出年齡}(2)結(jié)構(gòu)體變量作為函數(shù)參數(shù)這種用法的參數(shù)形式為:形參:結(jié)構(gòu)體變量實(shí)參:有值結(jié)構(gòu)體變量或結(jié)構(gòu)體數(shù)組元素通過(guò)實(shí)參將相應(yīng)的結(jié)構(gòu)體類(lèi)型數(shù)據(jù)傳遞給對(duì)應(yīng)的形參,實(shí)現(xiàn)傳值調(diào)用,不同于數(shù)組作參數(shù)的傳址調(diào)用!【注意】(在結(jié)構(gòu)體類(lèi)型數(shù)據(jù)作為函數(shù)參數(shù)時(shí),應(yīng)將結(jié)構(gòu)體類(lèi)型定義成外部的,即在所有函數(shù)之前定義結(jié)構(gòu)體類(lèi)型。)【例11-7】打印學(xué)號(hào)為20050102學(xué)生的全部信息#defineN3

structstu_type/*定義外部的結(jié)構(gòu)體類(lèi)型*/

{longnum;

charname[20];

intage;

};voidPRINT(structstu_typestu//注意在聲明結(jié)構(gòu)體函數(shù)時(shí)通常是這樣的步驟)

{printf("No.\t\tName\tAge\n");

printf("%-16ld%s\t%d\n",stu.num,,stu.age);

}main()

{structstu_typest[N]

={{20050101,"wang",19},{20050102,"li",18},

{20050103,"zhao",20}};//初始化inti;for(i=0;i<N;i++)

if(st[i].num==20050102)PRINT(st[i]);//注意這一種輸出方式

}2.結(jié)構(gòu)體指針作為函數(shù)參數(shù)此用法一般用于結(jié)構(gòu)體數(shù)組問(wèn)題。與基本類(lèi)型一維數(shù)組的情況相同,實(shí)現(xiàn)傳址調(diào)用,參數(shù)用法如下:形參:結(jié)構(gòu)體數(shù)組或結(jié)構(gòu)體指針變量;實(shí)參:結(jié)構(gòu)體數(shù)組名或取得數(shù)組名首地址的結(jié)構(gòu)體指針變量?!纠?1-8】輸出全部學(xué)生的信息#defineN3structstu_type{longnum;charname[20];intage;};voidPRINT(structstu_type*p){inti;printf("No.\t\tName\tAge\n");for(i=0;i<N;i++)printf("%-16ld%s\t%d\n",(p+i)->num,(p+i)->name,(p+i)->age);}main(){structstu_typest[N]

={{20050101,"wang",19},{20050102,"li",18},{20050103,"zhao",20}};PRINT(st);//無(wú)返回值}3.返回結(jié)構(gòu)體類(lèi)型數(shù)據(jù)的函數(shù)函數(shù)返回值可以是結(jié)構(gòu)體類(lèi)型的值,也可以是指向結(jié)構(gòu)體變量(或數(shù)組元素)的指針。當(dāng)函數(shù)返回值是結(jié)構(gòu)體類(lèi)型的值時(shí),稱(chēng)該函數(shù)為結(jié)構(gòu)體類(lèi)型函數(shù);【例9-9】當(dāng)函數(shù)返回值是指向結(jié)構(gòu)體類(lèi)型存儲(chǔ)單元的指針(地址)時(shí),稱(chēng)該函數(shù)為結(jié)構(gòu)體類(lèi)型指針函數(shù)。【例9-10】【例9-9】用結(jié)構(gòu)體類(lèi)型函數(shù)實(shí)現(xiàn)打印學(xué)號(hào)為20050102學(xué)生的全部信息。#defineN3structstu_type{longnum;charname[20];intage;};structstu_typefun(structstu_typest[])/*返回結(jié)構(gòu)體的函數(shù)*/{inti;for(i=0;i<N;i++)if(st[i].num==20050102)return(st[i]);}main(){structstu_typest[N]

={{20050101,"wang",19},{20050102,"li",18},{20050103,"zhao",20}};//初始化structstu_typestu;//聲明一個(gè)新的結(jié)構(gòu)體stu=fun(st);//將返回的函數(shù)值賦值給新的結(jié)構(gòu)體printf("No.\t\tName\tAge\n");printf("%-16ld%s\t%d\n",stu.num,,stu.age);}【例11-10】用返回結(jié)構(gòu)體類(lèi)型指針的函數(shù)實(shí)現(xiàn)打印學(xué)號(hào)為20050102學(xué)生的全部信息。#defineN3structstu_type{longnum;charname[20];intage;};structstu_type*fun(structstu_typest[])//構(gòu)造一指針類(lèi)的函數(shù){structstu_type*p;inti;p=st;for(i=0;i<N;i++,p++)if(p->num==20050102)return(p);}main(){structstu_typest[N]={{20050101,“wang”,19},{20050102,“l(fā)i”,18},{20050103,“zhao”,20}};structstu_type*ps;ps=fun(st);printf(“No.\t\tName\tAge\n”);printf(“%-16ld%s\t%d\n”,ps->num,ps->name,ps->age);}11.1.8動(dòng)態(tài)內(nèi)存分配與鏈表1.動(dòng)態(tài)內(nèi)存分配和鏈表的概念(1)內(nèi)存分配①固定內(nèi)存分配在C語(yǔ)言中用說(shuō)明語(yǔ)句定義各種存儲(chǔ)類(lèi)型(自動(dòng)、靜態(tài)、寄存器、外部)的變量或數(shù)組,均由系統(tǒng)分配存儲(chǔ)單元,程序員無(wú)法在函數(shù)的執(zhí)行部分干預(yù)存儲(chǔ)單元的分配和釋放。這樣的存儲(chǔ)分配叫固定內(nèi)存分配,又叫系統(tǒng)存儲(chǔ)分配。②動(dòng)態(tài)內(nèi)存分配 C語(yǔ)言允許程序員在函數(shù)執(zhí)行部分使用動(dòng)態(tài)存儲(chǔ)分配函數(shù)開(kāi)辟或回收存儲(chǔ)單元,這樣的存儲(chǔ)分配叫動(dòng)態(tài)內(nèi)存分配。動(dòng)態(tài)內(nèi)存分配使用自由、節(jié)約內(nèi)存。(2)鏈表的概念①結(jié)點(diǎn)組成鏈表的基本存儲(chǔ)單元叫結(jié)點(diǎn),該存儲(chǔ)單元存有若干數(shù)據(jù)和指針,由于存放了不同數(shù)據(jù)類(lèi)型的數(shù)據(jù),它的數(shù)據(jù)類(lèi)型應(yīng)該是結(jié)構(gòu)體類(lèi)型。在結(jié)點(diǎn)的結(jié)構(gòu)體存儲(chǔ)單元中,存放數(shù)據(jù)的域叫數(shù)據(jù)域,存放指針的域叫指針域,簡(jiǎn)單結(jié)點(diǎn)的形式如圖所示。數(shù)據(jù)域指針域結(jié)點(diǎn)類(lèi)型定義的一般形式為:

struct類(lèi)型名

{數(shù)據(jù)域定義;

struct類(lèi)型名*指針域名;

};例如有如下結(jié)點(diǎn)類(lèi)型的定義:

structstudent

{intnum;

floatscore;

structstudent*next;

}②

鏈表若有一些結(jié)點(diǎn),每一個(gè)結(jié)點(diǎn)的指針域存放下一個(gè)結(jié)點(diǎn)的地址,因此就指向下一個(gè)結(jié)點(diǎn),這樣就首尾銜接形成一個(gè)鏈狀結(jié)構(gòu),稱(chēng)為鏈表。用上面的結(jié)構(gòu)體類(lèi)型建立的有4個(gè)結(jié)點(diǎn)的鏈表如圖所示。

(2)鏈表的概念頭結(jié)點(diǎn):指向鏈表中第一個(gè)包含有用數(shù)據(jù)的結(jié)點(diǎn),本身不包含有用數(shù)據(jù),用于對(duì)鏈表的訪問(wèn)。尾結(jié)點(diǎn):不指向其他結(jié)點(diǎn)的結(jié)點(diǎn)。尾結(jié)點(diǎn)的指針域存放的地址為NULL(或0,或'\0')。

(2)鏈表的概念相同點(diǎn):它們均由同類(lèi)型的存儲(chǔ)單元組成。不同點(diǎn):數(shù)組由固定分配的連續(xù)的存儲(chǔ)單元組成,定義后存儲(chǔ)單元不可增加或減少,對(duì)數(shù)組元素的訪問(wèn)為隨機(jī)訪問(wèn)。鏈表可由不連續(xù)的存儲(chǔ)單元(結(jié)點(diǎn))組成,結(jié)點(diǎn)一般為動(dòng)態(tài)分配存儲(chǔ)單元,可隨時(shí)增、刪。只能順序訪問(wèn)鏈表中的結(jié)點(diǎn)。

鏈表與數(shù)組c.data=15;c.next=NULL;

p=head;

while(p!=NULL){printf("%d->",p->data);

p=p->next;

}

printf("NULL\n");

}【例11-11】以三個(gè)結(jié)構(gòu)體變量為結(jié)點(diǎn)建立一個(gè)簡(jiǎn)單的鏈表并輸出。structnode

{intdata;

structnode*next;

};main()

{structnodea,b,c,*head,*p;head=&a;a.data=5;a.next=&b;

b.data=10;b.next=&c;2.C動(dòng)態(tài)存儲(chǔ)分配函數(shù)C動(dòng)態(tài)存儲(chǔ)分配函數(shù)有:malloc、calloc、free、realloc,函數(shù)定義包含在頭文件stdlib.h中。(1)malloc函數(shù)void*malloc(unsignedintsize)調(diào)用形式為:(類(lèi)型*)malloc(size)例如:int*pi;float*pf;pi=(int*)malloc(2);pf=(float*)malloc(4);【例11-12】動(dòng)態(tài)開(kāi)辟一組字符型存儲(chǔ)單元,用于存放字符串,然后輸出。#include"stdlib.h"#include"stdio.h"main(){char*str;if((str=(char*)malloc(50))==NULL){printf("Noenoughmemorytoallocataforthestring.");exit(1);}printf("Inputthestring:");gets(str);printf("Thestringis:%s\n",str);free(str);}(2)calloc函數(shù)void*calloc(unsignedn,unsignedsize)調(diào)用形式為:(類(lèi)型*)calloc(n,size)如:char*ps;ps=(char*)calloc(10,sizeof(char));【例11-13】動(dòng)態(tài)開(kāi)辟可存放100個(gè)float型數(shù)據(jù)的存儲(chǔ)單元。#include"stdlib.h"main(){float*p;p=(float*)calloc(100,sizeof(float));if(p==NULL)printf("Allocationisfailed.\n");elseprintf("Allocationissuccessful.\n");free(p);}(3)realloc函數(shù)void*realloc(void*ptr,unsignednewsize)調(diào)用形式為:(類(lèi)型*)realloc(ptr,newsize)(4)free函數(shù)voidfree(void*)調(diào)用形式為:free(p);其中指針變量p是由malloc、calloc、realloc函數(shù)分配存儲(chǔ)單元存放首地址的指針變量,作用是收回由p指向的動(dòng)態(tài)分配的存儲(chǔ)單元。該函數(shù)無(wú)返回值?!纠?1-14】利用realloc函數(shù)重新分配動(dòng)態(tài)存儲(chǔ)空間。#include"stdlib.h"#include"string.h"#include"stdio.h"main(){char*str;str=(char*)malloc(10);if(!str){printf("Allocationisfailed.\n");exit(1);}printf("Inputthestring:");gets(str);str=(char*)realloc(str,20);if(!str){printf("Allocationisfailed.\n");exit(1);}strcat(str,"**********");printf("Thefinalstringis:%s\n",str);free(str);}3.動(dòng)態(tài)存儲(chǔ)分配鏈表的基本操作由包含一個(gè)指針域的結(jié)點(diǎn)組成的鏈表為單向鏈表。鏈表的基本操作:①建立并初始化鏈表②遍歷訪問(wèn)鏈表(包括查找、輸出結(jié)點(diǎn)等)③刪除鏈表中的結(jié)點(diǎn)④在鏈表中插入結(jié)點(diǎn)(1)建立單向鏈表建立單向鏈表的步驟如下:①建立頭結(jié)點(diǎn)(或定義頭指針變量);②讀取數(shù)據(jù);③生成新結(jié)點(diǎn);④將數(shù)據(jù)存入結(jié)點(diǎn)的數(shù)據(jù)域中;⑤將新結(jié)點(diǎn)連接到鏈表中(將新結(jié)點(diǎn)地址賦給上一個(gè)結(jié)點(diǎn)的指針域)。⑥重復(fù)步驟②~⑤,直到輸入結(jié)束?!纠?1-15】建立帶有頭結(jié)點(diǎn)的單向鏈表,當(dāng)輸入-1時(shí)結(jié)束。#include<stdio.h>structnode{intdata;structnode*next;};main(){intx;structnode*h,*s,*r;h=(structnode*)malloc(sizeof(structnode));r=h;scanf("%d",&x);while(x!=-1)

{s=(structnode*)malloc(sizeof(structnode));s->data=x;r->next=s;r=s;scanf("%d",&x);

}r->next=NULL;}(2)輸出鏈表輸出鏈表即順序訪問(wèn)鏈表中各結(jié)點(diǎn)數(shù)據(jù)域,方法是:從頭結(jié)點(diǎn)開(kāi)始,不斷讀取數(shù)據(jù)和下移指針變量,直到尾結(jié)點(diǎn)為止?!纠?1-16】編寫(xiě)單向鏈表的輸出函數(shù)。voidprint_slist(structnode*h)

{structnode*p;p=h->next;if(p==NULL)printf("Linklistisnull!\n");else{printf("head");while(p!=NULL){printf("->%d",p->data);p=p->next;}printf("->end\n");

}

}(3)刪除單向鏈表中的一個(gè)結(jié)點(diǎn)刪除單向鏈表中一個(gè)結(jié)點(diǎn)的方法步驟如下:①找到要?jiǎng)h除結(jié)點(diǎn)的前驅(qū)結(jié)點(diǎn);②將要?jiǎng)h除結(jié)點(diǎn)的后繼結(jié)點(diǎn)的地址賦給要?jiǎng)h除結(jié)點(diǎn)的前驅(qū)結(jié)點(diǎn)的指針域;③將要?jiǎng)h除結(jié)點(diǎn)的存儲(chǔ)空間釋放?!纠?1-17】編寫(xiě)函數(shù),在單向鏈表中刪除值為x的結(jié)點(diǎn)voiddelete_node(structnode*h,intx)

{structnode*p,*q;

q=h;p=h->next;if(p!=NULL)

{while((p!=NULL)&&(p->data!=x)){q=p;p=p->next;}if(p->data==x)

{q->next=p->next;free(p);}

}

}(4)在單向鏈表的某結(jié)點(diǎn)前插入一個(gè)結(jié)點(diǎn)在單向鏈表的某結(jié)點(diǎn)前插入一個(gè)結(jié)點(diǎn)的步驟如下:①開(kāi)辟一個(gè)新結(jié)點(diǎn)并將數(shù)據(jù)存入該結(jié)點(diǎn)的數(shù)據(jù)域;②找到插入點(diǎn)結(jié)點(diǎn);③將新結(jié)點(diǎn)插入到鏈表中:將新結(jié)點(diǎn)的地址賦給插入點(diǎn)上一個(gè)結(jié)點(diǎn)的指針域,并將插入點(diǎn)的地址存入新結(jié)點(diǎn)的指針域【例11-18】編寫(xiě)函數(shù),在單向鏈表中值為x的結(jié)點(diǎn)前插入值為y的結(jié)點(diǎn),若值為x的結(jié)點(diǎn)不存在,則插在表尾。分析:本例結(jié)合了查找和插入兩種功能,可能遇到三種情況:①鏈表非空,值為x的結(jié)點(diǎn)存在,則插在值為x的結(jié)點(diǎn)之前;②鏈表非空,值為x的結(jié)點(diǎn)不存在,則插在表尾;③鏈表為空,也相當(dāng)于值為x的結(jié)點(diǎn)不存在,則插在表尾。函數(shù)編寫(xiě)如下:

voidinsert_node(structnode*h,intx,inty)

{structnode*s,*p,*q;s=(structnode*)malloc(sizeof(structnode));s->data=y;/*向新結(jié)點(diǎn)存入數(shù)據(jù)*/q=h;p=h->next;/*工作指針初始化,p指向第一個(gè)結(jié)點(diǎn)*/while((p!=NULL)&&(p->data!=x))

{q=p;p=p->next;}/*p、q下移,q指向p的前趨結(jié)點(diǎn)*/q->next=s;s->next=p;

}11.2共用體

11.2.1共用體類(lèi)型的定義C語(yǔ)言允許在一個(gè)存儲(chǔ)單元中(先后)存放不同類(lèi)型的數(shù)據(jù),或者在該存儲(chǔ)單元中以某種類(lèi)型存放數(shù)據(jù)卻以另外的類(lèi)型訪問(wèn)該數(shù)據(jù),這種特殊的數(shù)據(jù)類(lèi)型就叫做“共用體”類(lèi)型,其定義形式:union類(lèi)型名{成員項(xiàng)表列};例如:unionexam/*共用體類(lèi)型名*/

{inta;

floatb;

charc;};11.2.2共用體變量的定義三種方式:1.先定義共用體類(lèi)型,再用該類(lèi)型定義共用體變量union類(lèi)型名{成員表列};union類(lèi)型名變量名表;例如用unionexam類(lèi)型定義共用體變量x、y:unionexamx,y;2.定義共用體類(lèi)型名的同時(shí)定義共用體變量union類(lèi)型名{成員表列;}變量名表;unionexam

{inta;

floatb;

charc;}x,y;例如3.不定義類(lèi)型名直接定義共用體變量形式為:union

{成員表列}變量名表;

定義共用體變量后,系統(tǒng)為共用體變量開(kāi)辟存儲(chǔ)單元。由于共用體變量先后存放不同類(lèi)型的成員,系統(tǒng)開(kāi)辟的共用體變量的存儲(chǔ)單元的字節(jié)數(shù)為最長(zhǎng)的成員需要字節(jié)數(shù)。如對(duì)上面定義的共用體類(lèi)型unionexam或變量x,表達(dá)式sizeof(unionexam)和sizeof(x)的值均為4。另外,先后存放的各成員首地址都相同,即共用體變量、共用體變量的所有成員它們的首地址都相同。

11.2.3共用體變量的引用1.共用體變量的引用引用共用體變量的要點(diǎn)如下:(1)一般只能引用共用體變量的成員而不能整體引用共用體變量,盡管它同時(shí)只有一個(gè)成員有值。共用體變量的一個(gè)基本類(lèi)型成員相當(dāng)于一個(gè)普通變量,可參與該成員所屬數(shù)據(jù)類(lèi)型的一切運(yùn)算。例如對(duì)上面定義的共用體變量x可以先后引用的成員有:x.a、x.b和x.c,它們都相當(dāng)于一個(gè)普通變量。1.共用體變量的引用(2)同一類(lèi)型的共用體變量可相互賦值。例如有賦值語(yǔ)句x.a=3;共用體變量x有值,則可有下面的賦值語(yǔ)句:y=x;這樣y.a的值也為3。(3)在賦值和輸入輸出方面也與結(jié)構(gòu)體類(lèi)似,即:不允許對(duì)共用體變量名(整體)賦(常數(shù))值;共用體輸入和輸出也只能對(duì)共用體變量成員進(jìn)行,不允許直接對(duì)共用體變量進(jìn)行輸入和輸出,盡管它同時(shí)只存有一個(gè)成員!2.共用體的應(yīng)用(1)變體記錄問(wèn)題【例11-19】輸入N個(gè)人的信息,共同的信息有:姓名、性別,另外,職業(yè)(job)為教師('t')則登記其單位(group),職業(yè)為學(xué)生('s')則登記其班級(jí)(class),最后將信息輸出。程序如下:#defineN2

main()

{struct

{charname[20];

charsex;

charjob;

union

{intclass;

chargroup[20];

}category;}person[N];inti;printf("Enter%dperson

informations:\n",N);for(i=0;i<N;i++)

{gets(person[i].name);

scanf("%c",&person[i].sex);

scanf("%c",&person[i].job);

getchar();【例11-19】if(person[i].job=='s')

scanf("%d",&person[i].category.class);if(person[i].job=='t')

scanf("%s",person[i].category.group);getchar();

}printf("Name\tSex\tJob\tGroup/Class\n");for(i=0;i<N;i++)

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

printf("%-8s%c\t%c\t%d\n",person[i].name,person[i].sex,

person[i].job,person[i].category.class);if(person[i].job=='t')

printf("%-8s%c\t%c\t%s\n",person[i].name,person[i].sex,

person[i].job,person[i].category.group);

}【例11-19】程序運(yùn)行情況如圖所示: (2)將內(nèi)存空間的內(nèi)容拆分成幾部分使用【例11-20】運(yùn)行下面的程序,分析運(yùn)行結(jié)果。main(){uniondata{inta;charc[2];}u;printf("Enteru.ainHex:\n");scanf("%x",&u.a);printf("u.c[0]=%c,u.c[1]=%c\n",u.c[0],u.c[1]);}11.3枚舉類(lèi)型枚舉類(lèi)型:以用戶定義的一組標(biāo)識(shí)符為常量的類(lèi)型。11.3.1枚舉類(lèi)型的定義枚舉類(lèi)型定義的形式為:enum

類(lèi)型名{標(biāo)識(shí)符序列};例如定義枚舉類(lèi)型color_name,它由5個(gè)枚舉值組成:enumcolor_name{red,yellow,blue,white,black};【說(shuō)明】(1)enum是定義枚舉類(lèi)型的關(guān)鍵字。

(2)枚舉值標(biāo)識(shí)符是常量不是變量,系統(tǒng)自動(dòng)給予它們0,1,2,3…值,因此枚舉類(lèi)型是基本數(shù)據(jù)類(lèi)型。

(3)枚舉值只能是一些標(biāo)識(shí)符(字母開(kāi)頭,字母、數(shù)字和下劃線組合),不能是基本類(lèi)型常量。雖然它們有值0,1,2,3…,但如果這樣定義類(lèi)型:

enumcolor_name{0,1,2,3,4};是錯(cuò)誤的。(4)可在定義枚舉類(lèi)型時(shí)對(duì)枚舉常量重新定義值,如:

enumcolor_name{red=3,yellow,blue,white=8,black};此時(shí)yellow為4,blue為5,black為9,即系統(tǒng)自動(dòng)往后延續(xù)。

11.3.2枚舉變量的定義及引用1.枚舉變量的說(shuō)明①用定義過(guò)的枚舉類(lèi)型來(lái)定義枚舉變量,形式為:enum類(lèi)型名變量名表;例如定義枚舉類(lèi)型color_name的變量color:enumcolor_namecolor;②在定義類(lèi)型的同時(shí)定義變量,形式為:enum類(lèi)型名{標(biāo)識(shí)符序列}變量名表;例如定義枚舉類(lèi)型color_name的變量color:enumcolor_name{red,yellow,blue,white,black}color;③省略類(lèi)型名直接定義變量,形式為:enum{標(biāo)識(shí)符序列}變量名表;2.枚舉變量的引用(1)枚舉變量定義以后就可以對(duì)它賦枚舉常量值或者其對(duì)應(yīng)的整數(shù)值,例如變量color可以賦5個(gè)枚舉值之一:color=red;或color=0;color=blue;或color=2;但color=green;或color=10;均不合法,因?yàn)間reen不是枚舉值,而10已超過(guò)枚舉常量對(duì)應(yīng)的內(nèi)存值。(2)因枚舉常量對(duì)應(yīng)整數(shù)值,因此枚舉變量、常量和常量對(duì)應(yīng)的整數(shù)之間可以比較大小,如:if(color==red)printf("red");或if(color==0)printf("red");if(color!=black)printf("Thecolorisnotblack!");if(color>white)printf("Itisblack.");(3)枚舉變量還可以進(jìn)行++、--等運(yùn)算。(4)枚舉變量不能通過(guò)scanf或gets函數(shù)輸入枚舉常量標(biāo)識(shí)符,只能通過(guò)賦值取得枚舉常量值。但是枚舉變量可以通過(guò)scanf("%d",&枚舉變量);輸入枚舉常量對(duì)應(yīng)的整數(shù)值。(5)枚舉變量和枚舉常量可以用printf(“%d”,…);輸出對(duì)應(yīng)的整數(shù)值,若想輸出枚舉值字符串,則只能間接進(jìn)行,如:

color=red;

if(color==red)printf("red");由于枚舉變量可以作為循環(huán)變量,因此可以利用循環(huán)和switch語(yǔ)句打印全部的枚舉值字符串?!纠?1-21】輸出全部的枚舉值字符串main(){enum{red,yellow,blue,white,black}color;printf("Allenumstringsare:\n");for(color=red;color<=black;color++)switch(color){casered:printf("red\n");break;caseyellow:printf("yellow\n");break;caseblue:printf("blue\n");break;casewhite:printf("white\n");break;caseblack:printf("black\n");break;}}11.3.3枚舉類(lèi)型的應(yīng)用【例9-22】輸入星期幾的整數(shù),輸出“工作日”或“休息日”的信息。main(){enumday{mon=1,tue,wed,thu,fri,sat,sun}x;printf("Inputainteger:\n");scanf("%d",&x);switch(x){casemon:casetue:casewed:casethu:casefri:printf("Workday\n");break;casesat:casesun:printf("Restday\n");break;default:printf("Inputerror!\n");}}11.4用戶定義類(lèi)型1.定義“替代”類(lèi)型名typedef類(lèi)型名標(biāo)識(shí)符;注意:“類(lèi)型名”必須是系統(tǒng)提供的數(shù)據(jù)類(lèi)型或用戶已定義的數(shù)據(jù)類(lèi)型。作用:給已有類(lèi)型起個(gè)別名標(biāo)識(shí)符,例如:typedefintINTEGER;2.定義“構(gòu)造”類(lèi)型名typedef類(lèi)型名標(biāo)識(shí)符及“構(gòu)造”;注意:“類(lèi)型名”必須是系統(tǒng)提供的數(shù)據(jù)類(lèi)型或用戶已定義的數(shù)據(jù)類(lèi)型。作用:自己定義新“構(gòu)造”類(lèi)型名標(biāo)識(shí)符。舉例(1)定義字符型指針類(lèi)型名CHARPtypedefchar*CHARP;以后可用它來(lái)定義指針變量,例如:CHARPp,q;即等價(jià)于:char*p,*q;(2)定義具有3個(gè)元素的整型數(shù)組名NUMtypedefintNUM[3];以后可用它來(lái)定義有三個(gè)元素的int型數(shù)組,如:NUMa,b,c;就相當(dāng)于inta[3],b[3],c[3];(3)定義某結(jié)構(gòu)體類(lèi)型名STUDENTtypedefstruct

{intnum;

charname[10];

charsex;

floatscore[3];

}STUDENT;以后可用它來(lái)定義該種結(jié)構(gòu)體類(lèi)型變量、指針變量等,例如:STUDENTstu1,stu2,*st;

就定義了該結(jié)構(gòu)體類(lèi)型的變量和指針變量。舉例3.定義新類(lèi)型名的一般步驟及說(shuō)明(1)先按定義變量或數(shù)組的方法寫(xiě)出定義;如:chara[10];(2)將定義的名字換成新類(lèi)型名;如:charNAME[10];(3)在前面加上typedef;如:typedefcharNAME[10];(4)然后可以用新類(lèi)型名定義變量;如:NAMEc,d;c、d即是有10個(gè)元素的字符數(shù)組11.5程序舉例【例11-23】有5個(gè)學(xué)生,每個(gè)學(xué)生的信息有學(xué)號(hào)、姓名和三門(mén)課的成績(jī),求每個(gè)學(xué)生的平均成績(jī)并按平均成績(jī)從大到小對(duì)所有學(xué)生的信息進(jìn)行排序然后輸出。分析:在定義結(jié)構(gòu)體類(lèi)型時(shí)可以設(shè)計(jì)一個(gè)存放平均成績(jī)的成員,排序交換位置時(shí)應(yīng)將結(jié)構(gòu)體數(shù)組元素整體交換,編程如下:【例11-23】main()

{structstudent

{longnum;

charname[10];

intscore[3];

floatevr;

}t,st[5]={{1001,"wang",67,75,88},{1002,"li",83,92,95},

{1003,"zhao",56,82,79},{1004,"han",78,87,79},

{1005,"qian",69,79,81}};inti,j;for(i=0;i<5;i++)

{st[i].evr=0;

for(j=0;j<3;j++)

st[i].evr+=st[i].score[j];st[i].evr/=3;}

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

for(j=i+1;j<5;j++)

if(st[i].evr<st[j].evr){t=st[i];st[i]=st[j];st[j]=t;}printf("No.Namescor1scor2score3evr\n");for(i=0;i<5;i++)

{printf("%ld%8s",st[i].num,st[i].name);for(j=0;j<3;j++)printf("%8d",st[i].score[j]);printf("%8.1f\n",st[i].evr);

}

}【例11-23】【例11-24】有5個(gè)學(xué)生,每個(gè)學(xué)生的信息有學(xué)號(hào)、姓名和三門(mén)課的成績(jī),輸出三門(mén)課的總平均分以及所有成績(jī)中最高成績(jī)所對(duì)應(yīng)學(xué)生的全部信息?!痉治觥咳T(mén)課的總平均分可以定義一個(gè)數(shù)組,找出最高成績(jī)時(shí)應(yīng)記錄是哪個(gè)學(xué)生才能輸出該學(xué)生的全部信息,編程如下:main()

{structstudent

{longnum;

charname[10];

intscore[3];

}st[5]={{1001,"wang",67,75,88},{1002,"li",83,92,95},

{1003,"zhao",56,82,79},{1004,"han",78,87,79},

{1005,"qian",69,79,81}};inti,j,max,maxi;

floataver[3]={0};for(j=0;j<3;j++)

{for(i=0;i<5;i++)

aver[j]+=st[i].score[j];

aver[j]/=5;

}

max=st[0].score[0];for(i=0;i<5;i++)

for(j=0;j<3;j++)

if(st[i].score[j]>max){max=st[i].score[j];maxi=i;}printf("Theaveragesofcoursesare:\n");for(i=0;i<3;i++)printf("%6.1f",aver[i]);printf("\n");printf("Theinformationsofthestudentwithmaximalscore:\n");printf("No.Namescor1scor2score3\n");printf("%ld%8s",st[maxi].num,st[maxi].name);for(j=0;j<3;j++)printf("%8d",st[maxi].score[j]);

printf("\n");

}【例11-25】已知單向鏈表的結(jié)點(diǎn)類(lèi)型為structnode,頭指針為head,編

溫馨提示

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