第9 結構體與共用體_第1頁
第9 結構體與共用體_第2頁
第9 結構體與共用體_第3頁
第9 結構體與共用體_第4頁
第9 結構體與共用體_第5頁
已閱讀5頁,還剩43頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

會計學1第9結構體與共用體29.2結構體結構體:一種構造數據類型用途:把不同類型的數據組合成一個整體-------自定義數據類型結構體類型定義struct[結構體名]{

類型標識符成員名;類型標識符成員名;

…………….};成員類型可以是基本型或構造型struct是關鍵字,不能省略合法標識符可省:無名結構體第1頁/共48頁3例

struct

student{intnum;charname[20];charsex;intage;floatscore;charaddr[30];};namenumsexagescoreaddr2字節(jié)2字節(jié)20字節(jié)1字節(jié)4字節(jié)30字節(jié)……..結構體類型定義描述結構的組織形式,不分配內存結構體類型定義的作用域例子圖解第2頁/共48頁4先定義結構體類型,再定義結構體變量一般形式:struct結構體名{

類型標識符成員名;類型標識符成員名;

…………….};struct結構體名變量名表列;

結構體變量的定義例structstudent{intnum;charname[20];charsex;intage;floatscore;charaddr[30];};structstudentstu1,stu2;結構體變量定義結構體類型定義第3頁/共48頁5一般形式:struct結構體名{

類型標識符成員名;類型標識符成員名;

…………….}變量名表列;例structstudent{intnum;charname[20];charsex;intage;floatscore;charaddr[30];}stu1,stu2;定義結構體類型的同時定義結構體變量結構體類型定義結構體變量stu1,stu2定義第4頁/共48頁6一般形式:struct{

類型標識符成員名;類型標識符成員名;

…………….}變量名表列;例struct{intnum;charname[20];charsex;intage;floatscore;charaddr[30];}stu1,stu2;用無名結構體直接定義變量只能一次直接定義結構體變量

第5頁/共48頁7結構體類型與結構體變量概念不同:類型:不分配內存;

變量:分配內存類型:不能賦值、存取、運算;變量:可以結構體可嵌套結構體成員名與程序中變量名可相同,不會混淆結構體類型及變量的作用域與生存期說明:第6頁/共48頁8具有嵌套結構的結構體類型

structdate{intyear;intmonth;intday;};structstudent1{intnumber;charname[8];charsex;

structdatebirthday;floatscore;};structstudent1a;/*定義變量a

*/a.number=200801;="heli";a.sex=m;a.birthday.year=1990a.birthday.month=1990a.birthday.day=1990a.score=92;第7頁/共48頁9引用規(guī)則結構體變量不能整體引用,只能引用變量成員可以將一個結構體變量賦值給另一個結構體變量結構體嵌套時逐級引用成員(分量)運算符優(yōu)先級:1結合性:從左向右引用方式:結構體變量名.成員名結構體變量的引用例:在上例中

stu1.sex=m;stu1.score=87.5;例:在上例中

stu2=stu1;第8頁/共48頁10形式一:struct結構體名{

類型標識符成員名;類型標識符成員名;

…………….};struct結構體名結構體變量名={初始數據};例structstudent{intnum;charname[20];charsex;intage;charaddr[30];};structstudentstu1={112,"WangLin",M,19,"200BeijingRoad"};結構體變量的初始化第9頁/共48頁11struct結構體名{

類型標識符成員名;類型標識符成員名;

…………….}結構體變量名={初始數據};例structstudent{intnum;charname[20];charsex;intage;charaddr[30];}stu1={112,"WangLin",M,19,"200BeijingRoad"};結構體變量的初始化形式二:第10頁/共48頁12struct{

類型標識符成員名;類型標識符成員名;

…………….}結構體變量名={初始數據};例struct{intnum;charname[20];charsex;intage;charaddr[30];}stu1={112,"WangLin",M,19,"200BeijingRoad"};結構體變量的初始化形式三:第11頁/共48頁13結構體數組的定義三種形式:形式一:

structstudent{intnum;charname[20];charsex;intage;};structstudentstu[2];形式二:structstudent{intnum;charname[20];charsex;intage;}stu[2];形式三:struct{intnum;charname[20];charsex;intage;}stu[2];numnamesexagenumnamesexagestu[0]stu[1]25B結構體數組第12頁/共48頁14例struct{intnum;charname[20];charsex;intage;}stu[]={{……},{……},{……}};結構體數組引用引用方式:

結構體數組名[下標]成員名

structstudent{intnum;charname[20];charsex;intage;}stu[3];stu[1].age++;strcpy(stu[0].name,"ZhaoDa");結構體數組初始化第13頁/共48頁15structperson{charname[20];intcount;}leader[3]={“Li”,0,“Zhang”,0,”Wang“,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);}namecountLiZhangWang000例

統(tǒng)計后選人選票(10張選票,3個候選人)第14頁/共48頁16指向結構體變量的指針定義形式:struct結構體名*結構體指針變量名;例structstudent*p;使用結構體指針變量引用成員形式存放結構體變量在內存的起始地址numnamesexagestupstructstudent{intnum;charname[20];charsex;intage;}stu;structstudent*p=&stu;(*結構體指針名).成員名結構體指針名->成員名結構體變量名.成員名指向運算符優(yōu)先級:1結合方向:從左向右例指向結構體的指針變量例intn;int*p=&n;

*p=10;n=10structstudentstu1;structstudent*p=&stu1;stu1.num=101;

(*p).num=101結構體和指針第15頁/共48頁17用結構體變量的成員作參數----值傳遞用指向結構體變量作參數用數組的指針作參數----地址傳遞用結構體變量作參數----多值傳遞,效率低用指向結構體的指針作函數參數第16頁/共48頁18structdata{inta,b,c;};main(){voidfunc(structdata);structdataarg;arg.a=27;arg.b=3;arg.c=arg.a+arg.b;printf("arg.a=%darg.b=%darg.c=%d\n",arg.a,arg.b,arg.c);printf("CallFunc()....\n");

func(arg);printf("arg.a=%darg.b=%darg.c=%d\n",arg.a,arg.b,arg.c);}voidfunc(structdataparm){printf("parm.a=%dparm.b=%dparm.c=%d\n",parm.a,parm.b,parm.c);printf("Process...\n");parm.a=18;parm.b=5;parm.c=parm.a*parm.b;printf("parm.a=%dparm.b=%dparm.c=%d\n",parm.a,parm.b,parm.c);printf("Return...\n");}arga:27b:3c:30(main)(func)parma:27b:3c:30copyarga:27b:3c:30(main)(func)parma:18b:5c:90arga:27b:3c:30(main)arga:27b:3c:30(main)例用結構體變量作函數參數(1)第17頁/共48頁19上面程序的運行結果第18頁/共48頁20structdata{inta,b,c;};main(){voidfunc(structdata*parm);structdataarg;arg.a=27;arg.b=3;arg.c=arg.a+arg.b;printf("arg.a=%darg.b=%darg.c=%d\n",arg.a,arg.b,arg.c);printf("CallFunc()....\n");

func(&arg);printf("arg.a=%darg.b=%darg.c=%d\n",arg.a,arg.b,arg.c);}voidfunc(structdata*parm){printf("parm>a=%dparm>b=%dparm>c=%d\n",parm>a,parm>b,parm>c);printf("Process...\n");parm->a=18;parm->b=5;parm->c=parm->a*parm->b;printf("parm>a=%dparm>b=%dparm>c=%d\n",parm>a,parm>b,parm>c);printf("Return...\n");}arga:18b:5c:90(main)arga:27b:3c:30(main)arga:27b:3c:30(main)(func)parm****arga:18b:5c:90(main)(func)parm****例用結構體指針變量作函數參數(2)第19頁/共48頁21例:用結構體數組作函數參數structstudent{longnum;charname[20];intage;charsex;};main(){structstudentstu[3]={{8031,"xuyimin",20,m},{8032,“heli",19,’f’},{8033,"chenwei",18,’m’}};

voidOutput(structstudent*p,intn);/*函數聲明*/Output(stu,3);}voidOutput(structstudent*p,intn)/*輸出函數*/{inti;for(i=0;i<n;i++,p++)printf("\n%ld,%s,%d,%c",p->num,p->name,p->age,p->sex);}學號不可0開頭,否則報八進制數錯執(zhí)行結果:8031,xuyimin,20,m8032,heli,19,f8033,chenwei,18,m第20頁/共48頁22鏈表處理利用指針特性及內存動態(tài)分配的方法,建立動態(tài)變化的數據結構—鏈表鏈表中每一個元素稱為“結點”:結構體類型數據i鏈表分類:單(向)鏈表、雙(向)鏈表

鏈頭:指向鏈表首地址鏈尾:NULL標志空地址例

structstudent{unsignedlongnum;

floatscore;

structstudent*next;

};第21頁/共48頁23處理鏈表所需的函數malloc函數:動態(tài)內存分配標準函數,函數原型為:void*malloc(unsignedint

size);在動態(tài)存儲區(qū)中分配一個長度為size的連續(xù)空間,返回指針值(基類型為void)指向分配區(qū)域起始地址,分配失敗返回null.calloc函數:動態(tài)內存分配標準函數,函數原型為:void*calloc(unsignedn,unsignedsize);在動態(tài)存儲區(qū)中分配n個長度為size的連續(xù)空間,返回指針值(基類型為void)指向分配區(qū)域起始地址,分配失敗返回null.free函數:動態(tài)內存分配標準函數,函數原型為:voidfree(void

*p);釋放由p指向的存儲空間,p為最近一次調用malloc或calloc函數時返回的值,free函數無返回值。第22頁/共48頁24建立動態(tài)鏈表#include<malloc.h>#defineNULL0#defineLENsizeof(structstudent)structstudent{longnum;floatscore;structstudent*next;};intn;/*n為全局變量,本文件模塊中各函數均可使用它*/structstudent*creat(void)/*此函數帶回一個指向鏈表頭的指針*/{structstudent*head,*p1,*p2;n=0;/*計數器n置初值*/

p1=p2=(structstudent*)malloc(LEN);/*開辟一個新單元*/scanf(“%ld,%f”,&p1>num,&p1–>score);/*為節(jié)點輸入數據*/head=NULL;while(p1->num!=0){n=n+1;/*計數器n對插入鏈表中的節(jié)點計數*/if(n==1)head=p1;elsep2->next=p1;/*新結點總是插入鏈表的末端*/p2=p1;/*讓p2總是指向鏈表的末端節(jié)點*/p1=(structstudent*)malloc(LEN);/*開辟一個新結點*/scanf("%ld,%f",&p1->num,&p1->score);/*為節(jié)點輸入數據*/}p2->next=NULL;/*最后輸入成績的學生結點為鏈尾*/return(head);/*函數返回鏈表的頭節(jié)點指針*/}voidmain(){structstudent*pt;pt=creat();/*函數返回鏈表第1個結點的地址*/printf(“\nnum:%ld\nscore:%5.1f\n“,pt->num,pt->score);

/*輸出第1個結點的成員值*/};程序運行情況如下:1001,67.5↙(輸入第1個學生的學號和成績)1003.87↙(輸入第2個學生的學號和成績)1004,99.5↙(輸入第3個學生的學號和成績)0,0↙(輸入0,表示輸入結束)num:1001(輸出第1個結點的成員值)score:67.5第23頁/共48頁25輸出鏈表voidprint(structstudent*head){structstudent*p;printf(“\nNow,These%drecordsare:\n”,n);p=head;/*使p指向鏈表的頭結點*/if(head!=NULL)/*如果不是空鏈表*/do{printf("%ld%5.1f\n",p->num,p->score);p=p->next;/*使p指向鏈表的下一個結點*/}while(p!=NULL);/*如果p不是空指針,則執(zhí)行循環(huán)體*/}voidmain()/*主函數*/{structstudent*head;head=creat();/*調用creat函數,返回鏈表的起始地址*/print(head);/*調用print函數*/}第24頁/共48頁26對鏈表的刪除操作structstudent*del(structstudent*head,longnum)/*返回鏈頭指針*/{structstudent*p1,*p2;if(head==NULL){printf("\nlistnull\n");gotoend;}p1=head;while(num!=p1->num&&p1->next!=NULL){p2=p1;p1=p1->next;}/*p1后移一個結點

,p2指向p1前一個結點*/if(num==p1->num)/*找到了!p1指向刪除結點*/

{if(p1==head)head=p1->next;/*刪除結點為頭結點*/elsep2->next=p1->next;/*p2原指向刪除結點的前一節(jié)點*/

printf(“delete:%ld\n“,num);/*打印刪除結點學號*/n=n-1;

}elseprinf(“%ldnotbeenfound!\n”,num);/*找不到該節(jié)點*/end:return(head);/*函數返回鏈表的頭節(jié)點指針*/}第25頁/共48頁對鏈表的插入操作structstudent*insert(structstudent*head,structstudent*stud){structstudent*p0,

*p1,*p2;p1=head;p0=stud;if(head==NULL){head=p0;p0->next=NULL}elsewhile(p0->

num>p1->num&&p1->next!=NULL){p2=p1;p1=p1->next;}/*p1后移一個結點

,p2指向p1前一個結點*/if(p0->

num<=p1->num)/*p0插到p1結點之前*/{if(head==p1)head=p0;/*p0插到p1結點之前

*/elsep2->next=p0;/*p0插到p2結點之后*/p0->next=p1;}/*p0插到p1結點之前,p2結點之后*/else{p1->next=p0;p0->next=NULL}/*這時,*/n=n+1;/*p0為鏈表中最大節(jié)點。則p0插到p1結點之后*/return(head);/*函數返回鏈表的頭節(jié)點指針*/}(鏈表head中插入節(jié)點stud)從鏈表頭開始,找到第一個節(jié)點p1,滿足:p0->num<=p1->num將p0插到p1之前,p2之后。第26頁/共48頁28構造數據類型,也叫聯(lián)合體用途:使幾個不同類型的變量共占一段內存(相互覆蓋)共用體類型定義定義形式:union共用體名{

類型標識符成員名;類型標識符成員名;

…………….};例uniondata{inti;charch;floatf;};fchi類型定義不分配內存9.3共用體第27頁/共48頁29形式一:uniondata{inti;charch;floatf;}a,b;形式二:uniondata{inti;charch;floatf;};uniondataa,b,c,*p,d[3];形式三:union{inti;charch;floatf;}a,b,c;fchifchiab共用體變量定義分配內存,長度=最長成員所占字節(jié)數共用體變量任何時刻只有一個成員存在共用體變量的定義第28頁/共48頁30引用方式:例a.i=1;a.ch=‘a’;a.f=1.5;printf(“%d”,a.i);(編譯通過,運行結果不對)

引用規(guī)則不能引用共用體變量,只能引用其成員共用體指針名–>成員名共用體變量名.成員名(*共用體指針名).成員名uniondata{inti;charch;floatf;};uniondataa,b,c,*p,d[3];a.ia.cha.fp->ip->chp->f(*p).i(*p).ch(*p).fd[0].id[0].chd[0].f共用體變量中起作用的成員是最后一次存放的成員例union{inti;charch;floatf;}a;a=1;()不能在定義共用體變量時初始化例union{inti;charch;floatf;}a={1,’a’,1.5};()可以用一個共用體變量為另一個變量賦值例floatx;union{inti;charch;floatf;}a,b;a.i=1;a.ch=‘a’;a.f=1.5;

b=a;()

x=a.f;()共用體變量引用第29頁/共48頁310110000101000001低字節(jié)高字節(jié)0100000101100001ch[0]ch[1]運行結果:i=60501ch0=101,ch1=141ch0=A,ch1=amain(){

unionint_char{inti;charch[2];}x;

x.i=24897;printf("i=%o\n",x.i);printf("ch0=%o,ch1=%o\nch0=%c,ch1=%c\n", x.ch[0],x.ch[1],x.ch[0],x.ch[1]);}例將一個整數按字節(jié)輸出第30頁/共48頁32區(qū)別:存儲方式不同structnode{charch[2];intk;}a;unionnode{charch[2];intk;}b;achkbchk變量的各成員同時存在任一時刻只有一個成員存在聯(lián)系:兩者可相互嵌套結構體與共用體unionun{charkname[30];intnum;};struct{intno;charname[12];charzc;

unionunx;}teach[3];

共用體類型unionun出現在結構體類型的定義中

第31頁/共48頁339.4枚舉類型枚舉類型的定義:

例:enumseasons{spring,summer,autumn,winter};例:enumcolors{red,blue,green,yellow,white,black};一般形式為:enum枚舉類型名{枚舉常量1,枚舉常量2,…,枚舉常量n};定義枚舉類型enumseasons定義枚舉類型enumcolors自定義每一個枚舉常量的值:enumseasons{spring=4,summer=1,autumn,winter};

spring的值為4,summer的值為1,其后枚舉常量的值為前一個枚舉常量的值加1,順序為2、3第32頁/共48頁34枚舉類型變量的定義:先定義枚舉類型,再定義變量:例:enumweekday{sun,mon,tue,wed,thu,fri,sat};

enumweekdayweek;直接定義枚舉變量:例:

enum{sun,mon,tue,wed,thu,fri,sat}week;

enumcolors{red,blue,green,yellow,white,black}c1,c2[7];枚舉類型變量使用:例:c1=white;c2[3]=green;

同類型的枚舉變量、枚舉常量、枚舉變量與枚舉常量間可以進行算術運算和關系運算等

第33頁/共48頁35例:口袋中有五種不同顏色的球若干個,每次從中取出3個球,問得到3種不同顏色球的可能取法,打印每種組合的3種顏色。n=0i從red變到blackj從red變到blackij真真假假k從red變到blackn=n+1輸出輸出取法的總數nki和kj

輸出一種取法

對于3個不同顏色球i、j、k的每種取法:(ij且ki和kj)為了顯示輸出i、j、k這三個枚舉值,組織循環(huán),依次將i,j,k存入枚舉變量prj,再用switch語句將prj枚舉值轉換為字符串形式輸出。for(loop=1;loop<=3;loop++){①switch(loop){case1:pri=i;break;case2:pri=j;break;case3:pri=k;break;default:break;}

②switch(pri)

{casered:printf("%s","red");break;caseyellow:printf("%s","yellow");break;caseblue:printf("%s","blue");break;casewhite:printf("%s","white");break;caseblack:printf("%s","black");break;default:break;}}第34頁/共48頁36{n=n+1;printf("%-4d",n);for(loop=1;loop<=3;loop++){switch(loop){case1:pri=i;break;case2:pri=j;break;case3:pri=k;break;default:break;}switch(pri){casered:printf("%-10s","red");break;caseyellow:printf("%-10s","yellow");break;caseblue:printf("%-10s","blue");break;casewhite:printf("%-10s","white");break;caseblack:printf("%-10s","black");break;default:break;}} printf("\n");}include<stdio.h>main#(){enumcolor{red,yellow,blue,white,black};enumcolori,j,k,pri;intn,loop;n=0;for(i=red;i<=black;i++)for(j=red;j<=black;j++)if(i!=j){for(k=red;k<=black;k++)if((k!=i)&&(k!=j))

}printf("\ntotal:%5d\n",n);}右框程序段第35頁/共48頁37

功能:用自定義名字為已有數據類型命名類型定義簡單形式:

typedeftype

name;例typedefintINTEGER;類型定義語句關鍵字已有數據類型名用戶定義的類型名例typedeffloatREAL;類型定義后,與已有類型一樣使用例INTEGERa,b,c;REALf1,f2;

inta,b,c;floatf1,f2;

說明:1.typedef沒有創(chuàng)造新數據類型2.typedef是定義類型,不能定義變量3.typedef與define不同

define

typedef預編譯時處理

編譯時處理簡單字符置換

為已有類型命名

9.5用typedef定義類型第36頁/共48頁38按定義變量方法先寫出定義體如inti;將變量名換成新類型名如intINTEGER;最前面加typedef如typedefintINTEGER;用新類型名定義變量如INTEGERi,j;例定義數組類型

inta[100];intARRAY[100];typedefintARRAY[100];ARRAYa,b,c;inta[100],b[100],c[100];例定義指針類型

char*str;char*STRING;typedefchar*STRING;STRINGp,s[10];char*p;char*s[10];例定義函數指針類型

int(*p)();int(*POWER)();typedefint(*POWER)();POWERp1,p2;int(*p1)(),(*p2)();例定義結構體類型

structdate{intmonth;intday;intyear;}d;例定義結構體類型

structdate{intmonth;intday;intyear;}DATE;例定義結構體類型typedefstructdate{intmonth;intday;intyear;}DATE;例定義結構體類型

DATEbirthday,*p;structdate{intmonth;intday;intyear;}birthday,*p;類型定義可嵌套例typedefstructclub{charname[20];intsize;intyear;}GROUP;typedefGROUP*PG;PGpclub;GROUP*pclub;structclub*pclub;GROUP為結構體類型PG為指向GROUP的指針類型typedef定義類型步驟第37頁/共48頁399.6編譯預處理命令作用:對源程序編譯之前做一些處理,生成擴展C源程序種類宏定義#define文件包含#include條件編譯#if--#else--#endif等格式:“#”開頭占單獨書寫行語句尾不加分號第38頁/共48頁40如if(x==YES)printf(“correct!\n”);elseif(x==NO)printf(“error!\n”);展開后:if(x==1)printf(“correct!\n”);elseif(x==0)printf(“error!\n”);宏定義不帶參數宏定義一般形式:

#define宏名宏體功能:用指定標識符(宏名)代替字符序列(宏體)宏展開:預編譯時,用宏體替換宏名---不作語法檢查如#defineYES1#defineNO0#definePI3.1415926#defineOUTprintf(“Hello,World”);定義位置:任意(一般在函數外面)作用域:從定義命令到文件結束#undef可終止宏名作用域格式:

#undef宏名例#defineYES1main(){……..}#undefYES#defineYES0max(){……..}YES原作用域YES新作用域宏定義可嵌套,不能遞歸例#defineMAXMAX+10()引號中的內容與宏名相同也不置換例#definePI3.14159printf(“2*PI=%f\n”,PI*2);宏展開:printf(“2*PI=%f\n”,3.14159*2);宏定義中使用必要的括號()例#defineWIDTH80#defineLENGTH

WIDTH+40var=LENGTH*2;宏展開:var=80+40*2;()()例#defineWIDTH80#defineLENGTH

WIDTH+40var=LENGTH*2;宏展開:var=80+40*2;第39頁/共48頁41宏定義中“宏體”的常見形式宏體為常量:#definePI3.1415926宏體為表達式:#defineP(2*x*x-3*x+1)例:求多項式(2*x2-3*x+1)2+(2*x2-3*x+1)/2-4的值#defineP(2*x*x-3*x+1)main(){floatx,y;scanf("%f",&x);y=p*p+p/2-4;printf(“\ny=%f\n",y);}宏體為格式串:#defineFORMA

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論