C程序設(shè)計:CH11 結(jié)構(gòu)體與共同體_第1頁
C程序設(shè)計:CH11 結(jié)構(gòu)體與共同體_第2頁
C程序設(shè)計:CH11 結(jié)構(gòu)體與共同體_第3頁
C程序設(shè)計:CH11 結(jié)構(gòu)體與共同體_第4頁
C程序設(shè)計:CH11 結(jié)構(gòu)體與共同體_第5頁
已閱讀5頁,還剩36頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第十一章結(jié)構(gòu)體與共同體本章要點:1.掌握結(jié)構(gòu)和聯(lián)合類型數(shù)據(jù)的定義方法和引用方法;2.掌握鏈表處理──結(jié)構(gòu)指針的應(yīng)用3.了解枚舉類型數(shù)據(jù)的定義方法和引用方法。11.1概述有時,需將不同類型的數(shù)據(jù)組合成一個有機的整體,以便于引用。這些數(shù)據(jù)是相互聯(lián)系的。如一個學(xué)生的有關(guān)信息:可采用結(jié)構(gòu)體數(shù)據(jù)結(jié)構(gòu)描述上述信息。例如:structstudent{intnum;charname[20];charsex;

intage;charaddr[30];};定義一個結(jié)構(gòu)體類型的一般形式為:struct

結(jié)構(gòu)體名{成員表列};對各成員都要進行類型說明;成員名定名規(guī)則與變量名同。是類型,不是變量名,但是由用戶自己指定11.2定義結(jié)構(gòu)體類型變量的方法方法一:先定義結(jié)構(gòu)體類型再定義變量名structstudent{intnum;charname[20];charsex;

intage;charaddr[30];};structstudentstudent1,student2;定義studet1和sudent2為structstudent類型變量不能只指定一個變量為“struct型”而不指定結(jié)構(gòu)體名有時,可用符號常量代表一個結(jié)構(gòu)體類型,如:#defineSTUDENT

structstudentSTUDENT{intnum;charname[20];charsex;

intage;charaddr[30];};這樣,可直接用STUDENT定義變量,如:STUDENTstudent1,student2;此時,不必再寫關(guān)鍵字struct方法二:在定義類型的同時定義變量,如:structstudent{intnum;charname[20];charsex;

intage;charaddr[30];}student1,student2;一般形式是:struct

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

{

成員表列

}變量名表列;方法三:直接定義結(jié)構(gòu)類型變量。其一般形式是:struct{

成員表列

}變量名表列;此時,不出現(xiàn)結(jié)構(gòu)體名幾點說明:1.

類型與變量是不同概念,不要混淆;2.

結(jié)構(gòu)體中的成員,可以單獨使用,其作用與地位相當(dāng)于普通變量;3.

成員也可以是一個結(jié)構(gòu)體變量;例如:structdate{intmonth;

intday;

intyear;};structstudent{intnum;charname[20];intage;structdatebirthday;}student1,student2;4.

成員名可以與程序中的變量名相同,二者不代表同一對象。11.3結(jié)構(gòu)體類型變量的引用規(guī)則:1.

不能將一個結(jié)構(gòu)體變量作為一個整體進行賦值和輸出;只能對其各個成員分別輸出(引用形式為:結(jié)構(gòu)體變量名.成員名)。printf(“%d%s%d%f”,student1);printf(“%d”,student1.num);輸出10010錯!正確!2.若成員本身又屬一個結(jié)構(gòu)體類型,只能對最低級的成員進行賦值或存取以及運算。如:student1.birthday.year

(續(xù))(接上片)3.

對成員變量可以象普通變量一樣進行各種運算,如:

sumage=student1.age+student2.age;4.

可以引用成員的地址,也可以引用結(jié)構(gòu)體變量的地址,如

scanf(“%d”,&student1.num);printf(“%o”,&student1);scanf(“%d,%s,%c,%d,%s”,&student1);錯!輸入student1.num的值輸出student1的首地址11.4結(jié)構(gòu)體變量的初始化

structstudent{longintnum;charname[20];charsex;charaddr[20];}a={9801,”Wanghong”,’W’,”2LinggongRoad”};main(){printf(“No.:%ld\nname:%s\nsex:%c\naddress:%s\n”,a.num,,a.sex,a.addr);}運行結(jié)果為:No.:9801name:Wanghongsex:Waddress:2LinggongRoad11.5結(jié)構(gòu)體數(shù)組

(每個數(shù)組元素都是一個結(jié)構(gòu)體類型的數(shù)據(jù))(一)結(jié)構(gòu)體數(shù)組的定義,如structstudent{intnum;charname[20];charsex;

intage;charaddr[30];};

structstudentstu[3];也可直接定義,如structstudent{intnum;…}stu[3];或struct{intnum;…}stu[3];(二)結(jié)構(gòu)體數(shù)組的初始化structstudent{intnum;charname[20];charsex;intage;charaddr[30];}stu[3]={{111,”Li”,’M’,18,”Dalian”},{…},{…}};也可采用:structstudent{intnum;…};

structstudentstu[]={{…},{…},{…}};結(jié)構(gòu)體數(shù)組的初始化的一般形式是在定義數(shù)組后面加上:={初值表列};例題:設(shè)有三個候選人,每次輸入一個得票的候選人的名字,要求最后輸出各人得票結(jié)果。structperson{charname[20];

intcount;}leader[3]={“Li”,0,”zhang”,0,”Liu”,0};main(){inti,j;charleader_name[20];for(i=1;i<=10;i++){scanf(“%s”,leader_name);for(j=0;j<3;j++)

if(strcmp(leader_name,leader[j].name)==0)leader[j].count++);}for(i=0;i<3;i++)printf(“%5s:%d\n”,leader[i].name,leader[i].count);}在下面結(jié)構(gòu)數(shù)組的定義中,不正確的是()。A)structstudent{intno;charname[10];floatscore;}

structstudentstud[100];B)structstud[100]{int

no;charname[10];floatscore;}C)structstudent{intno;charname[10];floatscore;}stud[100];D)struct

{intno;charname[10];floatscore;}stud[10];11.6指向結(jié)構(gòu)體類型數(shù)據(jù)的指針結(jié)構(gòu)體變量的指針:是該結(jié)構(gòu)體變量所占居的內(nèi)存段的起始地址。例如:main(){structstudent{longintnum;charname[20];charsex;};structstudentstu_1;structstudent*p;p=&stu_1;stu.num=9901;strcpy(stu_1.name,”LiMin”);stu_1.sex=‘W’;printf(“No.:%ld\nname%s\nsex:%c\n”,stu_1.num,stu_1.name,stu_1.sex);printf(“\nNo.:%ld\nname%s\nsex:%c\n”,(*p).num,(*p).name,(*p).sex);}引用結(jié)構(gòu)體成員的三種形式:結(jié)構(gòu)體變量名.成員名(*p).成員名p->成員名指向運算符。其優(yōu)先級高于自增、自減運算符試分析以下運算:p->n

得到p指向的結(jié)構(gòu)體變量中的成員n的值p->n++

得到p指向的結(jié)構(gòu)體變量中的成員n的值,用完后使它加1;->優(yōu)先級高于++++p->n得到p指向的結(jié)構(gòu)體變量中的成員n的值使其先加1如:p->n=3;則p->n++=?++p->n=?下列程序正確的運行結(jié)果為【21】。 structs { intn; int*m; }*p; intd[5]={10,20,30,40,50}; structsarr[5]= {100,&d[0],200,&d[1],300,&d[2],400,&d[3],500,&d[4]};#include<stdio.h> main() { p=arr; printf("%d\n",++p->n); printf("%d\n",(++p)->n); printf("%d\n",++(*p->m));}

11.8共用體11.8.1共用體的概念共用體:使幾個不同的變量共占同一段內(nèi)存的結(jié)構(gòu),稱為“共用體”類型的結(jié)構(gòu)?!肮灿皿w”類型變量的定義形式為:union共用體名

{成員表列

}變量表列;

例如:uniondata{inti;charch;floatf;}a,b,c;或uniondata{inti;charch;floatf;};uniondataa,b,c;或union{inti;charch;floatf;}a,b,c;直接定義先定義類型注意共用體類型變量與結(jié)構(gòu)體類型變量的區(qū)別結(jié)構(gòu)體類型變量所占內(nèi)存長度是各成員占的內(nèi)存長度之和。共用體類型變量所占內(nèi)存長度等于最長的成員的長度。下列程序的輸出結(jié)果為()。main(){structdate{intyear,month,day;}today;union{longi;intk;charch;}mix;

printf("%d,",sizeof(structdate));

printf("%d",sizeof(mix));}A)6,2B)6,4C)8,4D)8,6)下列程序的輸出結(jié)果為()。#include<string.h>main(){voidfunc();

structdate{

inta;chars[5];}arg;

arg.a=27;

strcpy(arg.s,"abcd");

func(&arg.a,arg.s);

printf("arg.a=%d,arg.s=%s\n",arg.a,arg.s);}voidfunc(int*x,chars1[]){*x-=5;strcpy(s1,"ABCD");}A)arg.a=22,arg.s=ABCDB)arg.a=27,arg.s=abcdC)arg.a=22,arg.s=abcdD)arg.a=27,arg.s=ABCD11.8.2共用體變量的引用方式注意:只能引用共用體變量中的成員,不能引用共用體變量本身。如:可以引用

a.i(引用共用體變量中的整型變量i)

a.ch(引用共用體變量中的字符變量ch)

a.f(引用共用體變量中的實型變量f)不能只引用共用體變量,如:

printf(“%d”,a);錯啦!11.8.3共用體類型數(shù)據(jù)的特點1.每一瞬時只有一個成員起作用;2.

共用體變量中起作用的成員是最后一次存放的成員;3.共用體變量的地址和它的各成員的地址都是同一地址;4.不能對共用體變量名賦值,也不能企圖引用變量名來得到成員的值,又不能在定義共用體變量時對它初始化。5.

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

共用體類型可以出現(xiàn)在結(jié)構(gòu)體類型定義中,也可以定義共用體數(shù)組。而結(jié)構(gòu)體也可以出現(xiàn)在共用體類型定義中,數(shù)組也可以作為共用體的成員。設(shè)有一聯(lián)合體變量定義如下: uniondata { longw; floatx; inty; charz; };uniondatabeta;執(zhí)行下面賦值語句后,正確的聯(lián)合體變量beta的值是【36】。

beta.w=123456; beta.y=888;

beta.x=3.1416; beta.z='*';(A)123456 (B)888 (C)3.1416 (D)'*'

11.9枚舉類型若一個變量只有幾種可能的值,可以定義為枚舉類型。所謂“枚舉”是指將變量的值一一列舉出來,變量的值只限于列舉出來的值的范圍內(nèi)。定義方法:先定義枚舉類型

enumweekday{sun,mon,tue,wed,thu,fri,sat};再用此類型定義變量,如:enumweekdayworkday,week_end;或直接定義枚舉變量。如:enumweekday{sun,mon,tue,wed,thu,fri,sat}workday,week_end;說明:枚舉元素為常量,不是變量,故不能對它們賦值枚舉常量有值。如上面定義中,sun、mon

、tue······sat的值依次為0、1、2······7也可改變枚舉元素的值,在定義時指出,如:

enum

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

則tue=2,wed=3,…..接著mon開始遞增編號。枚舉值可用來作判斷比較,如:

if(workday==mon)if(workday>sun)一個整數(shù)不能直接賦值給一個枚舉變量,應(yīng)先進行強制類型轉(zhuǎn)換才能賦值,如:

workday=(enumweekday)2;(相當(dāng)于將序號為2的枚舉元素值賦給workday,即:workday=tue;設(shè)有如下枚舉類型定義:enum

color{red=3,yellow,blue=10,white,black};其中枚舉量black的值是【39】。

(A)7 (B)15

(C)12 (D)14設(shè)定義星期的枚舉類型變量如下:

enumworkday{mon,tue,wed,thu,fri};

enumworkdaydate1,date2;則下面錯誤的賦值語句是:【31】。

A)date1=0 B)date2=mon

C)date1=date2 D)date1=fri

2個函數(shù)定義malloc函數(shù)其函數(shù)原型為void*malloc(unsigned

intsize);其作用是在內(nèi)存的動態(tài)存儲區(qū)中分配一個長度為size的連續(xù)空間。此函數(shù)的值(即“返回值”)是一個指向分配域起始地址的指針(類型為void)。如果此函數(shù)未能成功地執(zhí)行(例如內(nèi)存空間不足),則返回空指針(NULL)。如:malloc(4);(2)calloc函數(shù)其函數(shù)原型為void*calloc(unsignedn,unsignedsize);其作用是在內(nèi)存的動態(tài)存儲區(qū)中分配n個長度為size的連續(xù)空間。函數(shù)返回一個指向分配域起始地址的指針;如果分配不成功,返回NULL。用calloc函數(shù)可以為一維數(shù)組開辟動態(tài)存儲空間,n為數(shù)組元素個數(shù),每個元素長度為sizecalloc(64,16):開辟64個長度為16字節(jié)的連續(xù)存儲空間,共占1K字節(jié)。(3)free函數(shù)其函數(shù)原型為voidfree(void*p);其作用是釋放由p指向的內(nèi)存區(qū),使這部分內(nèi)存區(qū)能被其他變量使用。p是最近一次調(diào)用calloc或malloc函數(shù)時返回的值。free函數(shù)無返回值.

§11.7用指針處理鏈表

11.7.1鏈表概述鏈表是一種常見的重要的數(shù)據(jù)結(jié)構(gòu),是動態(tài)地進行存儲分配的一種結(jié)構(gòu)。鏈表的組成:頭指針:存放一個地址,該地址指向一個元素

結(jié)點:用戶需要的實際數(shù)據(jù)和鏈接節(jié)點的指針圖11-10§11.7用指針處理鏈表

用結(jié)構(gòu)體建立鏈表:

struct

student{int

num;

float

score;

struct

student*next;};

其中成員num和score用來存放結(jié)點中的有用數(shù)據(jù)(用戶需要用到的數(shù)據(jù)),next是指針類型的成員,它指向structstudent類型數(shù)據(jù)(這就是next所在的結(jié)構(gòu)體類型)圖11-11§11.7用指針處理鏈表

11.7.2簡單鏈表

#include<stdio.h>

#defineNULL0

structstudent

{longnum;floatscore;structstudent*next;};

main()

{structstudenta,b,c,*head,*p;

a.num=99101;a.score=89.5;

b.num=99103;b.score=90;

c.num=99107;c.score=85;

head=&a;a.next=&b;b.next=&c;

c.next=NULL;p=head;

do{printf("%ld%5.1f\n",p->num,p->score);

p=p->next;}while(p!=NULL);

}運行結(jié)果:1010189.51010390.01010785.0§11.7建立動態(tài)鏈表建立鏈表的函數(shù)如下:

#include<stdio.h>#include<malloc.h>#defineNULL0//令NULL代表0,用它表示“空地址#defineLENsizeof(structstudent)//令LEN代表struct//student類型數(shù)據(jù)的長度

structstudent{longnum;floatscore;structstudent*next;};intn;//n為全局變量,本文件模塊中各函數(shù)均可使用它§11.7用指針處理鏈表

structstudent*creat(){structstudent*head;structstudent*p1,*p2;n=0;

p1=p2=(structstudent*)malloc(LEN);scanf("%ld,%f",&p1->num,&p1->score);head=NULL;while(p1->num!=0){

n=n+1; if(n==1)head=p1; elsep2->next=p1;

p2=p1; p1=(structstudent*)malloc(LEN); scanf("%ld,%f",&p1->num,&p1->score); }p2->next=NULL;return(head);}§

11.7.6對鏈表的刪除操作從一個動態(tài)鏈表中刪去一個結(jié)點,并不是真正從內(nèi)存中把它抹掉,而是把它從鏈表中分離開來,只要撤銷原來的鏈接關(guān)系即可。圖11-19P2if(p1==head)head=p1->next;elsep2->next=p1->next;P1刪除結(jié)點的函數(shù)del:structstudent*del(structstudent*head,longnum){structstudent*p1,*p2;if(head==NULL){printf("\nlistnull!\n");return;} p1=head;

while(num!=p1->num&&p1->next!=NULL){p2=p1;p1=p1->next;}

if(num==p1->num) {if(p1==head)head=p1->next; elsep2->next=p1->next;

printf("delete:%ld\n",num); n=n-1; } elseprintf("%ldnotbeenfound!\n",num);

return(head);}

11.7.7對鏈表的插入操作

對鏈表的插入是指將一個結(jié)點插入到一個已有的鏈表中。為了能做到正確插入,必須解決兩個問題:①怎樣找到插入的位置;②怎樣實現(xiàn)插入。

圖11-19P2P0P1P2->next=P0->next;P0->nex

溫馨提示

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

評論

0/150

提交評論