第10章 結(jié)構(gòu)體(最終講稿)_第1頁
第10章 結(jié)構(gòu)體(最終講稿)_第2頁
第10章 結(jié)構(gòu)體(最終講稿)_第3頁
第10章 結(jié)構(gòu)體(最終講稿)_第4頁
第10章 結(jié)構(gòu)體(最終講稿)_第5頁
已閱讀5頁,還剩36頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

結(jié)構(gòu)體、共用體及枚舉類型第

10

章10.1結(jié)構(gòu)體類型和結(jié)構(gòu)體變量10.2結(jié)構(gòu)體數(shù)組10.3結(jié)構(gòu)體指針10.4用指針處理鏈表

10.5共用體類型

10.6枚舉類型

10.7用typedef命名類型本章小結(jié)結(jié)構(gòu)體類型和結(jié)構(gòu)體變量10.1教學(xué)進程10.1.1結(jié)構(gòu)體類型的定義有時需要將不同類型的數(shù)據(jù)組合成一個有機的整體,以便于引用。如:一個學(xué)生有學(xué)號、姓名、性別、年齡、成績、地址等屬性

intnum;charname[20];charsex;

intage;floatscore;

intcharaddr[30];問題定義:100101

LiFun

M1887.5Beijing

Numnamesexagescoreaddr應(yīng)當把它們組織成一個組合項,在一個組合項中包含若干個類型不同(當然也可以相同)的數(shù)據(jù)項。教學(xué)進程結(jié)構(gòu)體類型struct

結(jié)構(gòu)體名{類型標識符成員名表1;類型標識符成員名表2;

…;類型標識符成員名表n;};定義一個結(jié)構(gòu)體類型的一般形式為:其中struct是用于定義具體結(jié)構(gòu)體類型的關(guān)鍵字,與結(jié)構(gòu)體名共同組成結(jié)構(gòu)體類型名。在“成員表列”中可以定義該類型中有哪些成員,各成員屬于什么數(shù)據(jù)類型,由它們組成結(jié)構(gòu)體。教學(xué)進程結(jié)構(gòu)體類型structstudent{intnum;charname[20];charsex;

intage;floatscore;charaddr[30];};結(jié)構(gòu)體類型名成員類型名成員名例如:structstudent{intnum;charname[20];charsex;

intage;floatscore;charaddr[30];};structdate{intmonth;

intday;

intyear;}structstudent{intnum;charneme[20],sex;

intage;

structdatebirthday;charaddr[30];}student1,student2;已定義的結(jié)構(gòu)體類型可以像基類型一樣使用。教學(xué)進程結(jié)構(gòu)體類型的定義可以嵌套在這個定義中,結(jié)構(gòu)體“日期”類型date中又嵌套定義了結(jié)構(gòu)體“時間”類型time。這就是結(jié)構(gòu)體的嵌套定義。定義一個結(jié)構(gòu)體“日期”類型date:

structdate{intyear; /*年*/

intmonth; /*月*/

intday; /*日*/

structtime/*結(jié)構(gòu)體“時間”類型*/{inthour; /*小時*/

intminute; /*分*/

intsecond; /*秒*/}t;

};結(jié)構(gòu)體類型(2)當一個結(jié)構(gòu)體類型定義在函數(shù)之外時,它具有全局作用域;若定義在任一對花括號之內(nèi),則具有局部作用域,其作用范圍是所在花括號構(gòu)成的塊。(3)結(jié)構(gòu)體是一種復(fù)雜的數(shù)據(jù)類型,是數(shù)目固定、類型不同的若干成員的集合,結(jié)構(gòu)體類型的定義只是列出了該結(jié)構(gòu)的組成情況,編譯系統(tǒng)并未因此而分配存儲空間,當定義了結(jié)構(gòu)體類型的變量或數(shù)組后,編譯系統(tǒng)才會分配存儲空間。(4)成員名可以與程序中的變量名相同,二者不代表同一個對象。例如,程序中可以定義一個變量num,它與struct

stu中的num是兩回事,互不干擾。(5)如果兩個結(jié)構(gòu)體的成員類型、名稱、個數(shù)相同,但結(jié)構(gòu)體名不同,也是兩個不同的結(jié)構(gòu)類型。結(jié)構(gòu)體類型教學(xué)進程要強調(diào)的是,結(jié)構(gòu)體類型名(如上例中的date)是定義的類型名,而不是變量名,就好像整型的類型名為int,雙精度實型的類型名為double,字符型的類型名為char一樣,只不過整型、雙精度實型、字符型等基本數(shù)據(jù)類型是C編譯系統(tǒng)已經(jīng)定義的,用戶可以直接用它們來定義相應(yīng)類型的變量,而結(jié)構(gòu)體類型是用戶根據(jù)數(shù)據(jù)處理的需要臨時定義的一種類型,一經(jīng)定義就可以像系統(tǒng)定義的類型一樣使用了。但系統(tǒng)并不為類型分配存儲空間,為了能在程序中使用結(jié)構(gòu)體類型的數(shù)據(jù),必須定義結(jié)構(gòu)體類型的變量。定義結(jié)構(gòu)體類型的變量教學(xué)進程結(jié)構(gòu)體類型和結(jié)構(gòu)體變量結(jié)構(gòu)體變量的定義可以采取以下3種方法定義結(jié)構(gòu)體變量:(1)先定義結(jié)構(gòu)體類型,再定義結(jié)構(gòu)體變量例如:structstudent

student1,student2;↑↑↑

結(jié)構(gòu)體類型名結(jié)構(gòu)體變量名定義了student1和student2為structstudent類型(應(yīng)事先已定義)的變量,即它們具有structstudent類型的結(jié)構(gòu)。student1100101ZhangXinM1990.5Shanghai100102WangLiF2098Beijingstudent2在TC中占字節(jié)數(shù)2201243059定義結(jié)構(gòu)體類型變量教學(xué)進程●一般形式為:

struct結(jié)構(gòu)體名{成員表列}變量名表列;(2)在定義結(jié)構(gòu)體類型的同時定義結(jié)構(gòu)體變量例如:structstudent{intnum;

charname[20];

charsex;

intage;

floatscore;

charaddr[30];}student1,student2;它的作用與第一種方法相同,即定義了兩個structstudent類型的變量student1,student2。如果需要,在程序中還可以定義該種結(jié)構(gòu)體類型的其它變量。結(jié)構(gòu)體類型變量的定義教學(xué)進程(3)不指定類型名而直接定義結(jié)構(gòu)體變量●

struct

{成員表}變量表;例如:

struct

{intnum;

charname[10];

charsex;

intage;

floatscore;

}studernt1,

student2;指定了一個無名的結(jié)構(gòu)體類型,它沒有名字,顯然不能再以此結(jié)構(gòu)體類型去定義其它變量了。未出現(xiàn)結(jié)構(gòu)體名結(jié)構(gòu)體類型變量的定義教學(xué)進程注意(1)結(jié)構(gòu)體類型與結(jié)構(gòu)體變量是不同的概念,不能混同。(2)結(jié)構(gòu)體類型中的成員名可以與程序中的變量名相同,但二者不代表同一對象。(3)對結(jié)構(gòu)體變量中的成員,可以單獨使用,它的作用與地位相當于普通變量。教學(xué)進程結(jié)構(gòu)體變量中的每個成員與普通變量一樣,可進行各種運算。

st.num=115;

[0]=‘z';

[1]='a';

[2]='\0';

st.sex='M';

st.age=19;

st.score=95.0;

scanf("%d",&st.num);

printf("%s",);方式●結(jié)構(gòu)體變量名.成員名其中“.”為結(jié)構(gòu)體成員運算符,它的優(yōu)先級最高。結(jié)構(gòu)體變量的引用和初始化結(jié)構(gòu)體變量的引用在定義結(jié)構(gòu)體變量后,就可以引用其成員。引用結(jié)構(gòu)體類型變量教學(xué)進程(1)同類的結(jié)構(gòu)體變量可以互相賦值如:student1=student2;

但不能將一個結(jié)構(gòu)體變量作為一個整體進行輸入和輸出。如:已定義student1和student2為結(jié)構(gòu)體變量并已有值,

printf(″%d,%s,%c,%d,%f,%\n″,student1);(2)如果成員本身又屬一個結(jié)構(gòu)體類型,則要用若干個成員運算符,一級一級地找到最低一級的成員,進行賦值或存取及運算。

如:訪問上面定義的結(jié)構(gòu)體變量student1的各成員

student1.numstudent1.birthday.month定義了結(jié)構(gòu)體變量后,便可以引用這個變量。但應(yīng)遵守以下規(guī)則:引用結(jié)構(gòu)體類型變量教學(xué)進程(3)對結(jié)構(gòu)體變量的成員可以像普通變量一樣進行各種運算(根據(jù)其類型決定可以進行的運算)。

如:student2.score=student1.score;sum=student1.score+student2.score;student1.age++;++student2.age;(4)可引用結(jié)構(gòu)體變量成員的地址,也可引用結(jié)構(gòu)體變量的地址。

如:scanf(″%d″,&student1.num);//為成員student1.num賦值

printf(″%o″,&student1);//輸出變量student1的首地址

但不能用以下語句整體讀入結(jié)構(gòu)體變量如:

scanf(″%d,%s,%c,%d,%f,%s″,&student1);

結(jié)構(gòu)體變量的地址主要用作函數(shù)參數(shù),傳遞結(jié)構(gòu)體變量的地址。教學(xué)進程與普通變量一樣,在定義結(jié)構(gòu)體類型變量的同時也可以對結(jié)構(gòu)體類型變量賦初值。結(jié)構(gòu)體變量的引用和初始化結(jié)構(gòu)體變量的初始化例10-1對結(jié)構(gòu)變量初始化。#include<stdio.h>main(){struct

stu

{intnum;charname[20];charsex;

intage;floatscore;}boy2,boy1={102,"Zhangping",'M',20,78.5};boy2=boy1;printf("Number:%d\nName:%s\n",boy2.num,);printf("Sex:%c\nage:%dScore:%4.1f\n",boy2.sex,boy2.age,boy2.score);}

本例中,對結(jié)構(gòu)體變量boy1作了初始化賦值,然后把boy1的值整體賦予boy2,最后用printf函數(shù)輸出boy2各成員的值。程序運行結(jié)果如下:Number:102Name:ZhangpingSex:MAge:20Score:78.5結(jié)構(gòu)體數(shù)組10.310.3.1定義結(jié)構(gòu)體數(shù)組教學(xué)進程與整型數(shù)組、實型數(shù)組、字符型數(shù)組一樣,在程序中也可以定義結(jié)構(gòu)體類型的數(shù)組,并且同一個結(jié)構(gòu)體數(shù)組中的元素應(yīng)為同一種結(jié)構(gòu)體類型。與定義結(jié)構(gòu)體變量的方法相似,只需說明其為數(shù)組即可。如:structstudent{intnum;charname[20];charsex;intage;floatscore;charaddr[30];

};structstudentstu[3];}stu[3];/*直接定義結(jié)構(gòu)體數(shù)組*/定義了一個數(shù)組stu,數(shù)組有3個元素,均為structstudent類型數(shù)據(jù)。結(jié)構(gòu)體數(shù)組10.310.3.2結(jié)構(gòu)體數(shù)組的初始化教學(xué)進程與其它類型的數(shù)組一樣,對結(jié)構(gòu)體數(shù)組可以初始化。如:

structstudent{int

num;charname[20];charsex;

intage;floatscore;charaddr[30];

}stu[3]={{10101,″LiLin″,′M′,18,87.5,″103BeijingRoad″},{10102,″ZhangFun″,′M′,19,99,″130ShanghaiRoad″},{10104,″WangMin″,′F′,20,78.5,″1010ZhongshanRoad″}};圖9-4定義結(jié)構(gòu)體數(shù)組教學(xué)進程數(shù)組各元素在內(nèi)存中連續(xù)存放,如圖所示。一個結(jié)構(gòu)體數(shù)組的元素相當于一個結(jié)構(gòu)體變量,引用結(jié)構(gòu)體數(shù)組元素的一般形式為:數(shù)組名[下標].成員名10.3.3結(jié)構(gòu)體數(shù)組的引用教學(xué)進程【例10.2】計算學(xué)生的平均成績和不及格的人數(shù)。#include<stdio.h>struct

stu{intnum;charname[20];charsex;floatscore;}boy[5]={{101,"Liping",'M',45},{102,"Zhangping",'M',62.5},{103,"Hefang",'F',92.5},{104,"Chengling",'F',87},{105,"Wangming",'M',58}};main(){int

i,c=0;floatave,s=0;

for(i=0;i<5;i++){s+=boy[i].score;

if(boy[i].score<60)c+=1;}

ave=s/5;

printf("average=%f\ncount=%d\n",ave,c);}

本例程序中定義了一個結(jié)構(gòu)體數(shù)組boy,共5個元素,并作了初始化賦值。在main函數(shù)中用for語句逐個累加各元素的score成員值存于s之中,如果score的值小于60(不及格),那么計數(shù)器c加1,循環(huán)完畢后輸出全班平均分及不及格人數(shù)。程序運行結(jié)果如下:average=69.000000count=2結(jié)構(gòu)體指針10.410.4.1指向結(jié)構(gòu)體變量的指針變量教學(xué)進程結(jié)構(gòu)體類型的指針變量指向結(jié)構(gòu)體變量或數(shù)組(或數(shù)組元素)的起始地址。

structstudent{intnum;

charname[10];

charsex;

intage;

floatscore;

};

structstudentst1,st2,

st[10],*p;例如令p=&st1,st1.num(*p).nump->num令p=st,

st[0].num(*p).nump->num指向結(jié)構(gòu)體變量的指針變量教學(xué)進程當結(jié)構(gòu)體類型的指針變量p指向一個結(jié)構(gòu)體類型變量后,下列三種表示是等價的:結(jié)構(gòu)體變量名.成員

(*p).成員

p->成員必須注意,當p定義為指向結(jié)構(gòu)體類型的變量后,它不能指向某一成員。例如,p=&st1.num;是錯誤的,因為它企圖讓結(jié)構(gòu)體指針變量指向結(jié)構(gòu)體變量st1中的成員num。10.4.2指向結(jié)構(gòu)體數(shù)組的指針教學(xué)進程

#include<stdio.h>structstudent{intnum;charname[20];charsex;

intage;};【例10.4】

指向結(jié)構(gòu)體數(shù)組元素的指針的應(yīng)用。structstudentstu[3]={{10101,"LiLin",'M',18},{10102,"ZhangFun",'M',19},{10104,"WangMin",'F',20}};voidmain(){structstudent*p;

printf("No.Namesexage\n");

for(p=stu;p<stu+3;p++)printf("%5d%-20s%2c%4d\n",p->num,p->name,p->sex,p->age);}結(jié)構(gòu)體指針10.4指向結(jié)構(gòu)體數(shù)組的指針教學(xué)進程程序分析:p是指向structstudent結(jié)構(gòu)體類型數(shù)據(jù)的指針變量。在for語句中先使p的初值為stu,也就是數(shù)組stu第一個元素的起始地址。在第一次循環(huán)中輸出stu[0]的各個成員值。然后執(zhí)行p++,使p自加1。p加1意味著p所增加的值為結(jié)構(gòu)體數(shù)組stu的一個元素所占的字節(jié)數(shù)。執(zhí)行p++后p的值等于stu

+1,p指向stu[1]。在第二次循環(huán)中輸出stu[1]的各成員值。在執(zhí)行p++后,p的值等于stu+2,再輸出stu[2]的各成員值。在執(zhí)行p++后,p的值變?yōu)閟tu+3,已不再小于stu+3了,不再執(zhí)行循環(huán)。圖9-8教學(xué)進程注意:(1)

如果p的初值為stu,即指向第一個元素,則p加1后p就指向下一個元素。例如:

(++p)->num先使p自加1,然后得到它指向的元素中的num成員值(即10102)。

(p++)->num先得到p->num的值(即10101),然后使p自加1,指向stu[1]。(2)

程序已定義了p是一個指向structstudent類型數(shù)據(jù)的指針變量,它用來指向一個structstudent類型的數(shù)據(jù),不應(yīng)用來指向stu數(shù)組元素中的某一成員。指向結(jié)構(gòu)體數(shù)組的指針用指針處理鏈表10.710.7.1鏈表概述1.鏈表的一般結(jié)構(gòu)存儲節(jié)點數(shù)據(jù)域 存放數(shù)據(jù)元素指針域 存放下一個結(jié)點元素的地址鏈表是一種常見的重要的數(shù)據(jù)結(jié)構(gòu),是動態(tài)地進行存儲分配的一種結(jié)構(gòu)。鏈表的組成:頭指針:存放一個地址,該地址指向一個元素

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

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

結(jié)點:用戶需要的實際數(shù)據(jù)和鏈接節(jié)點的指針教學(xué)進程教學(xué)進程鏈表的概述2.結(jié)點結(jié)構(gòu)體類型的定義

struct

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

{數(shù)據(jù)成員表;

struct

結(jié)構(gòu)體名*指針變量名;

};鏈表結(jié)點結(jié)構(gòu)的一般形式:其函數(shù)原型為void*malloc(unsigned

intsize);又如:float*pc;pc=(float*)malloc(5*sizeof(float));3.結(jié)點的動態(tài)分配

malloc(存儲區(qū)字節(jié)數(shù))

該函數(shù)返回存儲區(qū)的首地址。形式是:釋放存儲區(qū)用如下函數(shù):free(p);它表示釋放由p指向的存儲空間。教學(xué)進程教學(xué)進程結(jié)點的動態(tài)分配用結(jié)構(gòu)體建立鏈表:

structstudent{intnum;

floatscore;

structstudent*next;};

其中成員num和score用來存放結(jié)點中的有用數(shù)據(jù)(用戶需要用到的數(shù)據(jù)),next是指針類型的成員,它指向structstudent類型數(shù)據(jù)(這就是next所在的結(jié)構(gòu)體類型)教學(xué)進程教學(xué)進程#include<stdio.h>structstudent{longnum;floatscore;

structstudent*next;};voidmain(){structstudenta,b,c,*head,*p;

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

b.num=99103;b.score=90;c.num=99107;c.score=85;用指針處理鏈表10.710.7.2建立簡單的靜態(tài)鏈表【例10.7】建立上圖所示的簡單鏈表,它由個學(xué)生數(shù)據(jù)的節(jié)點組成。輸出個節(jié)點中的數(shù)據(jù)。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);}教學(xué)進程教學(xué)進程建立鏈表指從無到有建立一個鏈表,即一個一個地開辟結(jié)點和輸入各結(jié)點數(shù)據(jù),并建立前后相鏈的關(guān)系,其算法如下:①讀取數(shù)據(jù);②生成新結(jié)點;③將數(shù)據(jù)存入新結(jié)點;④將新結(jié)點插入到鏈表中。重復(fù)上述步驟,直到輸入結(jié)束??梢愿鶕?jù)需要將新結(jié)點插入到鏈表不同位置,如鏈表頭、鏈表中間、鏈表尾等,例10-10將新結(jié)點插入到鏈表尾部。10.7.3創(chuàng)建動態(tài)鏈表

【例10.7】從鍵盤讀入學(xué)生的信息,包括學(xué)號、成績,當輸入的學(xué)號為0時,表示建立鏈表結(jié)束。#include<stdlib.h>#include<alloc.h>#defineLENsizeof(struct

stu)/*LEN為結(jié)構(gòu)體類型struct

stu的長度*/struct

stu{intnum;floatscore;

struct

stu*next;};struct

stu*creat(){struct

stu*head;/*用于指向鏈表的第一個結(jié)點*/struct

stu*p;/*用于指向新生成的結(jié)點*/struct

stu*tail;/*用于指向鏈表的最后一個結(jié)點*/

intx;floaty;tail=head=NULL;

scanf("%d",&x);

while(x!=0){p=(struct

stu*)malloc(LEN);p->num=x;

if(head==NULL)head=p;

scanf("%f",&y);p->score=y;

if(tail!=NULL)tail->next=p;tail=p;

scanf("%d",&x);}

if(tail!=NULL)tail->next=NULL;

return(head);}所謂“訪問”就是對各結(jié)點的數(shù)據(jù)域中的值進行修改、運算、輸出等。例10-11編寫函數(shù),順序輸出鏈表中各結(jié)點數(shù)據(jù)域中的內(nèi)容。順序輸出鏈表的算法比較簡單,只需利用一個指針p從頭到尾依次指向鏈表中的每個結(jié)點,即可以完成順序訪問。10.7.4順序訪問鏈表中的結(jié)點voidlist(struct

stu*head){struct

stu*p;

printf("Thelistrecordsare:\n");p=head;

if(head!=NULL)do{printf("%d\t%5.1f\n",p->num,p->score);p=p->next;}while(p!=NULL);else

printf("Thelistisnull");}main(){struct

stu*head;head=creat();

list(head);}程序運行結(jié)果如下:10190↙10289↙0↙Thelistrecordsare:1019010289共用體類型10.8教學(xué)進程使幾個不同的變量共占同一段內(nèi)存的結(jié)構(gòu)。一般形式union共用體名

{成員表}變量表列;雖然共用體與結(jié)構(gòu)體在定義形式上類似,但它們在存儲空間的分配上是有本質(zhì)區(qū)別的。按照定義中各個成員所需要的存儲空間的總和來分配存儲單元,其中各成員的存儲位置是不同的。結(jié)構(gòu)體按定義中需要存儲空間最大的成員來分配存儲單元,其他成員也使用該空間,它們的首地址是相同的。共用體10.8.1什么是共用體類型共用體教學(xué)進程例如:

uniondatauniondata

{inti;{inti;charch;或charch;floatf;floatf;}a,b,c;};uniondataa,b,c;上面定義的“共用體”變量a、b、c各占4個字節(jié)(因為一個實型變量占4個字節(jié)),而不是各占2+1+4=7個字節(jié)。

溫馨提示

  • 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)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論