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

下載本文檔

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

文檔簡介

第十一章結(jié)構(gòu)體與共用體結(jié)構(gòu)體的概念在實際應(yīng)用中,經(jīng)常有一些既有聯(lián)系,類型又不同的數(shù)據(jù)需要一起處理。如:學(xué)生基本檔案的數(shù)據(jù)字段:學(xué)號姓名性別地址分?jǐn)?shù)類型:longcharchar

charfloat

C語言允許用戶按自己的需要將不同的基本類型構(gòu)造成一種特殊類型,即結(jié)構(gòu)體。結(jié)構(gòu)體的操作分為三個步驟:⑴根據(jù)需要定義結(jié)構(gòu)體類型;⑵通過定義的類型說明變量、數(shù)組、指針;⑶引用變量、數(shù)組元素和指針指向的對象。11.1結(jié)構(gòu)體

⒈結(jié)構(gòu)體類型的定義格式:struct

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

type成員1;

type成員2;…

type成員n;};結(jié)構(gòu)體標(biāo)志。用標(biāo)識符命名的結(jié)構(gòu)類型名。結(jié)構(gòu)類型中所含的成員項及其類型。例:structstudent{longnum;charname[20];

intage;charadd[30];floatscore;};⒉結(jié)構(gòu)變量的說明定義結(jié)構(gòu)只是確定該結(jié)構(gòu)體類型的名稱及其成員項的組成和成員項的類型。必須由定義的結(jié)構(gòu)類型說明結(jié)構(gòu)變量,才開辟相應(yīng)的內(nèi)存空間以供使用。結(jié)構(gòu)體變量的說明方式:⑴先定義后說明structstudent{longnum;charname[20];

intage;charadd[30];floatscore;};structstudentstu1,stu2,stu3;用structstudent類型說明三個變量。⑵定義結(jié)構(gòu)類型時說明變量stu1,stu2,stu3;變量在內(nèi)存中所占的字節(jié)數(shù)?⑶無名結(jié)構(gòu)方式說明變量struct{longnum;charname[20];

intage;charadd[30];floatscore;}stu1,stu2,stu3;;說明:⑴注意類型和變量的區(qū)別。⑵成員項可單獨使用。wang.age=20⑶結(jié)構(gòu)體的成員項也可以是結(jié)構(gòu)變量。structdoc{charname[20];

structbirthage;floatsal;};structbirth{intyear;

int

mon;

intday;};結(jié)構(gòu)doc中的成員項是一個birth的結(jié)構(gòu)變量!⒊結(jié)構(gòu)體變量的引用結(jié)構(gòu)變量都是以成員項作為引用單位,引用方式:結(jié)構(gòu)變量名.成員項名wang.score=100;說明:

(1)不能將一個結(jié)構(gòu)體變量作為一個整體進行輸入和輸出。(2)如果成員本身又屬一個結(jié)構(gòu)體類型,則要用若干個成員運算符,一級一級地找到最低的一級的成員。stu1.age.monthstu1.age.daystu1.age.year

(3)對成員變量可以像普通變量一樣進行各種運算stu2.score=stu1.score;sum=stu1.score+stu2.score;stu1.age++;(4)可以引用成員的地址,也可以引用結(jié)構(gòu)體變量的地址。scanf(“%ld”,&stu1.num);printf(“%o”,&stu1);但不能用以下語句整體讀入結(jié)構(gòu)體變量,例如:

scanf(“%ld,%s,%d,%s,%f”,&stu1)結(jié)構(gòu)體變量的地址主要用作函數(shù)的參數(shù),傳遞結(jié)構(gòu)體變量的地址。輸入stu1.num的值輸出stu1的首地址⒋結(jié)構(gòu)體變量的初始化結(jié)構(gòu)變量可以在說明時賦初值,稱為初始化。main(){structstudent{longnum;charname[20];charsex;

intage;charaddr[30];}wang={99010101,“wang

lin”,‘w’,20,“shanghai”};

printf("num=%ld,name=%s,sex=%c,age=%d,addr=%s",

wang.num,,wang.sex,wang.age,wang.addr);實例運行⒌結(jié)構(gòu)體數(shù)組結(jié)構(gòu)體變量也可以構(gòu)造成數(shù)組,稱為結(jié)構(gòu)體數(shù)組。每個數(shù)組元素都是一個結(jié)構(gòu)體變量,都含有結(jié)構(gòu)體成員項。它們在內(nèi)存中的地址是連續(xù)的。數(shù)組的說明:structstudent{longnum;charname[20];floatscore;}stud[3];說明:⑴定義了數(shù)組stud有3個元素,每上元素都為structstudent類型⑵結(jié)構(gòu)數(shù)組名stud,代表結(jié)構(gòu)數(shù)組的首地址。

={{99010101,“wang”,67.5},{},{99010103,“fun”,98.5}};結(jié)構(gòu)體數(shù)組的應(yīng)用例:對候選人得票的統(tǒng)計程序。設(shè)有3個候選人,每次輸入一個得票的候選人的序號,要求最后輸出各人得票結(jié)果。#include<stdio.h>/*a2.c*/#defineNUMBER6structperson{intnum;charname[20];

intcount;}lead[3]={{1,“fun”,0},{2,“tan”,0},{3,“wang”,0}};voidmain(void){inti,j,numb;for(i=0;i<NUMBER;i++){

scanf(“%d”,&numb);if(numb<4&&numb>0)lead[numb-1].count++;else

printf(“Selectionerror\n”);}printf(“\n”);for(i=0;i<3;i++)

printf(“%5s:%d\n”,lead[i].name,lead[i].count);}定義結(jié)構(gòu)說明數(shù)組并初始化。循環(huán)輸入統(tǒng)計票數(shù)輸出結(jié)果。實例運行⒍結(jié)構(gòu)體指針概念:指向結(jié)構(gòu)體變量首地址的指針稱為結(jié)構(gòu)體指針。結(jié)構(gòu)指針加一,地址加一個結(jié)構(gòu)變量所占的字節(jié)。結(jié)構(gòu)體指針的應(yīng)用:⑴先說明結(jié)構(gòu)體指針structstudentstu1,*p;指向結(jié)構(gòu)的指針⑵指針指向同類型的結(jié)構(gòu)變量或數(shù)組。p=&stu1;⑶通過指針引用指針指向變量的成員項,引用方式為:方式一:(*p).成員項名方式二:p->成員項名結(jié)構(gòu)體指針主要用于對結(jié)構(gòu)體數(shù)組操作。struct

studoc{

int

iNum;char*name; }*p,wang={2001,”wangli”};p=&wang;printf(“%d:%s”,p->iNum,p->name};舉例說明指向結(jié)構(gòu)體變量的指針的應(yīng)用。#include<stdio.h>/*a3.c,a4.c*/struct

sam{intnum;charname[20];char*addr;}ws[]={{101,“fun”,“Shanghai”},{102,“tan”,“Bejing”},{103,“wang”,“Hefei”}};voidmain(void){inti;

struct

sam*pws;

pws=ws;for(i=0;i<3;i++,pws++)

printf(“%-9d%-14s%-20s\n”,pws->num,

pws->name,

pws->addr);}定義結(jié)構(gòu),說明數(shù)組并初始化。說明結(jié)構(gòu)指針。指針指向結(jié)構(gòu)數(shù)組。通過指針引用成員項。實例運行實例運行如何用指針的另一種方式輸出?(*pws).num

⒎用結(jié)構(gòu)體變量和指向結(jié)構(gòu)體的指針作函數(shù)參數(shù)當(dāng)函數(shù)需要通過形參傳遞一個結(jié)構(gòu)體變量時,一般有兩種處理辦法:(2)傳遞一個結(jié)構(gòu)體指針(效率高)。將結(jié)構(gòu)體變量的地址傳給形參。(1)傳遞一個結(jié)構(gòu)體變量(效率低)。用結(jié)構(gòu)體變量作實參時,采取的也是“值傳遞”的方式,將結(jié)構(gòu)體變量所占的內(nèi)存單元的內(nèi)容全部順序傳遞給形參,形參也必須是同類型的結(jié)構(gòu)體變量。形參也要占用內(nèi)存單元。例:用結(jié)構(gòu)體變量作參數(shù)。#include<stdio.h>voidmprintp(structstudent);structstudent{longnum;char*name;floatscore;};

voidmain(){

structstudents1;s1.num=99010101;=“wang

hai”;s1.score=99;

mprintp(s1);}

voidmprintp(structstudentsv){printf(“%ld\n%s\n%5.1f\n”,sv.num,,sv.score

);}結(jié)構(gòu)變量。例:將上題改用結(jié)構(gòu)體變量的指針作參數(shù)。#include<stdio.h>voidmprintp(structstudent*);structstudent{longnum;char*name;floatscore;};

voidmain(){

structstudents1;s1.num=99010101;=“wang

hai”;s1.score=99;

mprintp(&s1);}

voidmprintp(structstudent*sp){printf(“%ld\n%s\n%5.1f\n”,sp->num,sp->name,sp->score);}指向結(jié)構(gòu)的指針。11.2鏈表⒈引用自身的結(jié)構(gòu)和鏈表的概念結(jié)構(gòu)中的某個成員項,為指向該結(jié)構(gòu)類型自身的指針,則稱為引用自身的結(jié)構(gòu)。structstudent{

intnum;floatscore;charname[10];

structstudent*next;};指向自身的結(jié)構(gòu)。鏈表的概念鏈表是一種動態(tài)存儲分配結(jié)構(gòu),通過指針相連,數(shù)據(jù)可以不連續(xù)存放。如用數(shù)組存放數(shù)據(jù)時,必須事先定義固定的長度(即元素的個數(shù))。如果事先難以確定元素的個數(shù),則必須把數(shù)組定義的足夠大,顯然這會造成內(nèi)存的浪費。鏈表則沒有這種缺點,它根據(jù)需要開辟內(nèi)存單元。A1249head13561249B1475C1021DNULL135614751021鏈表(單向鏈表)鏈表有一個“頭指針”變量,它存放一個地址,該地址指向一個元素。鏈表中每個元素稱為“結(jié)點”,每個結(jié)點都應(yīng)包含兩個部分:用戶需要用的實際數(shù)據(jù)和下一個結(jié)點的地址。最后一個結(jié)點不指向其他元素,它稱為“表尾”,它的地址部分放一個“NULL”,鏈表到此結(jié)束。鏈表中各元素不是連續(xù)存放的。要找某一元素,必須要找到上一個元素,根據(jù)它所提供的下一元素的地址才能找到下一個元素。如果不提供頭指針,則整個鏈表都無法訪問。這種鏈表的數(shù)據(jù)結(jié)構(gòu),必須利用指針變量才能實現(xiàn),即一個結(jié)點中應(yīng)包含一個指針變量,用它存放下一結(jié)點的地址。2、簡單鏈表例:建立一個簡單的鏈表,由3個學(xué)生數(shù)據(jù)的結(jié)點組成。#include<malloc.h>/*a7.c*/structstudent{intnum;floatscore;

structstudent*next;};main(){structstudenta,b,c,*head,*p;a.num=101;a.score=89.5;b.num=102;b.score=90;c.num=103;c.score=56;head=&a;a.next=&b;b.next=&c;c.next=NULL;p=head;while(p!=NULL){printf("%d,%5.1f\n",p->num,p->score);p=p->next;}}實例運行上例是比較簡單的,所有結(jié)點都是在程序中定義的,不是臨時開辟的,也不能用完后釋放,這種鏈表稱為“靜態(tài)鏈表”。前面講過,鏈表結(jié)構(gòu)是動態(tài)生地分配存儲的,即在需要時才開辟一個結(jié)點的存儲單元以便插入或追加節(jié)點,刪除節(jié)點后需要釋放節(jié)點占用的內(nèi)存單元。C語言提供了相應(yīng)的函數(shù)。3.處理動態(tài)鏈表所需的函數(shù)⑴void*malloc(unsigned

intsize)

:在內(nèi)存的動態(tài)存儲區(qū)中分配一個長度為size的連續(xù)空間。成功,則返回一個void型的空指針,否則,返回NULL.使用方法:ptr=malloc(size);分配內(nèi)存的字節(jié)數(shù)。返回空類型的指針。成功:返回內(nèi)存的地址。失?。悍祷豊ULL。ptr⑵voidfree(ptr)作用:釋放ptr指向的內(nèi)存空間。(3)void*calloc(unsignedn,unsignedsize)在內(nèi)存的動態(tài)區(qū)存儲中分配n個長度為size的連續(xù)空間。函數(shù)返回分配域的起始地址;如果分配不成功,返回0。4.建立動態(tài)鏈表例:寫一函數(shù)建立一個有多名學(xué)生數(shù)據(jù)的單向動態(tài)鏈表。(當(dāng)學(xué)號輸入為0時,表示鏈表建立結(jié)束)算法:設(shè)3個指針變量:head,p1,p2,都是指向結(jié)構(gòu)體類型數(shù)據(jù)head:存放第1個結(jié)點的地址,即頭指針p1:指向當(dāng)前新開辟的結(jié)點p2:指向前一個結(jié)點(即已建成的鏈表中的最后一個結(jié)點)所謂建立動態(tài)鏈表是指在程序執(zhí)行過程中從無到有地建立起一個鏈表,即一個一個地開辟結(jié)點和輸入各結(jié)點數(shù)據(jù),并建立起前后相鏈的關(guān)系。結(jié)構(gòu)體的定義:#include<stdio.h>#include<malloc.h>#defineLENsizeof(structstudent)#defineNULL0structstudent{longnum;intscore;structstudent*next;};intn;建立鏈表的函數(shù):structstudent*create(void){structstudent*head,*p1,*p2;n=0;head=NULL;printf("inputnumandscore\n");p1=p2=(structstudent*)malloc(LEN);scanf("%ld,%d",&p1->num,&p1->score);while(p1->num!=0){n=n+1;if(n==1)head=p1;else{p2->next=p1;p2=p1;}p1=(structstudent*)malloc(LEN);scanf("%ld,%d",&p1->num,&p1->score);}p2->next=NULL;return(head);}5.輸出鏈表將鏈表中各結(jié)點的數(shù)據(jù)依次輸出。首先要知道鏈表第一個結(jié)點的地址,也就是要知道head的值。然后設(shè)一個指針變量p,先指向第一個結(jié)點,輸出p所指的結(jié)點,然后使p后移一個結(jié)點,再輸出,直到鏈表的尾結(jié)點。voidprint(structstudent*head){structstudent*p;printf("\nThese%drecordsare:\n",n);p=head;if(head!=NULL)do{printf("%ld%5d\n",p->num,p->score);p=p->next;}while(p!=NULL);}main(){structstudent*head;head=create();print(head);}實例運行6.對鏈表的刪除操作已有一個鏈表,希望刪除其中某個結(jié)點。ABCDEABCDE原來鏈表將C從鏈表中刪除例:寫一函數(shù)以刪除動態(tài)鏈表中指定的結(jié)點。思路:從P指向的第一個結(jié)點開始,檢查該結(jié)點中的num的值是否等于要刪除的那個學(xué)號。如果是,就將該結(jié)點刪除,不是,就將指針p后移一個結(jié)點,直到遇到表尾為止。設(shè)兩個指針p1,p2,p1為當(dāng)前結(jié)點,p2指向剛才檢查過的結(jié)點。找到要刪除的結(jié)點,又有兩種情況:A.要刪除的是第一個結(jié)點B.要刪除的不是第一個結(jié)點head=p1->nextp2->next=p1->next刪除結(jié)點的函數(shù):structstudent*del(structstudent*head,longnum){structstudent*p1,*p2;if(head==NULL){printf("\nlistisnull\n");}p1=head;while(p1->num!=num&&p1->next!=NULL){p2=p1;p1=p1->next;}if(p1->num==num){if(p1==head)head=p1->next;elsep2->next=p1->next;printf("delete:%d\n",num);n=n-1;}elseprintf("%ldnotbeenfound!",num);return(head);}實例運行7.對鏈表的插入操作(在尾部追加節(jié)點)步驟:①為新節(jié)點分配內(nèi)存。②建立新節(jié)點的成員項。③建立鏈接關(guān)系。在鏈表最后插入一個結(jié)點:structstudent*Add(structstudent*head){ structstudent*p1,*p2,*p3; p1=head;

if(head!=NULL) while(p1->next!=NULL) p1=p1->next; p2=(structstudent*)malloc(sizeof(structstudent));

printf("Yournum:");scanf("%ld",&p2->num);

printf("Yourscore:");scanf("%d",&p2->score);

if(head==NULL)head=p2; else p1->next=p2; p2->next=NULL;

printf("Add

Succee...\n"); return(head);}實例運行11.3共用體(union)概念:不同數(shù)據(jù)類型的集合;每個成員項共用一段內(nèi)存空間;某一時刻只能對一個“活的active”成員項操作;⒈共用體類型的定義格式:union共用體名{

type成員項1;

type成員項2;

type成員項n;};unionexam{

inta;floatb;charc;};⒉共用體變量的說明和引用可以用共用體類型說明:共用體變量、共用體數(shù)組、指向共用體指針。unionexamx,*px,y[10];引用:引用變量的成員項。通過變量引用:變量名.成員項名通過指針引用:指針->成員項名⒊共用體與結(jié)構(gòu)體的區(qū)別s

溫馨提示

  • 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

提交評論