C語言程序設(shè)計(jì)課件第9章 結(jié)構(gòu)體、共用體和枚舉類型_第1頁
C語言程序設(shè)計(jì)課件第9章 結(jié)構(gòu)體、共用體和枚舉類型_第2頁
C語言程序設(shè)計(jì)課件第9章 結(jié)構(gòu)體、共用體和枚舉類型_第3頁
C語言程序設(shè)計(jì)課件第9章 結(jié)構(gòu)體、共用體和枚舉類型_第4頁
C語言程序設(shè)計(jì)課件第9章 結(jié)構(gòu)體、共用體和枚舉類型_第5頁
已閱讀5頁,還剩54頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

第9章結(jié)構(gòu)體、共用體和枚舉類型本章主要內(nèi)容:9.1結(jié)構(gòu)體(重點(diǎn))9.2鏈表(重點(diǎn))9.3共用體9.4枚舉類型(重點(diǎn))9.5類型定義符typedef本章教學(xué)要求:掌握結(jié)構(gòu)體類型的定義及應(yīng)用熟悉鏈表的定義及使用方法

掌握枚舉類型定義及在實(shí)際問題中的應(yīng)用了解共用體及類型定義符的使用9.1結(jié)構(gòu)體

本節(jié)主要介紹結(jié)構(gòu)體類型的定義、結(jié)構(gòu)體變量的定義與使用、結(jié)構(gòu)體數(shù)組的定義與使用、結(jié)構(gòu)體指針的定義與使用。9.1.1結(jié)構(gòu)體類型的定義1.定義格式如下:struct結(jié)構(gòu)體名{ 成員項(xiàng)列表;};第9章結(jié)構(gòu)體、共用體和枚舉類型9.1結(jié)構(gòu)體9.1.1結(jié)構(gòu)體類型的定義2.例如,可以這樣定義與學(xué)生基本信息對(duì)應(yīng)的結(jié)構(gòu)體類型:structstudent{charnum[11]; /*學(xué)號(hào)*/charname[10]; /*姓名*/charsex; /*性別*/intage; /*年齡*/charnation; /*民族*/charaddr[20]; /*家庭住址*/};第9章結(jié)構(gòu)體、共用體和枚舉類型9.1結(jié)構(gòu)體9.1.1結(jié)構(gòu)體類型的定義3.注意①不要忘記寫花括弧外的分號(hào)。②一個(gè)結(jié)構(gòu)體類型有其專用的標(biāo)志,它由兩個(gè)標(biāo)識(shí)符組成,其中第一個(gè)標(biāo)識(shí)符為關(guān)鍵字struct,第二個(gè)標(biāo)識(shí)符student為結(jié)構(gòu)體名,由編程人員按照標(biāo)識(shí)符的命名規(guī)則來指定。這兩者聯(lián)合起來組成一個(gè)“類型標(biāo)識(shí)符”即“類型名”。③一個(gè)結(jié)構(gòu)體類型是由若干個(gè)數(shù)據(jù)項(xiàng)組成,每一個(gè)數(shù)據(jù)項(xiàng)都必須屬于一種已定義的類型,且各個(gè)數(shù)據(jù)項(xiàng)的類型可以不相同。每一個(gè)數(shù)據(jù)項(xiàng)稱為一個(gè)結(jié)構(gòu)體的成員,也稱為“域”。比如在上面的定義中,name、sex、age等不是變量名而是結(jié)構(gòu)體類型structstudent的成員名。在一個(gè)函數(shù)中,可以另外定義與結(jié)構(gòu)體成員同名的變量名,它們代表不同的對(duì)象。第9章結(jié)構(gòu)體、共用體和枚舉類型9.1結(jié)構(gòu)體9.1.1結(jié)構(gòu)體類型的定義3.注意④結(jié)構(gòu)體類型可以有無數(shù)種。因?yàn)榻Y(jié)構(gòu)體名可由程序設(shè)計(jì)人員自定,且結(jié)構(gòu)體成員可千變?nèi)f化,所以結(jié)構(gòu)體類型不是只有一種,而可以有千千萬萬種,這一點(diǎn)也是與基本類型不同的。⑤定義一個(gè)結(jié)構(gòu)體類型并不意味著系統(tǒng)將分配一段內(nèi)存單元來存放各數(shù)據(jù)項(xiàng)成員。因?yàn)檫@只是定義類型而不是定義變量,只有在定義變量以后,計(jì)算機(jī)才會(huì)依據(jù)結(jié)構(gòu)體成員的數(shù)據(jù)類型,在內(nèi)存中取得一塊連續(xù)的存儲(chǔ)空間來存放這些成員。第9章結(jié)構(gòu)體、共用體和枚舉類型9.1結(jié)構(gòu)體9.1.2結(jié)構(gòu)體變量的定義與使用1.結(jié)構(gòu)體變量的定義結(jié)構(gòu)體在使用時(shí),需要先定義結(jié)構(gòu)體類型,然后再根據(jù)自定義的結(jié)構(gòu)體類型去定義結(jié)構(gòu)體變量??梢杂靡韵氯N方法定義一個(gè)結(jié)構(gòu)體變量。(1)先定義結(jié)構(gòu)體類型再定義該類型的變量。如上面已經(jīng)定義了一個(gè)結(jié)構(gòu)體類型structstudent,現(xiàn)在可以用它定義結(jié)構(gòu)體變量。structstudentstu1,stu2;(2)定義一個(gè)結(jié)構(gòu)體類型的同時(shí)定義該結(jié)構(gòu)體類型的變量。一般格式如下:struct

結(jié)構(gòu)體名{ 結(jié)構(gòu)體成員列表;}變量名列表;第9章結(jié)構(gòu)體、共用體和枚舉類型structstudent{charnum[11];charname[10];charsex;intage;charnation;charaddr[20];}stu1,stu2;9.1結(jié)構(gòu)體9.1.2結(jié)構(gòu)體變量的定義與使用1.結(jié)構(gòu)體變量的定義可以用以下三種方法定義一個(gè)結(jié)構(gòu)體變量。(3)直接定義結(jié)構(gòu)體類型的變量。一般格式如下:struct

{

結(jié)構(gòu)體成員列表;}變量名列表;即不出現(xiàn)結(jié)構(gòu)體名。但這種形式只是定義了結(jié)構(gòu)體類型的變量,沒有指定此結(jié)構(gòu)體類型的名字,因此以后不能再用它來定義其它變量。第9章結(jié)構(gòu)體、共用體和枚舉類型struct{ charnum[11]; charname[10]; charsex; intage; charnation; charaddr[20];}stu1,stu2;9.1結(jié)構(gòu)體9.1.2結(jié)構(gòu)體變量的定義與使用1.結(jié)構(gòu)體變量的定義說明:①類型與變量是不同的概念。對(duì)結(jié)構(gòu)體變量來說,在定義時(shí)一般先定義一個(gè)結(jié)構(gòu)體類型,然后定義該類型的變量。只能對(duì)變量賦值、存取或運(yùn)算,而不能對(duì)一個(gè)類型賦值、存取或運(yùn)算。在編譯時(shí)只對(duì)變量分配存儲(chǔ)空間,對(duì)類型是不分配空間的。②對(duì)于某個(gè)具體的結(jié)構(gòu)體類型,成員的數(shù)量必須固定。③對(duì)結(jié)構(gòu)體中的成員可以單獨(dú)使用,它的作用與地位相當(dāng)于普通變量。④結(jié)構(gòu)體類型的成員也可以是一個(gè)結(jié)構(gòu)體變量。第9章結(jié)構(gòu)體、共用體和枚舉類型9.1結(jié)構(gòu)體9.1.2結(jié)構(gòu)體變量的定義與使用2.結(jié)構(gòu)體變量的初始化結(jié)構(gòu)體類型的使用方法與數(shù)組相似,它的初始化需要以每個(gè)成員為基本單位,可以在定義變量的同時(shí)賦初值。例如:structstudent{charnum[11]; charname[10]; charsex;

intage; charnation; charaddr[20];};structstudentstu1={"20150101001","LiMing",'M',30,'H',"YingcaiRoad"};第9章結(jié)構(gòu)體、共用體和枚舉類型9.1結(jié)構(gòu)體9.1.2結(jié)構(gòu)體變量的定義與使用3.結(jié)構(gòu)體變量的引用(1)引用結(jié)構(gòu)體變量中的單個(gè)成員。一個(gè)結(jié)構(gòu)體變量表示的是一個(gè)整體,比如一個(gè)學(xué)生的基本信息,但有時(shí)我們要訪問的是其中的一個(gè)數(shù)據(jù)項(xiàng)成員,比如某個(gè)學(xué)生的姓名,訪問結(jié)構(gòu)體變量的某個(gè)數(shù)據(jù)項(xiàng)成員的形式為:

結(jié)構(gòu)體變量.結(jié)構(gòu)體成員名其中符號(hào)“.”稱為成員運(yùn)算符。第9章結(jié)構(gòu)體、共用體和枚舉類型structstudent{ charnum[11]; charname[10]; charsex; intage; charnation; charaddr[20];}stu1;strcpy(,"LiMing");stu1.age=19;9.1結(jié)構(gòu)體9.1.2結(jié)構(gòu)體變量的定義與使用3.結(jié)構(gòu)體變量的引用(2)整體引用結(jié)構(gòu)體變量??梢詫⒁粋€(gè)結(jié)構(gòu)體變量的值賦給另一個(gè)具有相同類型的結(jié)構(gòu)體變量。例如:

structstudentstu1={"20150101001","LiMing",'M',30,'H',"YingcaiRoad"};

structstudentstu2; stu2=stu1;但是不允許用賦值語句將一組常量直接賦給一個(gè)結(jié)構(gòu)體變量,如下面的用法是不正確的。

structstudentstu1; stu1={"20150101001","LiMing",'M',30,'H',"YingcaiRoad"};第9章結(jié)構(gòu)體、共用體和枚舉類型9.1結(jié)構(gòu)體9.1.2結(jié)構(gòu)體變量的定義與使用3.結(jié)構(gòu)體變量的引用(3)結(jié)構(gòu)體變量中成員的輸入輸出。C語言不允許把一個(gè)結(jié)構(gòu)體變量作為一個(gè)整體進(jìn)行輸入或輸出操作。例如下列語句是不合法的:

scanf("%d",&stu1);

printf("%d\n",stu1);

printf("%s,%s,%c,%d,%c,%s\n",stu1);因?yàn)樵谟胮rintf和scanf函數(shù)時(shí),必須指定輸入輸出格式,一個(gè)格式符對(duì)應(yīng)一個(gè)變量,有明確的存儲(chǔ)界限。而結(jié)構(gòu)體變量包括若干個(gè)不同類型的數(shù)據(jù)項(xiàng),所以,要輸入或輸出一個(gè)結(jié)構(gòu)體類型變量,只能對(duì)其成員進(jìn)行操作。第9章結(jié)構(gòu)體、共用體和枚舉類型9.1結(jié)構(gòu)體9.1.2結(jié)構(gòu)體變量的定義與使用3.結(jié)構(gòu)體變量的引用(4)可以引用結(jié)構(gòu)體變量其成員的地址,也可以引用結(jié)構(gòu)體變量的地址。

前面已經(jīng)提到,結(jié)構(gòu)體變量所占內(nèi)存大小是各成員所占內(nèi)存大小之和,這是因?yàn)榻Y(jié)構(gòu)體變量在內(nèi)存中存儲(chǔ)時(shí),各個(gè)成員按其定義的先后順序存儲(chǔ)在連續(xù)的一段存儲(chǔ)空間。這段連續(xù)存儲(chǔ)空間的首地址也就是該結(jié)構(gòu)體變量的地址,它的各個(gè)成員也有各自的存儲(chǔ)地址,可以引用這些地址。

scanf("%d",&stu1.age); /*輸入stu1.age的值*/

printf("%o%o\n",&stu1,&stu1.age); /*輸出stu1和stu1.age的地址*/第9章結(jié)構(gòu)體、共用體和枚舉類型9.1結(jié)構(gòu)體9.1.3結(jié)構(gòu)體數(shù)組的定義與使用一個(gè)結(jié)構(gòu)體變量只能存放一個(gè)對(duì)象(如一個(gè)學(xué)生)的數(shù)據(jù),如果要存放一所學(xué)校所有的學(xué)生數(shù)據(jù)就要用到數(shù)組,這就是結(jié)構(gòu)體數(shù)組。結(jié)構(gòu)體數(shù)組的每個(gè)數(shù)組元素都是一個(gè)結(jié)構(gòu)體類型的變量。1.結(jié)構(gòu)體數(shù)組的定義(1)先定義結(jié)構(gòu)體類型再定義結(jié)構(gòu)體數(shù)組。例如:structworker{

charname[20]; charsex;

intage; floatsalary;};structworkerw[50];第9章結(jié)構(gòu)體、共用體和枚舉類型9.1結(jié)構(gòu)體9.1.3結(jié)構(gòu)體數(shù)組的定義與使用1.結(jié)構(gòu)體數(shù)組的定義(2)定義類型的同時(shí)定義數(shù)組。例如:structworker{ charname[20]; charsex;

intage; floatsalary;}w[50];第9章結(jié)構(gòu)體、共用體和枚舉類型9.1結(jié)構(gòu)體9.1.3結(jié)構(gòu)體數(shù)組的定義與使用1.結(jié)構(gòu)體數(shù)組的定義(3)直接定義結(jié)構(gòu)體數(shù)組。例如:struct

{ charname[20]; charsex;

intage; floatsalary;}w[50];第9章結(jié)構(gòu)體、共用體和枚舉類型9.1結(jié)構(gòu)體9.1.3結(jié)構(gòu)體數(shù)組的定義與使用2.結(jié)構(gòu)體數(shù)組的初始化結(jié)構(gòu)體數(shù)組在定義時(shí)可以直接進(jìn)行初始化。例如:structworker{ charname[20]; charsex;

intage; floatsalary;}w[50]={{"LiuGang",'M',30,5500},{"WangKe",'F',25,4000}};第9章結(jié)構(gòu)體、共用體和枚舉類型9.1結(jié)構(gòu)體9.1.3結(jié)構(gòu)體數(shù)組的定義與使用3.結(jié)構(gòu)體數(shù)組的引用一個(gè)結(jié)構(gòu)體數(shù)組的元素相當(dāng)于一個(gè)結(jié)構(gòu)體變量,所以前面關(guān)于結(jié)構(gòu)體變量的使用方法對(duì)結(jié)構(gòu)體數(shù)組元素同樣適用。有關(guān)數(shù)組的用法同一般數(shù)組。例如,數(shù)組的輸入可采用以下形式:for(i=0;i<50;i++)

scanf("%s,%c,%d,%f",w[i].name,&w[i].sex,&w[i].age,&w[i].salary);數(shù)組的輸出:for(i=0;i<50;i++)

printf("%s,%c,%d,%f",w[i].name,w[i].sex,w[i].age,w[i].salary);第9章結(jié)構(gòu)體、共用體和枚舉類型9.1結(jié)構(gòu)體9.1.3結(jié)構(gòu)體數(shù)組的定義與使用【例9-1】員工檔案信息的輸入與輸出。源程序:第9章結(jié)構(gòu)體、共用體和枚舉類型#include<stdio.h>#defineMAX3structworker{charname[20];charsex;intage;floatsalary;};intmain(){structworkerw[MAX];inti;for(i=0;i<MAX;i++){printf("Inputname:");scanf("%s",w[i].name);printf("Inputsex:");scanf("%c",&w[i].sex);printf("Inputage:");scanf("%d",&w[i].age);printf("Inputsalary:");scanf("%f",&w[i].salary);}printf("namesexagesalary\n");for(i=0;i<MAX;i++)printf("%-10s%-6c%-6d%-10.2f\n",w[i].name,w[i].sex,w[i].age,w[i].salary);return0;}程序運(yùn)行結(jié)果:Inputname:LiuGang↙Inputsex:M↙Inputage:30↙Inputsalary:5600↙Inputname:WangKe↙Inputsex:F↙Inputage:25↙Inputsalary:4000↙Inputname:ChenPing↙Inputsex:F↙Inputage:30↙Inputsalary:5650↙name sexagesalaryLiuGang M305600.00WangKe F254000.00ChenPingF305650.009.1結(jié)構(gòu)體9.1.4結(jié)構(gòu)體指針的定義與使用一個(gè)結(jié)構(gòu)體類型的數(shù)據(jù)在內(nèi)存中占用一段連續(xù)的存儲(chǔ)區(qū)域,可以定義一個(gè)指針變量來存儲(chǔ)該存儲(chǔ)區(qū)域的起始地址,這樣的指針變量稱為指向結(jié)構(gòu)體類型的指針變量,簡(jiǎn)稱結(jié)構(gòu)體指針。1.結(jié)構(gòu)體指針的定義(三種方式)定義結(jié)構(gòu)體指針的方法和定義結(jié)構(gòu)體變量的方法相同,也有三種方式:(1)先定義結(jié)構(gòu)體類型再定義指向該類型的指針變量。如前面已定義過structworker類型,則可定義該類型的指針變量:structworker*p,*q;第9章結(jié)構(gòu)體、共用體和枚舉類型9.1結(jié)構(gòu)體9.1.4結(jié)構(gòu)體指針的定義與使用1.結(jié)構(gòu)體指針的定義(三種方式)(2)定義類型的同時(shí)定義指針變量。例如:structworker{ charname[9]; charsex;

intage; floatsalary;}*p,*q;第9章結(jié)構(gòu)體、共用體和枚舉類型9.1結(jié)構(gòu)體9.1.4結(jié)構(gòu)體指針的定義與使用1.結(jié)構(gòu)體指針的定義(三種方式)(3)直接定義指針變量。例如:struct

{ charname[20]; charsex;

intage; floatsalary;}*p,*q;第9章結(jié)構(gòu)體、共用體和枚舉類型9.1結(jié)構(gòu)體9.1.4結(jié)構(gòu)體指針的定義與使用2.結(jié)構(gòu)體指針的使用(1)結(jié)構(gòu)體指針的賦值與普通變量相同,結(jié)構(gòu)體指針變量也必須先賦值才能使用。一個(gè)結(jié)構(gòu)體指針變量可以用一個(gè)結(jié)構(gòu)體變量的首地址賦值,也可以用結(jié)構(gòu)體數(shù)組的某個(gè)元素的首地址賦值,例如:structworker{ charname[20]; charsex;

intage; floatsalary;};structworkerw1,w[50],*p,*q;p=&w1;q=w;或q=&w[0];第9章結(jié)構(gòu)體、共用體和枚舉類型注意:結(jié)構(gòu)體指針只能指向一個(gè)結(jié)構(gòu)體變量,不能指向結(jié)構(gòu)體變量中的某一個(gè)成員,因?yàn)榻Y(jié)構(gòu)體指針和結(jié)構(gòu)體成員的數(shù)據(jù)類型不一致。9.1結(jié)構(gòu)體9.1.4結(jié)構(gòu)體指針的定義與使用2.結(jié)構(gòu)體指針的使用(2)利用結(jié)構(gòu)體指針引用結(jié)構(gòu)體變量的成員。

要訪問結(jié)構(gòu)體變量的一個(gè)成員,可以用運(yùn)算符“.”(如w1.age)的形式。如果要用結(jié)構(gòu)體指針來訪問這個(gè)結(jié)構(gòu)成員,也可以寫成(*p).age的形式。除此之外,為了使用方便和直觀,C語言又引入了指向運(yùn)算符“->”,即:(*p).age也可以寫成p->age的形式。這樣,引用結(jié)構(gòu)體變量成員可以有以下三種形式:①結(jié)構(gòu)體變量名.成員名②(*結(jié)構(gòu)體指針變量名).成員名③結(jié)構(gòu)體指針變量名->成員名注意:①運(yùn)算符“->”左側(cè)只能是結(jié)構(gòu)體指針變量。②在第二種形式中,“(*結(jié)構(gòu)體指針變量名)”兩邊的括號(hào)不能省略,因?yàn)檫\(yùn)算符.的優(yōu)先級(jí)要高于指針運(yùn)算符*。第9章結(jié)構(gòu)體、共用體和枚舉類型9.1結(jié)構(gòu)體9.1.4結(jié)構(gòu)體指針的定義與使用【例9-2】輸入一個(gè)學(xué)生的學(xué)號(hào)、姓名、期中考試成績(jī)和期末考試成績(jī),計(jì)算平均成績(jī)并輸出所有信息。分析:定義一個(gè)結(jié)構(gòu)體類型的變量,用來存放學(xué)生的相關(guān)信息。在引用各成員時(shí)有三種方式。源程序:第9章結(jié)構(gòu)體、共用體和枚舉類型#include<stdio.h>structstudent{ charnum[12],name[18]; intfinal,midterm,aver;};voidmain(){ structstudent*p,stu1; p=&stu1; printf("Inputthenumnamemidtermfinal:"); scanf("%s%s%d%d",stu1.num,,&stu1.midterm,&stu1.final); (*p).aver=((*p).final+(*p).midterm)/2;

printf("num:%sname:%s\n",p->num,p->name);

printf("midtermscore:%dfinalscore:%daverscore:%d\n", p->midterm,p->final,p->aver);}程序運(yùn)行結(jié)果:Inputthenumnamemidtermfinal:150203001LiLin88 92↙num:150203001name:LiLinmidtermscore:88finalscore:92averscore:909.2鏈表

鏈表是一種常見而又重要的數(shù)據(jù)結(jié)構(gòu)。它是一種動(dòng)態(tài)存儲(chǔ)結(jié)構(gòu),根據(jù)需要開辟內(nèi)存單元,其具體的理論和用法在《數(shù)據(jù)結(jié)構(gòu)》課程中會(huì)詳細(xì)介紹。本節(jié)主要介紹利用結(jié)構(gòu)體變量和指針實(shí)現(xiàn)鏈表的方法。

所謂鏈表是指將若干個(gè)數(shù)據(jù)元素按一定的原則連接起來的表。鏈表中的每一個(gè)數(shù)據(jù)元素(可能包含多個(gè)成員項(xiàng))稱為一個(gè)“結(jié)點(diǎn)”。

鏈表的連接原則是:前一個(gè)結(jié)點(diǎn)“指向”下一個(gè)結(jié)點(diǎn),只有通過前一個(gè)結(jié)點(diǎn)才能找到下一個(gè)結(jié)點(diǎn)。第9章結(jié)構(gòu)體、共用體和枚舉類型9.2鏈表9.2.1單鏈表的結(jié)構(gòu)

在單鏈表中,每個(gè)結(jié)點(diǎn)由兩個(gè)域組成:數(shù)據(jù)域用于存儲(chǔ)數(shù)據(jù);指針域用于存儲(chǔ)后繼結(jié)點(diǎn)的地址。第一個(gè)結(jié)點(diǎn)的地址存儲(chǔ)在一個(gè)指針變量中,該指針變量稱為“頭指針”(如圖9-1中的H);最后一個(gè)結(jié)點(diǎn)的指針域存儲(chǔ)一個(gè)“NULL”值(NULL是頭文件中定義的一個(gè)符號(hào)常量,值為0,專門用于設(shè)置指針無效或判斷指針是否無效),即空指針,表示鏈表到此結(jié)束。這樣,通過“頭指針”沿著各個(gè)結(jié)點(diǎn)的指針域就可以找到鏈表中各個(gè)結(jié)點(diǎn),如果不提供“頭指針”,則整個(gè)鏈表無法訪問。也正因?yàn)檫@種結(jié)構(gòu)就如同一條鐵鏈一樣,一環(huán)扣一環(huán),中間不能斷開,所以稱之為鏈表。第9章結(jié)構(gòu)體、共用體和枚舉類型9.2鏈表9.2.1單鏈表的結(jié)構(gòu)鏈表中的結(jié)點(diǎn)結(jié)構(gòu)可用結(jié)構(gòu)體類型來實(shí)現(xiàn)。例如:structstudent{

intnumber;

structstudent*next;};其中number用來存放結(jié)點(diǎn)數(shù)據(jù),next存放下一個(gè)結(jié)點(diǎn)的地址。第9章結(jié)構(gòu)體、共用體和枚舉類型9.2鏈表9.2.2鏈表的動(dòng)態(tài)存儲(chǔ)

在C語言中,鏈表中每個(gè)存儲(chǔ)單元的開辟和釋放都是動(dòng)態(tài)存儲(chǔ)函數(shù)實(shí)現(xiàn)的。

根據(jù)需要隨時(shí)開辟存儲(chǔ)單元,不再需要時(shí)又可隨時(shí)釋放,這樣使得存儲(chǔ)空間的利用比較合理。鏈表中各結(jié)點(diǎn)的地址在需要時(shí)向系統(tǒng)申請(qǐng)分配,系統(tǒng)會(huì)根據(jù)內(nèi)存的當(dāng)前情況,既可連續(xù)分配地址,也可跳躍式分配地址。第9章結(jié)構(gòu)體、共用體和枚舉類型9.2鏈表9.2.2鏈表的動(dòng)態(tài)存儲(chǔ)與動(dòng)態(tài)存儲(chǔ)有關(guān)的庫函數(shù)1.malloc函數(shù)。函數(shù)原型為:void*malloc(unsignedintsize)其功能是在內(nèi)存的動(dòng)態(tài)存儲(chǔ)區(qū)中分配一個(gè)長(zhǎng)度為size的存儲(chǔ)空間。函數(shù)返回值為分配域的起始地址,如果內(nèi)存不足,則分配不成功,返回0(空指針)。2.calloc函數(shù)。函數(shù)原型為:void*calloc(unsignedintn,unsignedintsize)其功能是在內(nèi)存的動(dòng)態(tài)存儲(chǔ)區(qū)中分配n個(gè)長(zhǎng)度為size字節(jié)的存儲(chǔ)空間。函數(shù)返回值為分配域的起始地址;如果分配不成功,則返回0。第9章結(jié)構(gòu)體、共用體和枚舉類型9.2鏈表9.2.2鏈表的動(dòng)態(tài)存儲(chǔ)與動(dòng)態(tài)存儲(chǔ)有關(guān)的庫函數(shù)3.free函數(shù)。函數(shù)原型為:voidfree(void*ptr)其功能是將指針變量ptr

所指向的存儲(chǔ)空間釋放。ptr

是最近一次調(diào)用calloc函數(shù)或malloc函數(shù)時(shí)返回的地址。free函數(shù)沒有返回值。4.realloc函數(shù)。函數(shù)原型為:void*realloc(void*ptr,unsignedintsize)其功能是將ptr所指向的存儲(chǔ)空間(是原先用malloc函數(shù)分配的)的大小改為size個(gè)字節(jié),即重新分配??梢允乖瓉淼姆峙鋮^(qū)擴(kuò)大也可縮小。它的函數(shù)返回值是一個(gè)指針,即新的存儲(chǔ)區(qū)的首地址。說明:以上庫函數(shù)包含在頭文件stdlib.h(即standardlibrary)標(biāo)準(zhǔn)庫頭文件中。第9章結(jié)構(gòu)體、共用體和枚舉類型9.2鏈表9.2.3單鏈表的建立與輸出1.單鏈表的建立建立單向鏈表的主要操作步驟如下:①定義鏈表中的結(jié)點(diǎn)結(jié)構(gòu);②讀取數(shù)據(jù);③生成新結(jié)點(diǎn);④將數(shù)據(jù)存入結(jié)點(diǎn)的成員變量中;⑤將新結(jié)點(diǎn)的指針成員賦值為空,如果是空表,則將新結(jié)點(diǎn)連接到表頭;如果是非空表,則把新結(jié)點(diǎn)連接到表尾。重復(fù)②~⑤的操作直到輸入結(jié)束。第9章結(jié)構(gòu)體、共用體和枚舉類型9.2鏈表9.2.3單鏈表的建立與輸出1.單鏈表的建立【例9-3】編寫函數(shù)creatlist,建立一個(gè)整數(shù)的單向鏈表。要求:結(jié)點(diǎn)數(shù)據(jù)域的數(shù)值從鍵盤輸入,以-1作為輸入的結(jié)束標(biāo)志,鏈表的起始地址由函數(shù)值返回。分析:設(shè)立三個(gè)指針:h、s和r,它們都指向結(jié)構(gòu)體類型數(shù)據(jù),其中h存放鏈表的起始地址,而s和r為工作指針:指針s用來指向新生成的結(jié)點(diǎn),指針r總是指向鏈表中最后一個(gè)結(jié)點(diǎn)。每當(dāng)把指針s所指的新開辟的結(jié)點(diǎn)連接到表尾后,指針r便移向這一新的表尾結(jié)點(diǎn),這時(shí)又可用指針s去指向下一個(gè)新開辟的結(jié)點(diǎn)。鏈表最后一個(gè)結(jié)點(diǎn)的指針域中置'\0'(NULL值),作為單向鏈表的結(jié)束標(biāo)志。n是結(jié)點(diǎn)個(gè)數(shù)。源程序:第9章結(jié)構(gòu)體、共用體和枚舉類型#include<stdlib.h>#include<stdio.h>#defineNULL0#defineLENsizeof(structstudent)structstudent/*定義結(jié)點(diǎn)類型*/{intdata;structstudent*next;};structstudent*creatlist()/*建立鏈表函數(shù)*/{structstudent*h,*s,*r;intx;printf("x=");scanf("%d",&x);/*輸入第一個(gè)元素值*/if(x==-1){h=NULL;return(h);}h=r=(structstudent*)malloc(LEN);/*在內(nèi)存中產(chǎn)生第一個(gè)結(jié)點(diǎn)空間*/r->data=x;printf("x=");scanf("%d",&x);/*輸入第二個(gè)元素值*/while(x!=-1){s=(structstudent*)malloc(LEN);/*產(chǎn)生下一個(gè)結(jié)點(diǎn)空間*/s->data=x;r->next=s; /*s結(jié)點(diǎn)接到鏈尾*/r=s; /*r指向新的鏈尾*/printf("x=");scanf("%d",&x);/*輸入下一個(gè)元素值*/}r->next=NULL;/*最后一個(gè)結(jié)點(diǎn)的指針域?yàn)榭?/return(h);}9.2鏈表9.2.3單鏈表的建立與輸出2.單鏈表的輸出

輸出鏈表是指將鏈表各結(jié)點(diǎn)的數(shù)據(jù)依次輸出。單向鏈表的輸出的操作步驟如下:①找到鏈表中第一個(gè)元素的地址;②設(shè)一個(gè)指針變量并使它指向第一個(gè)結(jié)點(diǎn),輸出其值成員;③使指針變量向后移一個(gè)結(jié)點(diǎn),即指到下一個(gè)結(jié)點(diǎn),再輸出其值成員。重復(fù)步驟③直到鏈表的尾結(jié)點(diǎn)。第9章結(jié)構(gòu)體、共用體和枚舉類型9.2鏈表9.2.3單鏈表的建立與輸出2.單鏈表的輸出【例9-4】寫出輸出鏈表的函數(shù)display。分析:設(shè)置一個(gè)指針變量p,先使它指向第一個(gè)結(jié)點(diǎn)在輸出完第一個(gè)結(jié)點(diǎn)之后,通過語句p=p->next;使p指向第二個(gè)結(jié)點(diǎn)依次處理直到表尾。head為頭指針,其值由實(shí)參傳過來。源程序:第9章結(jié)構(gòu)體、共用體和枚舉類型voiddisplay(structstudent*head){structstudent*p;p=head;while(p!=NULL){printf("%d",p->data);p=p->next;/*指針指向下一個(gè)結(jié)點(diǎn)*/}}voidmain(){structstudent*head;head=creatlist();display(head);}9.2鏈表9.2.4單鏈表的插入與刪除1.單鏈表的插入

單鏈表的插入是指在鏈表中適當(dāng)位置(稱為插入位置)添加一個(gè)新結(jié)點(diǎn)。插入位置可能處于鏈表頭、鏈表尾或鏈表中某兩個(gè)結(jié)點(diǎn)之間?!纠?-5】在單鏈表的第i個(gè)數(shù)據(jù)元素之前插入一個(gè)數(shù)據(jù)元素x。分析:此問題要修改第i-1數(shù)據(jù)元素的指針域,使其指向插入結(jié)點(diǎn)而插入結(jié)點(diǎn)的指針域指向第i個(gè)數(shù)據(jù)元素因此,首先應(yīng)找到第i-1個(gè)結(jié)點(diǎn),而后再修改指針的操作源程序:第9章結(jié)構(gòu)體、共用體和枚舉類型intinsert(structstudent*L,inti,intx){structstudent*p,*s;intj;p=L;j=1;while(p!=NULL&&j<i-1)/*查找第i-1個(gè)數(shù)據(jù)元素*/{p=p->next;j++;}if(p==NULL)return(0); /*如沒有查找返回0*/s=(structstudent*)malloc(LEN);s->data=x;s->next=p->next;p->next=s; /*修改相應(yīng)指針域,實(shí)現(xiàn)插入*/return(1);}9.2鏈表9.2.4單鏈表的插入與刪除2.單鏈表的刪除

單鏈表的刪除是指使單鏈表中的某個(gè)數(shù)據(jù)元素從鏈表中脫離。【例9-6】刪除單鏈表L的第i個(gè)數(shù)據(jù)元素。分析:要修改第i-1個(gè)數(shù)據(jù)元素的指針域,使其指向第i+1個(gè)數(shù)據(jù)元素。要?jiǎng)h除的第i個(gè)元素的值可通過指針參數(shù)帶回主調(diào)函數(shù)。源程序:第9章結(jié)構(gòu)體、共用體和枚舉類型intdelete(structstudent*L,inti,int*s){structstudent*p,*q;intj;if(L==NULL){printf("Listempty!");return(0);}/*鏈表為空,刪除第i個(gè)數(shù)據(jù)元素失敗*/p=L;j=1;while(p->next!=NULL&&j<i-1){p=p->next;j++;}if(p->next==NULL)return(0);q=p->next;p->next=q->next;*s=q->data;free(q);return(1);}9.3共用體共用體又稱聯(lián)合體,它是C語言中提供的另一種構(gòu)造類型,它是將幾種不同類型的變量存放到同一段內(nèi)存單元中。雖然這些不同類型的變量在內(nèi)存中所占的字節(jié)數(shù)不同,但它們都從同一地址單元開始存放。共用體使用的是一種覆蓋技術(shù),即幾個(gè)變量互相覆蓋。共用體的定義方法及使用規(guī)則與結(jié)構(gòu)體類型相似。第9章結(jié)構(gòu)體、共用體和枚舉類型9.3共用體9.3.1共用體類型和共用體變量的定義

共用體類型的定義與結(jié)構(gòu)體類型的定義相似,只需要將關(guān)鍵字struct換成union即可。其一般格式為:union

共用體名{

類型名1共用體成員名1;

類型名2共用體成員名2; ……

類型名n共用體成員名n;};

union為關(guān)鍵字,共用體各成員可以是簡(jiǎn)單變量,也可以是數(shù)組、指針、結(jié)構(gòu)體和共用體。第9章結(jié)構(gòu)體、共用體和枚舉類型9.3共用體9.3.1共用體類型和共用體變量的定義與結(jié)構(gòu)體變量相似,共用體變量的定義也有三種形式。1.先定義共用體類型再定義該類型的變量。例如:uniondata{

inta; charb; floatc;};uniondatax1,x2;其中,data是共用體名,x1和x2為data類型的共用體變量。第9章結(jié)構(gòu)體、共用體和枚舉類型根據(jù)共用體的定義,共用體變量x1中的各個(gè)成員共占內(nèi)存中同一段存儲(chǔ)空間,即成員a、b、c都是從同一存儲(chǔ)單元開始存放(假設(shè)地址為1000H),a為整型,占用2個(gè)字節(jié),即1000H和1001H兩個(gè)存儲(chǔ)單元;b為字符型,占用1個(gè)字節(jié),即1000H這個(gè)存儲(chǔ)單元;c為實(shí)型,占4個(gè)字節(jié),即1000H至1003H共四個(gè)存儲(chǔ)單元。共用體變量x1實(shí)際占用的存儲(chǔ)空間為其成員中所需存儲(chǔ)單元的最大值。9.3共用體9.3.1共用體類型和共用體變量的定義與結(jié)構(gòu)體變量相似,共用體變量的定義也有三種形式。2.定義一個(gè)共用體類型的同時(shí)定義該共用體類型的變量。例如:uniondata{

inta; charb; floatc;}x1,x2;第9章結(jié)構(gòu)體、共用體和枚舉類型9.3共用體9.3.1共用體類型和共用體變量的定義與結(jié)構(gòu)體變量相似,共用體變量的定義也有三種形式。3.直接定義共用體類型的變量。例如:union{

inta; charb; floatc;}x1,x2;第9章結(jié)構(gòu)體、共用體和枚舉類型9.3共用體9.3.2共用體變量引用

對(duì)于共用體變量,一般只引用它的成員,而不引用整個(gè)共用體變量。其成員引用的一般格式為:共用體變量名.成員名例如:x1.ax1.bx1.c也可以通過指向共用體變量的指針來引用其成員,例如:uniondatax,*p=&x;則以下也是合法的引用形式:(*p).ap->b第9章結(jié)構(gòu)體、共用體和枚舉類型9.3共用體9.3.2共用體變量引用

由于共用體變量的各個(gè)成員共用一段內(nèi)存,這段內(nèi)存在某一時(shí)刻只能用一個(gè)成員名來標(biāo)識(shí),也就是只有一個(gè)成員起作用,而不是各個(gè)成員并存。因此,共用體變量在使用時(shí)應(yīng)注意以下幾個(gè)方面:(1)不能在定義共用體變量時(shí)對(duì)它初始化。例如,以下初始化方式是非法的。 uniondata {

int

a;

charb;

floatc; }x1={10,’a’,7.8};第9章結(jié)構(gòu)體、共用體和枚舉類型9.3共用體9.3.2共用體變量引用(2)如果多次給共用體成員賦值,則最近一次賦值有效。例如:x1.a=10;x1.b=’a’;x1.c=7.8;最終,共用體變量x1中存放的有效值為7.8。前面所賦的值10被’a’覆蓋,而’a’被7.8覆蓋,所以此時(shí)不能再引用x1.a的值10和x1.b的值’a’。因此,共用體成員參加運(yùn)算時(shí),一定注意當(dāng)前在共用體變量中究竟是哪個(gè)成員有效。(3)共用體變量的地址與其各個(gè)成員的地址相同。例如:&x1==&x1.a==&x1.b==&x1.c第9章結(jié)構(gòu)體、共用體和枚舉類型9.3共用體9.3.2共用體變量引用(4)C語言允許兩個(gè)相同類型的共用體變量之間相互賦值。例如: uniondatax1,x2; x1.a=10; x2=x1;這樣,x2中的內(nèi)容與x1完全相同,也可以引用x1.a的值。但是,不能引用共用體變量名進(jìn)行以下操作,例如以下用法是錯(cuò)誤的。 x1=5; scanf("%d",&x1); printf("%d\n",x1);第9章結(jié)構(gòu)體、共用體和枚舉類型9.3共用體9.3.2共用體變量引用【例9-7】將下列數(shù)據(jù)說明為共用體類型,并進(jìn)行賦值和顯示。姓名

年齡

月收入WangLei 32 6000源程序:第9章結(jié)構(gòu)體、共用體和枚舉類型#include<stdio.h>voidmain(){unioninfo{char*name;intage;intincome;};unioninfolist;="WangLei";printf("%8s\n",);list.age=32;printf("%2dold\n",list.age);list.income=6000;printf("%4dyuan\n",list.income);}9.3共用體9.3.2共用體變量引用【例9-8】有一個(gè)教師與學(xué)生通用的表格,教師數(shù)據(jù)有姓名、性別、職業(yè)、教研室4項(xiàng);學(xué)生的數(shù)據(jù)有姓名、性別、職業(yè)、班級(jí)4項(xiàng)。編程序?qū)崿F(xiàn)數(shù)據(jù)的輸入和輸出。分析:教師的教研室可采用字符串表示,而學(xué)生的班級(jí)可以用整型的班級(jí)號(hào)來表示,它們的類型不同,但要共用表格的一列,所以該表格的第4項(xiàng)應(yīng)采用共用體類型。源程序:第9章結(jié)構(gòu)體、共用體和枚舉類型#include<stdio.h>#defineN10voidmain(){struct{charname[10];charsex;charjob;union{intclas;charoffice[10];}depa;}person[N];

inti;for(i=0;i<N;i++){printf("\nInput%dperson:",i+1);printf("\nname:");gets(person[i].name);printf("\nsex:");person[i].sex=getchar();getchar();printf("\njob:");person[i].job=getchar();if(person[i].job=='s'){printf("\nclass:");scanf("%d",&person[i].depa.clas);}else{printf("\noffice:");scanf("%s",&person[i].depa.office);}getchar();} for(i=0;i<N;i++){if(person[i].job=='s')printf("%-10s%-3c%-3c%-10d\n",person[i].name,person[i].sex,person[i].job,person[i].depa.clas);elseprintf("%-10s%-3c%-3c%-10s\n",person[i].name,person[i].sex,person[i].job,person[i].depa.office);}}9.4枚舉類型所謂“枚舉”是指將變量的值一一列舉出來,而變量的值只能列舉出來的其中之一。如果一個(gè)變量的取值范圍可以一一列舉出來,則可以將其定義為枚舉類型。枚舉類型的引入也可以限制數(shù)據(jù)的取值。第9章結(jié)構(gòu)體、共用體和枚舉類型9.4枚舉類型9.4.1枚舉類型的定義

枚舉類型也屬于一種構(gòu)造類型,定義枚舉類型的一般格式為:

enum

枚舉名{枚舉元素表};

其中,enum是表示枚舉類型的關(guān)鍵字;枚舉名是用戶定義的類型名;枚舉元素是用戶定義的有意義的標(biāo)識(shí)符,即羅列出該枚舉類型各種可能的、合法的取值。

與結(jié)構(gòu)體變量、共用體變量相似,枚舉變量的定義也有三種形式。1.先定義枚舉類型再定義該類型的變量。例如:

enum

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

enum

weekd1,d2;

上面定義了d1,d2兩個(gè)枚舉變量,它們的只能取sun,…,sat這7個(gè)值之一。第9章結(jié)構(gòu)體、共用體和枚舉類型9.4枚舉類型9.4.1枚舉類型的定義與結(jié)構(gòu)體變量、共用體變量相似,枚舉變量的定義也有三種形式。2.定義一個(gè)枚舉類型的同時(shí)定義該類型的變量。例如:

enum

week{sun,mon,tue,wed,thu,fri,sat}d1,d2;3.直接定義枚舉類型的變量。例如:

enum

{sun,mon,tue,wed,thu,fri,sat}d1,d2;第9章結(jié)構(gòu)體、共用體和枚舉類型9.4枚舉類型9.4.2枚舉變量的使用

枚舉變量的使用方式和普通變量一樣,但枚舉變量的取值范圍只能是其枚舉類型所列舉的各個(gè)枚舉元素。例如: d1=sun;d2=wed;都是合法的。但d1=sunday;則是非法的。第9章結(jié)構(gòu)體、共用體和枚舉類型9.4枚舉類型9.4.2枚舉變量的使用使用枚舉類型應(yīng)注意以下幾個(gè)問題:(1)在定義枚舉類型時(shí),枚舉元素的名字是程序設(shè)計(jì)者自己指定的例如:sun,mon等,命名規(guī)則與標(biāo)識(shí)符相同。這些名字并無固定的含義,只是一個(gè)符號(hào)。在C編譯中,對(duì)這些枚舉元素按常量處理,也稱枚舉常量。它們不是變量,不能改變它們的值。(2)枚舉常量的值是一些整數(shù),C語言編譯系統(tǒng)按定義時(shí)的順序使它們的值為0,1,2,……。例如,在上面的定義中sun的值為0,而mon的值為1等等。這是系統(tǒng)自動(dòng)賦給的,定義枚舉類型時(shí)不能寫成:

enum

weekday{0,1,2,3,4,5,6};枚舉常量必須用標(biāo)識(shí)符。

可以在定義類型時(shí)改變枚舉元素的值,例如:

enum

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

定義sun值為7,mon值為1,以后順序加1,tue值為2,sat值為6。第9章結(jié)構(gòu)體、共用體和枚舉類型9.4枚舉類型9.4.2枚舉變量的使用使用枚舉類型應(yīng)注意以下幾個(gè)問題:(3)枚舉常量的值可以賦給枚舉變量,但不能將一個(gè)整數(shù)直接賦給枚舉變量,例如:d2=wed;則d2的值就為3,且這個(gè)值可以輸出。例如:printf("%d\n",d2);輸出結(jié)果為3。但是d2=3;則是錯(cuò)誤的,因?yàn)樗鼈儗儆诓煌念愋?。?)枚舉常量的值可以進(jìn)行判斷比較。例如: if(d1==sun)printf("ItisSunday!\n"); if(d2!=sun)printf("ItisnotSunday!\n");它們是按所代表的整數(shù)值進(jìn)行比較的。

枚舉類型變量的值是在該枚舉類型中所列舉的常量所代表的整數(shù)值范圍內(nèi),因此枚舉變量可以作為循環(huán)變量來控制循環(huán)。第9章結(jié)構(gòu)體、共用體和枚舉類型9.4枚舉類型9.4.2枚舉變量的使用【例9-9】已知今天是星期天,輸入一個(gè)整數(shù)n,計(jì)算第n

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(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ǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論