版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
第10章自定義數(shù)據(jù)類型鹽城第10章自定義數(shù)據(jù)類型10.1自定義數(shù)據(jù)類型引入10.2結(jié)構(gòu)體類型10.3共用體類型10.4枚舉類型10.5類型定義符10.1自定義數(shù)據(jù)類型引入10.1.1問題與引例C語言提供了一些由系統(tǒng)已經(jīng)定義好的基本數(shù)據(jù)類型,用戶可以使用這些基本數(shù)據(jù)類型解決一般的問題,但這些同時(shí)處理的數(shù)據(jù)往往具有相同數(shù)據(jù)類型。思考:如果一組數(shù)據(jù)具有不同的數(shù)據(jù)類型,如何處理?10.1.1問題與引例【引例】建立一個(gè)學(xué)生登記表,并對學(xué)生的記錄按指定的要求進(jìn)行相應(yīng)的處理。設(shè)在學(xué)生登記表包括:學(xué)號(hào)(整型或字符型)、姓名(字符型)、年齡(整型)、性別(字符型)、成績(整型或?qū)嵭?。要求:①建立學(xué)生登記表;②根據(jù)學(xué)號(hào)進(jìn)行查找;③按成績排序;④輸出排序結(jié)果。問題分析:本例建立的學(xué)生登記表是一個(gè)經(jīng)常使用的二維表,這個(gè)表格由若干行若干列構(gòu)成,每一行是由不同數(shù)據(jù)類型的數(shù)據(jù)組成,顯然每一行的數(shù)據(jù)不能用數(shù)組進(jìn)行存儲(chǔ)和處理,因此,需要用戶定義一種新的數(shù)據(jù)類型來進(jìn)行處理。10.1.1問題與引例10.1.2結(jié)構(gòu)體的概念為了解決上述問題,C語言中可以采用自定義數(shù)據(jù)類型——“結(jié)構(gòu)”或稱為“結(jié)構(gòu)體”,它相當(dāng)于其它高級語言中的記錄。用戶自己建立由不同類型數(shù)據(jù)組成的組合型的數(shù)據(jù)結(jié)構(gòu),它稱為結(jié)構(gòu)體。結(jié)構(gòu)體是由若干“成員”組成的,每一個(gè)成員可以是一個(gè)基本數(shù)據(jù)類型或者又是一個(gè)自定義數(shù)據(jù)類型。10.2結(jié)構(gòu)體類型1.結(jié)構(gòu)體類型的定義聲明一個(gè)結(jié)構(gòu)體類型的一般形式為:struct結(jié)構(gòu)體名{
成員表列
};
由若干個(gè)成員組成,每個(gè)成員都是該結(jié)構(gòu)體的一個(gè)組成部分。其形式為:類型說明符成員名;
類型說明符
成員名;10.2.1結(jié)構(gòu)體類型及其變量的引用
10.2.1結(jié)構(gòu)體類型及其變量的引用
1.結(jié)構(gòu)體類型的定義structStudent{intnum;charname[20];charsex;floatscore;};定義了一個(gè)結(jié)構(gòu)體類型structStudent,它包括num,name,sex,score等4個(gè)不同類型的成員結(jié)構(gòu)體類型名和成員名遵循標(biāo)識(shí)符命名規(guī)則注意:花括號(hào)后面的分號(hào)是不可少的。結(jié)構(gòu)體定義之后,即可進(jìn)行變量定義,凡說明為結(jié)構(gòu)體student的變量都由上述4個(gè)成員組成。結(jié)構(gòu)體是一種復(fù)雜的數(shù)據(jù)類型,是數(shù)目固定、類型不同的若干個(gè)有序變量或數(shù)組的集合。10.2.1結(jié)構(gòu)體類型及其變量的引用
2.結(jié)構(gòu)體類型變量的定義定義結(jié)構(gòu)體變量有以下三種方法:(1)先定義結(jié)構(gòu)體類型,再聲明該類型變量例如:structstudent//結(jié)構(gòu)體類型定義{intnum;charname[20];charsex;floatscore;};10.2.1結(jié)構(gòu)體類型及其變量的引用
2.結(jié)構(gòu)體類型變量的定義定義結(jié)構(gòu)體變量有以下三種方法:(1)先定義結(jié)構(gòu)體類型,再聲明該類型變量結(jié)構(gòu)體類型名結(jié)構(gòu)體變量名
//結(jié)構(gòu)體類型變量聲明structStudentboy1,boy2;10.2.1結(jié)構(gòu)體類型及其變量的引用
2.結(jié)構(gòu)體類型變量的定義定義結(jié)構(gòu)體變量有以下三種方法:(2)在定義結(jié)構(gòu)體類型的同時(shí)聲明結(jié)構(gòu)體變量定義的一般形式為:struct結(jié)構(gòu)體名{成員表列}變量名表列;例如:structstudent{intnum;charname[20];charsex;floatscore;}boy1,boy2;10.2.1結(jié)構(gòu)體類型及其變量的引用
2.結(jié)構(gòu)體類型變量的定義定義結(jié)構(gòu)體變量有以下三種方法:(3)直接定義結(jié)構(gòu)體變量定義的一般形式為:struct{成員表列}變量名表列;例如:struct{
intnum;charname[20];charsex;floatscore;}boy1,boy2;10.2.1結(jié)構(gòu)體類型及其變量的引用
說明:(1)結(jié)構(gòu)體類型并非只有一種,而是可以設(shè)計(jì)出許多種結(jié)構(gòu)體類型,例如structTeacherstructWorkerstructDate等結(jié)構(gòu)體類型各自包含不同的成員10.2.1結(jié)構(gòu)體類型及其變量的引用
說明:(2)結(jié)構(gòu)體成員也可以屬于另一個(gè)結(jié)構(gòu)體類型
structDate
{intmonth;
intday;intyear;
};
structStu
{intnum;charname[20];charsex;intage;
structDatebirthday;
charaddr[30];
};numnamesexagebirthdayaddrmonthdayyear10.2.1結(jié)構(gòu)體類型及其變量的引用
3.結(jié)構(gòu)體類型變量的引用在ANSIC中除了允許具有相同類型的結(jié)構(gòu)變量相互賦值以外,一般對結(jié)構(gòu)體變量的使用,包括賦值、輸入、輸出、運(yùn)算等都是通過結(jié)構(gòu)體變量的成員來實(shí)現(xiàn)的。結(jié)構(gòu)體變量成員引用的一般形式:結(jié)構(gòu)體變量名.成員名10.2.1結(jié)構(gòu)體類型及其變量的引用
3.結(jié)構(gòu)體類型變量的引用例如:boy1.num//第一個(gè)學(xué)生的學(xué)號(hào)boy2.sex//第二個(gè)學(xué)生的性別如果結(jié)構(gòu)體變量成員本身又是一個(gè)結(jié)構(gòu)體,則必須逐級找到最低級的成員才能使用。例如:boy1.birthday.month10.2.1結(jié)構(gòu)體類型及其變量的引用
4.結(jié)構(gòu)體類型變量的賦值---按成員逐個(gè)賦值結(jié)構(gòu)體變量的賦值就是給各個(gè)成員賦值,可用輸入語句或賦值語句來完成。//結(jié)構(gòu)體成員賦值boy1.num=10001;="ZhangXin";10001ZhangXinM1990.5Shanghaiboy110.2.1結(jié)構(gòu)體類型及其變量的引用
例如:把一個(gè)學(xué)生的信息(包括學(xué)號(hào)、姓名、性別、地址)放在一個(gè)結(jié)構(gòu)體變量中,然后輸出這個(gè)學(xué)生的信息。解題思路:自己建立一個(gè)結(jié)構(gòu)體類型,包括有關(guān)學(xué)生信息的各成員用它定義結(jié)構(gòu)體變量,同時(shí)賦以初值輸出該結(jié)構(gòu)體變量的各成員10.2.1結(jié)構(gòu)體類型及其變量的引用
#include<stdio.h>voidmain(){structStudent{longintnum;charname[20];charsex;charaddr[20];}a={10101,"LiLin",’M’,"123BeijingRoad"};printf("NO.:%ld\nname:%s\nsex:%c\naddress:%s\n",
a.num,,a.sex,a.addr);}#include<stdio.h>voidmain(){structStudent{longintnum;charname[20];charsex;charaddr[20];}a={10101,"LiLin",’M’,"123BeijingRoad"};printf("NO.:%ld\nname:%s\nsex:%c\naddress:%s\n",a.num,,a.sex,a.addr);}#include<stdio.h>voidmain(){structStudent{longintnum;charname[20];charsex;charaddr[20];}a={10101,"LiLin",’M’,"123BeijingRoad"};……}a.num=10010;對printf("%s\n",a);不對#include<stdio.h>voidmain(){structStudent
{longintnum;charname[20];charsex;charaddr[20];}a={10101,”LiLin”,’M’,”123BeijingRoad”};……}b=a;對structStudentb;b.num++;對10.2.2結(jié)構(gòu)體數(shù)組1.結(jié)構(gòu)體數(shù)組定義數(shù)組的元素也可以是結(jié)構(gòu)體類型的,因此可以構(gòu)成結(jié)構(gòu)體數(shù)組。結(jié)構(gòu)體數(shù)組的每一個(gè)元素都是具有相同結(jié)構(gòu)體類型的下標(biāo)結(jié)構(gòu)體變量。在實(shí)際應(yīng)用中,經(jīng)常用結(jié)構(gòu)體數(shù)組來表示具有相同數(shù)據(jù)結(jié)構(gòu)的一個(gè)群體。如:一個(gè)班級的學(xué)生檔案、一個(gè)車間的職工信息等。10.2.2結(jié)構(gòu)體數(shù)組1.結(jié)構(gòu)體數(shù)組定義定義結(jié)構(gòu)體數(shù)組的一般形式:struct結(jié)構(gòu)體名{成員表列}數(shù)組名[常量表達(dá)式];1.結(jié)構(gòu)體數(shù)組定義例如:structstudent{intnum;char*name;charsex;floatscore;}boy[5];定義了一個(gè)結(jié)構(gòu)體數(shù)組boy,共有5個(gè)元素,boy[0]~boy[4]。每個(gè)數(shù)組元素都具有structstudent的結(jié)構(gòu)體形式,對結(jié)構(gòu)體數(shù)組可以進(jìn)行初始化賦值。10.2.2結(jié)構(gòu)體數(shù)組2.結(jié)構(gòu)體數(shù)組的初始化結(jié)構(gòu)體數(shù)組的初始化是在定義結(jié)構(gòu)體數(shù)組時(shí),在結(jié)構(gòu)體數(shù)組的后面加上初值表列。一般形式如下:struct結(jié)構(gòu)體名{成員表列}數(shù)組名[常量表達(dá)式]={初值表列};10.2.2結(jié)構(gòu)體數(shù)組2.結(jié)構(gòu)體數(shù)組初始化例如://定義結(jié)構(gòu)體數(shù)組的同時(shí)初始化structstudent{intnum;char*name;charsex;floatscore;}boy[3]={{101,"Liping",'M',45},{102,"Zhangping",'M',62.5},{103,"Hefang",'F',92.5}};10.2.2結(jié)構(gòu)體數(shù)組【例10.1】計(jì)算學(xué)生的平均成績和不及格的人數(shù)。(1)算法分析本例先定義一個(gè)結(jié)構(gòu)體數(shù)組boy,并初始化;然后將結(jié)構(gòu)體數(shù)組中每一個(gè)元素的score成員的值求和,若小于60,則計(jì)數(shù);最后求出平均成績。10.2.2結(jié)構(gòu)體數(shù)組(2)程序設(shè)計(jì)#include<stdio.h>structstudent{intnum;char*name;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}};10.2.2結(jié)構(gòu)體數(shù)組主函數(shù):voidmain(){inti,c=0;floatave,s=0;for(i=0;i<5;i++){s+=boy[i].score;//結(jié)構(gòu)體數(shù)組元素的score成員求和
if(boy[i].score<60)c+=1;//score成員小于60時(shí),計(jì)數(shù)
}ave=s/5;printf("average=%f\ncount=%d\n",ave,c);}10.2.3結(jié)構(gòu)體指針1.指向結(jié)構(gòu)體變量的指針當(dāng)用一個(gè)指針變量來指向一個(gè)結(jié)構(gòu)體變量時(shí),這個(gè)指針變量就稱之為結(jié)構(gòu)體指針變量。結(jié)構(gòu)體指針變量中的值是所指向的結(jié)構(gòu)體變量的首地址,通過結(jié)構(gòu)體指針變量即可訪問該結(jié)構(gòu)體變量,類似于數(shù)組指針。定義結(jié)構(gòu)體指針變量定義的一般形式:
struct結(jié)構(gòu)體名*結(jié)構(gòu)體指針變量名10.2.3結(jié)構(gòu)體指針1.指向結(jié)構(gòu)體變量的指針指向結(jié)構(gòu)體對象的指針變量既可以指向結(jié)構(gòu)體變量,也可以用來指向結(jié)構(gòu)體數(shù)組中的元素。指針變量的基類型必須與結(jié)構(gòu)體變量的類型相同。例如:structStudent*pt;10.2.3結(jié)構(gòu)體指針【例10.2】結(jié)構(gòu)體指針變量的使用。#include<stdio.h>structstudent{intnum;char*name;charsex;floatscore;}boy1={102,"Zhangping",'M',78.5},*p;voidmain(){p=&boy1;printf("Number=%d\nName=%s\n",boy1.num,);printf("Sex=%c\nScore=%f\n\n",boy1.sex,boy1.score);printf("Number=%d\nName=%s\n",(*p).num,(*p).name);printf("Sex=%c\nScore=%f\n\n",(*p).sex,(*p).score);printf("Number=%d\nName=%s\n",p->num,p->name);printf("Sex=%c\nScore=%f\n\n",p->sex,p->score);}2.用指針訪問結(jié)構(gòu)體變量成員訪問結(jié)構(gòu)體變量成員的一般形式:(*結(jié)構(gòu)體指針變量).成員名或?yàn)椋航Y(jié)構(gòu)體指針變量->成員名(更靈活高效)例如:(*p).num或者:p->num注意:(*p)兩側(cè)的括號(hào)不可少。因?yàn)槌蓡T符“.”的優(yōu)先級高于“*”。10.2.3結(jié)構(gòu)體指針3.指向結(jié)構(gòu)體數(shù)組的指針指針變量可以指向一個(gè)結(jié)構(gòu)體數(shù)組,這時(shí)結(jié)構(gòu)體指針變量的值是整個(gè)結(jié)構(gòu)體數(shù)組首元素的首地址。
結(jié)構(gòu)體指針變量也可以指向結(jié)構(gòu)體數(shù)組中的一個(gè)元素,這時(shí)結(jié)構(gòu)體指針變量的值是該結(jié)構(gòu)體數(shù)組元素的首地址。10.2.3結(jié)構(gòu)體指針【例10.3】用指針變量輸出結(jié)構(gòu)體數(shù)組。#include<stdio.h>structstudent{intnum;char*name;charsex;floatscore;}boy[5]={{101,"Zhouping",'M',45},{102,"Zhangping",'M',62.5},{103,"Lioufang",'F',92.5},{104,"Chengling",'F',87},{105,"Wangming",'M',58}};boy為外部結(jié)構(gòu)體數(shù)組,整個(gè)源程序有效主函數(shù):voidmain(){structstudent*ps;
printf("No\tName\t\t\tSex\tScore\t\n");for(ps=boy;ps<boy+5;ps++)
printf("%d\t%s\t\t%c\t%f\t\n",ps->num,ps->name,ps->sex,ps->score);}ps為指向結(jié)構(gòu)體student類型的指針ps指向boy數(shù)組的第一個(gè)元素,然后進(jìn)行循環(huán)說明:為了使用方便和直觀,C語言允許把(*p).num用p->num來代替(*p).name等價(jià)于p->name如果p指向一個(gè)結(jié)構(gòu)體變量stu,以下等價(jià):①stu.成員名(如stu.num)②(*p).成員名(如(*p).num)p->成員名(如p->num)【例10.4】用結(jié)構(gòu)體指針變量作為函數(shù)的參數(shù)求一組學(xué)生的平均成績和不及格人數(shù)。(1)解決問題的幾個(gè)主要步驟①結(jié)構(gòu)體類型定義;②結(jié)構(gòu)體類型數(shù)組定義及初始化;③定義結(jié)構(gòu)體指針變量;④數(shù)據(jù)處理;⑤輸出。(2)算法分析
先定義一個(gè)結(jié)構(gòu)體數(shù)組boy,并初始化;然后再定義一個(gè)指向結(jié)構(gòu)體數(shù)組的指針,使用指針將結(jié)構(gòu)體數(shù)組中每一個(gè)元素的score成員的值求和,若小于60,則計(jì)數(shù);最后求出平均成績。(3)部分程序代碼//結(jié)構(gòu)體類型定義,結(jié)構(gòu)體數(shù)組定義并賦值structstudent{intnum;char*name;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}};(3)部分程序代碼//計(jì)算平均值的函數(shù)voidaverage(structstudent*ps){intc=0,i;floatave,s=0;for(i=0;i<5;i++,ps++){s+=ps->score;if(ps->score<60)c+=1;}printf("s=%f\n",s);ave=s/5;printf("average=%f\ncount=%d\n",ave,c);}10.2.4鏈表由前可知:
數(shù)組在存儲(chǔ)器中占用一段連續(xù)的存儲(chǔ)空間,若要在數(shù)組中插入新的元素或要在數(shù)組中刪除一個(gè)元素,都要移動(dòng)大量數(shù)組元素。思考:有沒有更好的數(shù)據(jù)結(jié)構(gòu)來處理插入刪除操作,且不需要移動(dòng)元素呢?1.什么是鏈表鏈表是一種常見的重要的數(shù)據(jù)結(jié)構(gòu),它是動(dòng)態(tài)地進(jìn)行存儲(chǔ)分配的一種結(jié)構(gòu)使用鏈表可以方便實(shí)現(xiàn)元素的插入或刪除鏈表必須利用指針變量才能實(shí)現(xiàn)10.2.4鏈表鏈表由若干個(gè)結(jié)點(diǎn)鏈接而成的,每個(gè)結(jié)點(diǎn)是一個(gè)結(jié)構(gòu)體。在結(jié)點(diǎn)結(jié)構(gòu)中第一個(gè)結(jié)點(diǎn)稱為頭結(jié)點(diǎn),它存放有第一個(gè)結(jié)點(diǎn)的首地址。以后的每個(gè)結(jié)點(diǎn)都分為兩個(gè)域:數(shù)據(jù)域、指針域。存放時(shí),在第一個(gè)結(jié)點(diǎn)的指針域內(nèi)存入第二個(gè)結(jié)點(diǎn)的首地址,在第二個(gè)結(jié)點(diǎn)的指針域內(nèi)又存放第三個(gè)結(jié)點(diǎn)的首地址,如此下去直到最后一個(gè)結(jié)點(diǎn)。最后一個(gè)結(jié)點(diǎn)因無后繼結(jié)點(diǎn)連接,其指針域可賦為0或NULL。這樣一種連接方式,在數(shù)據(jù)結(jié)構(gòu)中稱為“鏈表”。10.2.4鏈表head12491249A135613561475B1475C10211021DNULL頭指針各結(jié)點(diǎn)地址可以不連續(xù)各結(jié)點(diǎn)含有兩個(gè)部分表尾由圖看出,鏈表中的各元素在內(nèi)存中不一定是連續(xù)存放的。鏈表的基本操作主要有:建立鏈表、結(jié)點(diǎn)的查找與輸出、結(jié)點(diǎn)的插入、結(jié)點(diǎn)的刪除等。下圖是一種簡單的鏈表結(jié)構(gòu)10.2.4鏈表2.建立與輸出靜態(tài)單向鏈表建立簡單靜態(tài)鏈表的主要步驟:(1)定義一個(gè)結(jié)構(gòu)體類型,其成員由具體問題決定。(2)將第一個(gè)結(jié)點(diǎn)的起始地址賦給頭指針,第二個(gè)結(jié)點(diǎn)的起始地址賦給第一個(gè)結(jié)點(diǎn)的指針域,第三個(gè)結(jié)點(diǎn)的起始地址賦給第二個(gè)結(jié)點(diǎn)的指針域,……(3)將最后一個(gè)結(jié)點(diǎn)的指針域賦予NULL。10.2.4鏈表2.建立與輸出靜態(tài)單向鏈表【例10.5】
建立一個(gè)如圖所示的簡單鏈表,它由3個(gè)學(xué)生數(shù)據(jù)的結(jié)點(diǎn)組成,要求輸出各結(jié)點(diǎn)中的數(shù)據(jù)。1010189.510103901010785a結(jié)點(diǎn)b結(jié)點(diǎn)c結(jié)點(diǎn)numscorenext10.2.4鏈表解題思路:1010189.510103901010785a結(jié)點(diǎn)b結(jié)點(diǎn)c結(jié)點(diǎn)numscorenextheadhead=&a;a.next=&b;b.next=&c;NULLc.next=NULL;10.2.4鏈表定義結(jié)點(diǎn):#include<stdio.h> structStudent{intnum;floatscore;
structStudent*next;//結(jié)構(gòu)體指針};voidmain()//主函數(shù){structStudenta,b,c,*head,*p;a.num=10101;a.score=89.5;b.num=10103;b.score=90;c.num=10107;c.score=85;//分別初始化head=&a;a.next=&b;//結(jié)點(diǎn)連接b.next=&c;c.next=NULL;p=head;//p指向頭結(jié)點(diǎn)
do{printf(”%ld%5.1f\n”,p->num,p->score);p=p->next; }while(p!=NULL);//依次輸出每個(gè)結(jié)點(diǎn)的值}
p=head;do{printf(”%ld%5.1f\n”,p->num,p->score);p=p->next; }while(p!=NULL);}1010189.510103901010785a結(jié)點(diǎn)b結(jié)點(diǎn)c結(jié)點(diǎn)numscorenextheadNULLp相當(dāng)于p=&b;
p=head;do{printf(”%ld%5.1f\n”,p->num,p->score);p=p->next; }while(p!=NULL);}1010189.510103901010785a結(jié)點(diǎn)b結(jié)點(diǎn)c結(jié)點(diǎn)numscorenextheadNULLp相當(dāng)于p=&b;
p=head;do{printf(”%ld%5.1f\n”,p->num,p->score);p=p->next; }while(p!=NULL);}1010189.510103901010785a結(jié)點(diǎn)b結(jié)點(diǎn)c結(jié)點(diǎn)numscorenextheadNULLp相當(dāng)于p=&c;
p=head;do{printf(”%ld%5.1f\n”,p->num,p->score);p=p->next; }while(p!=NULL);}1010189.510103901010785a結(jié)點(diǎn)b結(jié)點(diǎn)c結(jié)點(diǎn)numscorenextheadNULLp相當(dāng)于p=&c;
p=head;do{printf(”%ld%5.1f\n”,p->num,p->score);p=p->next; }while(p!=NULL);}1010189.510103901010785a結(jié)點(diǎn)b結(jié)點(diǎn)c結(jié)點(diǎn)numscorenextheadNULLp相當(dāng)于p=NULL;靜態(tài)鏈表3.建立與輸出動(dòng)態(tài)單向鏈表
所謂建立動(dòng)態(tài)鏈表是指在程序執(zhí)行過程中從無到有地建立起一個(gè)鏈表,即一個(gè)一個(gè)地開辟結(jié)點(diǎn)和輸入各結(jié)點(diǎn)數(shù)據(jù),并建立起前后相鏈的關(guān)系。10.2.4鏈表3.建立與輸出動(dòng)態(tài)單向鏈表(1)處理動(dòng)態(tài)鏈表所需要的庫函數(shù)①malloc()函數(shù);②calloc()函數(shù);③free()函數(shù)(2)建立動(dòng)態(tài)單向鏈表的步驟①讀取數(shù)據(jù);②生成新結(jié)點(diǎn);③將數(shù)據(jù)存入結(jié)點(diǎn)的成員變量中;④將新結(jié)點(diǎn)插入到鏈表中,重復(fù)上述操作直至輸入結(jié)束。10.2.4鏈表4.在鏈表中插入結(jié)點(diǎn)對鏈表的插入是指將一個(gè)結(jié)點(diǎn)插入到已有的鏈表之中。在單向鏈表中插入結(jié)點(diǎn),首先要確定插入的位置。插入結(jié)點(diǎn)在指針p所指的結(jié)點(diǎn)之前稱為“前插”,插入結(jié)點(diǎn)在指針p所指的結(jié)點(diǎn)之后稱為“后插”。10.2.4鏈表4.在鏈表中插入結(jié)點(diǎn)當(dāng)進(jìn)行前插操作時(shí),需要3個(gè)工作指針:s指向新開辟的結(jié)點(diǎn);用p指向插入的位置;q指向要插入的前趨結(jié)點(diǎn)。為了能做到正確插入,必須解決兩個(gè)問題:怎樣找到插入的位置;怎樣實(shí)現(xiàn)插入。具體實(shí)現(xiàn)過程在后續(xù)課程數(shù)據(jù)結(jié)構(gòu)中進(jìn)一步研究10.2.4鏈表5.刪除鏈表中的結(jié)點(diǎn)從一個(gè)動(dòng)態(tài)鏈表中刪去一個(gè)結(jié)點(diǎn),并不是真正從內(nèi)存中把它抹掉,而是把它從鏈表中分離開來,只要撤銷原來的鏈接關(guān)系即可。為了刪除單向鏈表中的某個(gè)結(jié)點(diǎn),首先要找到待刪除的結(jié)點(diǎn)的前趨結(jié)點(diǎn)(即當(dāng)前要?jiǎng)h除結(jié)點(diǎn)的前面一個(gè)結(jié)點(diǎn)),然后將此前趨結(jié)點(diǎn)的指針域去指向待刪除結(jié)點(diǎn)的后繼結(jié)點(diǎn)(即當(dāng)前要?jiǎng)h除結(jié)點(diǎn)的下一個(gè)結(jié)點(diǎn)),最后釋放被刪除結(jié)點(diǎn)所占的存儲(chǔ)空間即可。10.2.4鏈表10.3共用體類型10.3.1共用體類型定義10.3.2共用體變量的定義10.3.3共用體變量中成員的引用10.3共用體類型10.3.1共用體類型定義共用體是用同一段存儲(chǔ)空間存放不同類型的變量。使幾個(gè)不同的變量共享同一段內(nèi)存的結(jié)構(gòu),稱為“共用體”類型的結(jié)構(gòu)。10.3.1共用體類型定義
共用體的類型及其變量的定義和與結(jié)構(gòu)體類型及其變量定義的方式基本相同。
不同的是結(jié)構(gòu)體中變量中的成員各自占有不同的存儲(chǔ)空間,而共用體的變量中的所有成員占有同一段存儲(chǔ)空間。1000100110021003字符ch整型變量i實(shí)型變量f10.3.1共用體類型定義定義共用體類型的一般形式為:union共用體名{成員表列
};例如:unionData
{inti;
charch;
floatf;
};10.3.1共用體類型定義定義共用體類型變量的一般形式為:union共用體名{成員表列
}變量表列;例如:unionData
{inti;
charch;
floatf;
}a,b,c;unionData
{inti;charch;
floatf;
};unionDataa,b,c;10.3.2共用體變量的定義“共用體”與“結(jié)構(gòu)體”的定義形式相似,但它們的含義是不同的。結(jié)構(gòu)體變量所占內(nèi)存長度是各成員占的內(nèi)存長度之和,每個(gè)成員分別占有其自己的內(nèi)存單元。而共用體變量所占的內(nèi)存長度等于最長的成員的長度。10.3.2共用體變量的定義共用體變量中成員的引用方式共用體變量中每個(gè)成員的引用方式與結(jié)構(gòu)體變量完全相同,可以使用下列3種形式之一:(1)共用體變量名.成員名。(2)指針變量名->成員名。(3)(*指針變量名).成員名。例如,前面定義了a,b,c為共用體變量,下面的引用方式是正確的:a.ia.cha.f10.3.3共用體變量中成員的引用2.共用體類型數(shù)據(jù)的特點(diǎn)
同一內(nèi)存段可以用來存放幾種不同類型的成員,但在每一瞬時(shí)只能存放其中一個(gè)成員,而不是同時(shí)存放幾個(gè)。(2)可以對共用體變量初始化,但初始化表中只能有一個(gè)常量。(3)共用體變量中起作用的成員是最后一次被賦值的成員,在對共用體變量中的一個(gè)成員賦值后,原有變量存儲(chǔ)單元中的值就取代。10.3.3共用體變量中成員的引用(4)共用體變量的地址和它的各成員的地址都是同一地址。(5)
不能對共用體變量名賦值,也不能企圖引用變量名來得到一個(gè)值。(6)以前的C規(guī)定不能把共用體變量作為函數(shù)參數(shù),但可以使用指向共用體變量的指針作函數(shù)參數(shù)。(7)共用體類型可以出現(xiàn)在結(jié)構(gòu)體類型定義中,也可以定義共用體數(shù)組。反之,結(jié)構(gòu)體也可以出現(xiàn)在共用體類型定義中,數(shù)組也可以作為共用體的成員。10.3.3共用體變量中成員的引用【例10.6】分析下列程序的運(yùn)行結(jié)果。#include<stdio.h>uniondata{shortd[2];charch[4];};voidmain(){inti;uniondatada;for(i=0;i<4;i++) da.ch[i]=i;for(i=0;i<2;i++) printf("%8d",da.d[i]);printf("\n");}
【例10.7】有n個(gè)結(jié)構(gòu)體變量,內(nèi)含學(xué)生學(xué)號(hào)、姓名和3門課程的成績。要求輸出平均成績最高的學(xué)生的信息(包括學(xué)號(hào)、姓名、3門課程成績和平均成績)。算法分析:本例中教師和學(xué)生信息的前4項(xiàng)是相同的,只有第5項(xiàng)不同?,F(xiàn)要求采用一個(gè)表格處理,故可以定義一個(gè)結(jié)構(gòu)體,前4個(gè)成員表示教師和學(xué)生信息的前4項(xiàng),第5項(xiàng)用共用體處理。#include<stdio.h>#defineN3structStudent{intnum;charname[20];
floatscore[3];floataver;};4個(gè)成員輸入前3個(gè)成員值三門課程的平均成績voidmain(){voidinput(structStudentstu[]);structStudentmax(structStudentstu[]);voidprint(structStudentstu);structStudentstu[N],*p=stu;input(p);print(max(p));}voidinput(structStudentstu[]){inti;printf("請輸入各學(xué)生的信息:
學(xué)號(hào)、姓名、三門課成績:\n");for(i=0;i<N;i++){scanf("%d%s%f%f%f",&stu[i].num,stu[i].name,&stu[i].score[0],&stu[i].score[1],&stu[i].score[2]);
stu[i].aver=(stu[i].score[0]+stu[i].score[1]+stu[i].score[2])/3.0;}}stu[0]stu[1]stu[2]stu10101Li78899888.33voidinput(structStudentstu[]){inti;printf("請輸入各學(xué)生的信息:
學(xué)號(hào)、姓名、三門課成績:\n");for(i=0;i<N;i++){scanf("%d%s%f%f%f",&stu[i].num,stu[i].name,&stu[i].score[0],&stu[i].score[1],&stu[i].score[2]);
stu[i].aver=(stu[i].score[0]+stu[i].score[1]+stu[i].score[2])/3.0;}}stu[0]stu[1]stu[2]stu10101Li78899888.3310103Wang98.5876984.83voidinput(structStudentstu[]){inti;printf("請輸入各學(xué)生的信息:
學(xué)號(hào)、姓名、三門課成績:\n");for(i=0;i<N;i++){scanf("%d%s%f%f%f",&stu[i].num,stu[i].name,&stu[i].score[0],&stu[i].score[1],&stu[i].score[2]);
stu[i].aver=(stu[i].score[0]+stu[i].score[1]+stu[i].score[2])/3.0;}}stu[0]stu[1]stu[2]stu10101Li78899888.3310103Wang98.5876984.8310106Sun8876.58984.5structStudentmax(structStudentstu[]){inti,m=0;for(i=0;i<N;i++)if(stu[i].aver>stu[m].aver)m=i;returnstu[m];}
stu[0]stu[1]stu[2]stu10101Li78899888.3310103Wang98.5876984.8310106Sun8876.58984.5最大返回voidprint(structStudentstud){printf("\n成績最高的學(xué)生是:\n"); printf("學(xué)號(hào):%d\n姓名:%s\n
三門課成績:%5.1f,%5.1f,%5.1f\n
平均成績:%6.2f\n”,stud.num,,stud.score[0],stud.score[1],stud.score[2],stud.aver);}stud10101Li78899888.3310103Wang98.5876984.8310106Sun8876.58984.5numnamescoreaverstu[0]stu[1]stu[2]以上3個(gè)函數(shù)的調(diào)用,情況各不相同:調(diào)用input函數(shù)時(shí),實(shí)參是指針變量,形參是結(jié)構(gòu)體數(shù)組,傳遞的是結(jié)構(gòu)體元素的地址,函數(shù)無返回值。調(diào)用max函數(shù)時(shí),實(shí)參是指針變量,形參是結(jié)構(gòu)體數(shù)組,傳遞的是結(jié)構(gòu)體元素的地址,函數(shù)的返回值是結(jié)構(gòu)體類型數(shù)據(jù)。調(diào)用print函數(shù)時(shí),實(shí)參是結(jié)構(gòu)體變量,形參是結(jié)構(gòu)體變量,傳遞的是結(jié)構(gòu)體變量中各成員的值,函數(shù)無返回值。10.4枚舉類型如果一個(gè)變量只有幾種可能的值,則可以定義為枚舉類型所謂“枚舉”就是指把可能的值一一列舉出來,變量的值只限于列舉出來的值的范圍內(nèi)10.4.1枚舉類型及其變量的定義1.枚舉類型定義的一般形式enum
枚舉名{枚舉值表};在枚舉值表中應(yīng)列出所有可能的值,這些值也稱為枚舉元素。例如:enumweekday{sun,mon,tue,wed,thu,fri,sat};該枚舉名為weekday,枚舉元素共有7個(gè),即一周中的七天。凡被說明為weekday類型變量的取值只能是七天中的某一天。枚舉元素10.4枚舉類型2.枚舉類型變量的定義如同結(jié)構(gòu)體和共用體一樣,枚舉類型的變量也可用三種不同的方式進(jìn)行定義。定義枚舉類型變量的一般形式:enum枚舉名{枚舉值表}枚舉類型變量表列;然后可以用此類型來定義變量enumWeekdayworkday,weekend;10.4.1枚舉類型及其變量的定義(1)enum是關(guān)鍵字,標(biāo)識(shí)枚舉類型。(2)在定義時(shí),花括號(hào)中的枚舉元素是用戶自己指定的標(biāo)識(shí)符。例如:enumcolor{red,yellow,blue,white,black}c1,c2;(3)枚舉元素的值是一些整數(shù)。一般從第一個(gè)名字開始,各名字分別代表0、1、2、3、4,但不能enumcolor{0,1,2,3,4};。(4)可以在定義時(shí)對枚舉元素初始化enumcolor{red=3,yellow,blue,white=8,black};10.4.1枚舉類型及其變量的定義1.枚舉類型的使用規(guī)定(1)枚舉值是常量,不是變量。不能在程序中用賦值語句再對它賦值。例如:對枚舉weekday的元素再作以下賦值:sun=5;mon=2;sun=mon;都是錯(cuò)誤的。10.4.2枚舉類型變量的使用(2)枚舉元素本身由系統(tǒng)定義了一個(gè)表示序號(hào)的數(shù)值,從0開始順序定義為0,1,2,…。如在weekday中,sun值為0,mon值為1,…,sat值為6。2.枚舉類型的使用說明(1)只能把枚舉值賦給枚舉類型的變量,不能把元素的數(shù)值直接賦予枚舉變量。如果一定要把數(shù)值賦予枚舉變量,則必須用強(qiáng)制類型轉(zhuǎn)換。(2)枚舉元素不是字符常量也不是字符串常量,使用時(shí)不要加單、雙引號(hào)。10.4.2枚舉類型變量的使用10.5類型定義符C語言不僅提供了豐富的數(shù)據(jù)類型,而且還允許由用戶自己定義類型說明符,也就是說允許由用戶為數(shù)據(jù)類型取“別名”——類型定義符typedef10.5.1類型定義符的形式1.類型定義符的一般形式typedef原類型名新類型名其中原類型名中含有定義部分,新類型名一般用大寫表示。例如:typedefintINTEGER;typedeffloatREAL;10.5類型定義符1.typedef定義類型的方法先按定義變量的方法寫出定義體
將變量名換成新類型名(3)在最前面加typedef(4)然后可以用新類型名去定義變量
typedefintINTEGER;typedeffloatREAL;inti,j;floata,b;
與INTEGERi,j;REALa,b;
等價(jià)10.5.2typedef定義類型類型定義符的使用舉例:(1)命名一個(gè)新的類型名代表復(fù)雜結(jié)構(gòu)體類型:
typedefstruct{intmonth;intday;intyear;}Date;Datebirthday,*p;等價(jià)于typedefstructbirthday,*p;(2)命名一個(gè)新的類型名代表數(shù)組類型typedefintNum[100];Numa;10.5.2typedef定義類型以定義上述的數(shù)組類型為例來說明:①先按定義數(shù)組變量形式書寫:inta[100];②將變量名a換成自己命名的類型名:intNum[100];
③在前面加上typedef,得到typedefintNum[100];
用來定義變量:Numa;
相當(dāng)于定義了:inta[100];10.5.2typedef定義類型對字符指針類型,也是:char*p;
char*String;typedefchar*String;Stringp;10.5.2typedef定義類型2.typedef定義類型的說明(1)用typedef可以聲明各種類型名,但不能用來定義變量。
(2)用typedef只是對已經(jīng)存在的類型指定一個(gè)新的類型名,而沒有創(chuàng)造新的類型。(3)用typedef聲明數(shù)組類型、指針類型,結(jié)構(gòu)體類型、共用體類型、枚舉類型等,使得編程更方便。(4)typedef與#define表面上有相似之處10.5.2typedef定義類型2.typedef定義類型的說明(5)當(dāng)不同源文件中用到同一類型數(shù)據(jù)時(shí),常用typedef聲明一些數(shù)據(jù)類型??梢园阉械膖ypedef名稱聲明單獨(dú)放在一個(gè)頭文件中,然后在需要用到它們的文件中用#include指令把它們包含到文件中。這樣編程者就不需要在各文件中自己定義typedef名稱了。(6)用typedef名稱有利于程序的通用與移植。10.5.2typedef定義類型10.6自定義數(shù)據(jù)類型程序設(shè)計(jì)及實(shí)例【例10.11】建立一個(gè)三個(gè)結(jié)點(diǎn)的動(dòng)態(tài)單向鏈表,存放學(xué)生的數(shù)據(jù)(設(shè)學(xué)生的數(shù)據(jù)包含學(xué)號(hào)和成績兩項(xiàng))。解題思路:定義3個(gè)指針變量:head,p1和p2,它們都是用來指向structStudent類型數(shù)據(jù)structstudent//定義結(jié)構(gòu)體student類型{longnum;floatscore;structstudent*next;};structStudent*head,*p1,*p2;解題思路:用malloc函數(shù)開辟第一個(gè)結(jié)點(diǎn),并使p1和p2指向它p1#defineLENsizeof(structstudent)p1=p2=(structStudent*)malloc(LEN);p2解題思路:讀入一個(gè)學(xué)生的數(shù)據(jù)給p1所指的第一個(gè)結(jié)點(diǎn)p1scanf("%ld,%f",&p1->num,&p1->score);p21010189.5解題思路:讀入一個(gè)學(xué)生的數(shù)據(jù)給p1所指的第一個(gè)結(jié)點(diǎn)使head也指向新開辟的結(jié)點(diǎn)headp1p2scanf("%ld,%f",&p1->num,&p1->score);1010189.5解題思路:再開辟另一個(gè)結(jié)點(diǎn)并使p1指向它,接著輸入該結(jié)點(diǎn)的數(shù)據(jù)headp1p21010189
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025湖南省建筑安全員《C證》考試題庫及答案
- 2025甘肅省建筑安全員-C證(專職安全員)考試題庫
- 2025年山西省建筑安全員A證考試題庫及答案
- XX科技集團(tuán)開工大吉課件模板
- 班主任工作經(jīng)驗(yàn)交流52
- 《心理健康案例》課件
- 《撲動(dòng)及纖顫》課件
- 三年級科學(xué)復(fù)習(xí)
- 單位人力資源管理制度范文大全十篇
- 單位管理制度展示大全人員管理篇
- 手術(shù)室安全核查制度及流程課件
- 2024-2025學(xué)年高中英語選擇性必修 第二冊北師大版(2019)教學(xué)設(shè)計(jì)合集
- 高標(biāo)準(zhǔn)農(nóng)田跟蹤審計(jì)、工程中間計(jì)量、變更價(jià)格調(diào)整及竣工結(jié)算審核項(xiàng)目 投標(biāo)方案(技術(shù)方案)
- 感恩節(jié)英文課件
- 慈溪市2024-2025學(xué)年四上數(shù)學(xué)期末教學(xué)質(zhì)量檢測模擬試題含解析
- 人教版小學(xué)一年級語文上冊全冊試卷全套含答案
- 2025年高考化學(xué)二、三輪復(fù)習(xí)策略講座
- 2024-2025學(xué)年哈爾濱市平房區(qū)四上數(shù)學(xué)期末調(diào)研試題含解析
- 2022年高考數(shù)學(xué)試卷(上海)(秋考)(空白卷)
- 山東省濟(jì)南市語文小升初2024年模擬試題與參考答案
- 裝配式建筑復(fù)習(xí)試題及答案
評論
0/150
提交評論