第8章 全國計算機等級考試計算機二級C語言 結構體 和共用體_第1頁
第8章 全國計算機等級考試計算機二級C語言 結構體 和共用體_第2頁
第8章 全國計算機等級考試計算機二級C語言 結構體 和共用體_第3頁
第8章 全國計算機等級考試計算機二級C語言 結構體 和共用體_第4頁
第8章 全國計算機等級考試計算機二級C語言 結構體 和共用體_第5頁
已閱讀5頁,還剩88頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

造富羸等教育“十

第8章結構體和共用體

前面的章節(jié)中已經(jīng)介紹了各種基本數(shù)據(jù)類型、數(shù)組和指針

。但只有這些數(shù)據(jù)類型還難以處理一些比較復雜的數(shù)據(jù)結構。本章

將以前面介紹的數(shù)據(jù)類型為基礎,進一步介紹結構體類型、共用體

類型和枚舉類型。

普通羸等教育“十

第8章結構體和共用體

8.1結構體

8.2動態(tài)內(nèi)存分配與鏈表

8.3共用體類型n

8.4枚舉類型

8.5用戶自定義類型n

8.6程序舉例n

造富羸等教育“十

8.1結構體

SI鼠

修|8.1結構體造翳等教育“十

8.1.1結構類型定義

在實際問題中,一組數(shù)據(jù)往往具有不同的數(shù)據(jù)類型。例如,在學生登記表

中,姓名應為字符型;學號可為整型或字符型;年齡應為整型;性別應為字符型;成

績可為整型或?qū)嵭汀5@些顯然不能用一個數(shù)組來存放這一組數(shù)據(jù)。因為數(shù)組中各

元素的類型和長度都必須一致,以便于編譯系統(tǒng)處理。為了解決這個問題,C語言

中給出了另一種構造數(shù)據(jù)類型一“結構體”。

“結構體”是一種構造類型,它是由若干“成員”組成的。每一個成員可

以是一個基本數(shù)據(jù)類型或者又是一個構造類型。結構體既然是一種“構造”而成的

數(shù)據(jù)類型,那么在說明和使用之前必須先定義它,也就是構造它。如同在說明和調(diào)

用函數(shù)之前要先定義函數(shù)一樣。

修|8.1結構體造翳等教育“十

定義一個結構體類型的一般形式為:

struct結構體名

{

結構成員的說明;

);

成員表由若干個成員組成,每個成員都是該結構體的一個組成部分。對每個成員也

必須作類型說明,其形式為:

類型說明符成員名;

成員名的命名應符合標識符的書寫規(guī)定。例如:

structstu

{intnum;

charname[20];

charsex;

floatscore;

);

修|8.1結構體造翳等教育“十

在這個結構體定義中,結構體名為stu,該結構體由4個成員組成。第一

個成員為num,整型變量;第二個成員為name,字符數(shù)組變量;第三個成員為sex

,字符變量;第四個成員為score,實型變量。應注意在括號“}”后的分號是不

可少的。結構體定義之后,即可進行變量說明。凡說明為結構體Stu的變量都由上

述4個成員組成。由此可見,結構是一種復雜的數(shù)據(jù)類型,是數(shù)目固定,類型不同

的若干有序變量的集合。

修|8.1結構體造翳等教育“十

8.1.2結構體類型變量的說明

說明結構體變量有以下三種方法。以上面定義的stu為例來加以說明。

(1)先定義結構體類型,再說明結構體變量

例如:

structstu

{intnum;

charname[20];

charsex;

floatscore;

);

structstuboyl,boy2;

說明了兩個變量boyl和boy2為stu結構類型。也可以用宏定義使用一個符號常量來表示

一個結構類型,例如:

#defineSTUstructstu

STU

{intnum;

charname[20];

charsex;

floatscore;

);

STUboyl,boy2;

8.1結構體高等教育“十

(2)在定義結構體類型的同時說明結構體變量

例如:

structstu

{intnum;

charname[20];

charsex;

floatscore;

}boyl,boy2;

(3)直接說明結構體變量

例如:

struct

{intnum;

charname[20];

charsex;

floatscore;

}boyl,boy2;

修|8.1結構體造翳等教育“十

第三種方法與第二種方法的區(qū)別在于第三種方法中省去了結構體名,而直

接給出結構體變量。三種方法中說明的boyl,boy2變量都具有相同的結構。說明了

boyl,boy2變量為stu類型后,即可向這兩個變量中的各個成員賦值。

在上述Stu結構體定義中,所有的成員都是基本數(shù)據(jù)類型或數(shù)組類型。成員

也可以又是一個結構體類型,即構成了嵌套的結構體。

修|8.1結構體造翳等教育“十

例如:首先定義一個結構體date,由

structdate

month(月)、day(日)、year(年)三個成員組

{intmonth;

intday;成。在定義并說明變量boyl和boy2時,

intyear;其中的成員birthday被說明為data結構體類

};型。成員名可與程序中其它變量同名,互不

struct

{intnum;干擾。結構體變量成員的表示方法,在程序

charname[20];中使用結構體變量時,往往不把它作為一個

charsex;整體來使用。

structdatebirthday;

floatscore;

Jboyl,boy2;

說明:結構體在內(nèi)存中存儲容量是各成員容量之和,這是與后面聯(lián)合體的重要區(qū)別。

修|8.1結構體造翳等教育“十

8.1.3結構體變量的引用

一般情況下,不能對一個結構體變量作為整體引用,只能引用其中的成員。

結構體變量中成員引用的一般形式為:

結構體變量名.成員名

其中,是域成員運算符,是C語言中優(yōu)先級最高的運算符之一。

例如:boyl.num即第一個人的學號,boy2.sex即第二個人的性別。如果成

員本身又是一個結構體,則必須逐級找到最低級的成員才能使用。

例如:boyl.birthday,month即第一個人出生的月份。成員可以在程序中單

獨使用,與普通變量完全相同。

修|8.1結構體造翳等教育“十

8.1.4結構體變量的賦值

對于結構體變量,只有以下兩種情況可以對結構體變量賦值。

(1)結構體變量整體賦值

例如:

boy2=boyl;

(2)取結構體變量地址

例如:

&boy2;

&boyl;

注意:結構體變量名是地址常量,含義與數(shù)組名和函數(shù)名相同,不能對結構體變量做

整體輸入/輸出。例如:

scanf(〃%d,%s,%c,〃,&boyl);

printf(〃%d,%s,%c,%f〃,boyl);

這些語句都是不允許的,只能對結構體成員進行輸入/輸出。

修|8.1結構體造翳等教育“十

例8.1給結構體變量賦值并輸出其值。

ttinclude<stdio.h>

voidmain()

{structstu/*定義結構體stu*/

{intnum;

char*name;

charsex;

floatscore;

}boyl,boy2;/*定義stu類型的變量boyl、boy2

*/

boyl.num=102;

boy1.name=〃Zhangping〃;

printf("inputsexandscore:\n,z);

scanf(z,%c%fz,,&boyl.sex,&boyl.score);/*給boyl的成員sex和score賦值*/

boy2=boyl;/*把boyl整

體賦給boy2*/

printf("number/d\nnaineMs'n”,boy2.num,boy2.name);

printf(〃sex=%c\nscore=%6.2f\n〃,boy2.sex,boy2.score);

修|8.1結構體造翳等教育“十

程序運行結果:

inputsexandscore:

M96Z

number」02

name=Zhangping

sex二M

score=J96.00

本程序中用賦值語句給num和name兩個成員賦值,name是一個字符串指針

變量。用scanf()函數(shù)動態(tài)地輸入sex和score成員值,然后把boyl的所有成員的值

整體賦予boy2。最后分別輸出boy2的各個成員值。

修|8.1結構體造翳等教育“十

8.1.5結構體變量的初始化

如果結構體變量為全局變量或者靜態(tài)變量,則可以對它做初始

化賦值。對局部或自動結構體變量不能做初始化賦值。

修|8.1結構體造翳等教育“十

例8.2外部結構體變量初始化。

ttinclude<stdio.h>

structstu/*定義結構體*/

{intnum;

char*name;

charsex;

floatscore;

}boy2,boy1={102,z/Zhangping〃,'M',78.5};/*對變量boyl的成員初始化*/

voidmain()

{boy2=boyl;/*把boyl整體賦給boy2*/

printf(〃number=%d\nname二%s\n〃,boy2.num,boy2.name);

printf(〃sex=%c\nscore=%6.2f\n〃,boy2.sex,boy2.score);

修|8.1結構體造翳等教育“十

程序運行結果:

number=102

name=Zhangping

sex=M

score=J*78.50

本程序中,boy2,boyl均被定義為外部結構體變量,并對boyl作了初始

化賦值。在main。函數(shù)中,把boyl的值整體賦予boy2,然后用兩個printf()語句

輸出boy2各成員的值。

修|8.1結構體造翳等教育“十

例8.3靜態(tài)結構體變量初始化。

ttinclude<stdio.h>

voidmain()

{staticstructstu/*定義靜態(tài)結構體*/

{intnum;

char*name;

charsex;

floatscore;

}boy2,boyl={102,Zhangping〃,'M',78.5};/*對變量boyl的成員初始化*/

boy2=boyl;

printf("numberMd\nname或s'n”,boy2.num,boy2.name);

printf(,zsex=%c\nscore=%6.2f\n〃,boy2.sex,boy2.score);

本程序是把boyl,boy2都定義為靜態(tài)局部的結構體變量,同樣可以做初始化賦

值。

修|8.1結構體造翳等教育“十

8.1.6結構體數(shù)組

一個結構體變量可以處理一個對象,如果有多個對象,則需要多個結構體變

量,數(shù)組的元素也可以是結構體類型的,因此可以構成結構體數(shù)組。結構體數(shù)組的每

一個元素都是具有相同結構體類型的下標結構體變量。在實際應用中,經(jīng)常用結構體

數(shù)組來表示具有相同數(shù)據(jù)結構的一個群體。如一個班的學生檔案,一個車間職工的工

資表等

人、°結構體數(shù)組的定義方法和結構體變量相似,也有三種方式:

(1)先定義結構體類型,再定義結構體數(shù)組。

例如:

structstu

{intnum;

char*name;

charsex;

floatscore;

);

structstuboy[5];

定義了一個結構體數(shù)組boy,共有5個元素,boy[0]-boy[4]每個數(shù)組元素

都具有structstu的結構體形式。o

8.1結構體高等教育“十

(2)在定義結構體類型的同時定義結構體數(shù)組。

例如:

structstu

{intnum;

char*name;

charsex;

floatscore;

}boy[5];

(3)直接定義結構體數(shù)組。

例如:

struct

{intnum;

char*name;

charsex;

floatscore;

}boy[5];

修|8.1結構體造翳等教育“十

對外部結構體數(shù)組或靜態(tài)結構體數(shù)組可以做初始化賦值。例如:

structstu

{intnum;

char*name;

charsex;

floatscore;

}boy[5]={{101,z,Liping〃,'M',45},

{102,z/Zhangping〃,'M',62.5},

{103,"Hefang〃,'F',92.5},

{104,“Chengling〃,'F',87},

{105,z,Wangming〃,'M',58}};

當對全部元素做初始化賦值時,也可不給出數(shù)組長度。

修|8.1結構體造翳等教育“十

例8.4計算學生的平均成績和不及格的人數(shù)。

^include<stdio.h>

structstu/*定義

結構體*/

{intnum;

char*name;

charsex;

floatscore;

}boy[5]={{101,Z/Liping",'M',45},{102,“Zhangping〃,'M',62.5},{103,〃He

,,5

fang','F',92.5},{104,“Chengling','F',87},{105,〃Wangming)M*,58}};

/*對結構體數(shù)組元素初始化*/

voidmain()

{inti,c=0;

floatave,s=0;

for(1=0;i<5;i++)

{s+=boy[i].score;

if(boy[i].score<60)

c+二1;

)

printf(〃s=%6.2f\n〃,s);

ave=s/5;/*計算

平均成績*/〃

printf(,zaverage=%6.2f\ncount=%d\n〃,ave,c);

修|8.1結構體造翳等教育“十

程序運行結果:

s=345.00

average=169.00

count=2

本例程序中定義了一個外部結構體數(shù)組boy,共5個元素,并作了初

始化賦值。在main函數(shù)中用for語句逐個累加各元素的score成員值存于s之

中,如score的值小于60(不及格),即計數(shù)器C加1,循環(huán)完畢后計算平均成績

,并輸出全班總分、平均分及不及格人數(shù)。

普通羸等教育“十

8.1結構體

例8.5建立同學通訊錄。

^include<stdio.h>

ttdefineNUM2

structmem/*定

義結構體*/

{charname[20];

charphone[10];

);

voidmain()

{structmemman[NUM];

inti;

for(i=0;i<NUM;i++)/*輸

入通訊錄*/〃〃

{printf(z,inputname:");

gets(man[i].name);

printf(z,inputphone:");

gets(man[i].phone);

printf(,,Name\t\tPhone\n,z);

for(i=0;i<NUM;i++)/*輸

出通訊錄*/〃〃

printf(〃%s\t%s\n〃,man[i].name,man.phone);

修|8.1結構體造翳等教育“十

程序運行結果:

inputname:Zhangjun/

inputphone:88888888Z

inputname:Wangfang/

inputphone:99999999Z

NamePhone

Zhangjun88888888

Wangfang99999999

本程序中定義了一個結構體類型mem,它有兩個成員name和phone,用來

表示姓名和電話號碼。在主函數(shù)中定義man為具有mem類型的結構體數(shù)組。在for

語句中,用gets()函數(shù)分別輸入各個元素中兩個成員的值。然后又在for語句中用

printf()語句輸出各元素中兩個成員值。

修|8.1結構體造翳等教育“十

8.1.7指向結構體變量的指針變量

結構體指針變量是一個指針變量,用來指向改變量所分配的存儲區(qū)域的首

地址。結構體指針變量還可以用來指向結構體數(shù)組中的元素。結構體指針與以前介

紹的各種指針在特性和使用方法上完全相同。結構體指針變量的運算也按照C語言的

地址計算規(guī)則進行的。例如,結構體指針變量加1將指向內(nèi)存中下一個結構體變量,

結構體指針變量自身地址值的增加量取決于它所指向的結構體變量的數(shù)據(jù)長度(

sizeof()函數(shù)獲取)。總之,結構體指針變量是指向一個結構體變量的指針變量。

修|8.1結構體造翳等教育“十

1.結構體指針變量的定義

定義結構體指針變量的一般形式為:

struct結構體類型名*結構指針變量名;

例如:

structstu

{intnum;

char*name;

charsex;

floatscore;

}boy,*pstu;

pstu=&boy;

也可以定義結構體類型后再定義結構體指針變量。

結構體名和結構體變量是兩個不同的概念,不能混淆。結構體名只能表示一

個結構體形式,編譯系統(tǒng)并不對它分配內(nèi)存空間。只有當某變量被說明為這種類型的

結構時,才對該變量分配存儲空間。有了結構指針變量,就能更方便地訪問結構變量

的各個成員。

修|8.1結構體造翳等教育“十

2.結構體指針變量的賦值

結構體指針變量必須先賦值后使用。賦值是把結構體變量的首地址賦給該指

針變量,不能把結構名賦給該指針變量。例如,不能寫成pstu二&stu;。

注意:pstu已為指向一個結構體類型的指針變量,它只能指向結構體變量而

不能指向它其中一個成員。換句話說:pstu只能存放結構體變量的地址。例如,不能寫

成pstu二&stu.num;o

修|8.1結構體造翳等教育“十

3.結構體指針變量的引用

定義好一個結構體指針變量之后,就可以對該指針變量進行各種操作。例

如,給一個結構體變量指針賦一個地址值,輸出一個結構體變量指針的成員值,訪

問結構體變量指針所指向的變量的成員等。引用結構體指針變量的一般形式為:

(*結構指針變量).成員名;

結構指針變量-〉成員名;

例如:

(*pstu).num;

pstu-〉num;

應該注意0^$的)兩側(cè)的括號不可少,因為成員符的優(yōu)先級高于

“*”。如去掉括號寫作*pstu.num,則等效于*(pstu.num),這樣,意義就完全不

對了。

修|8.1結構體造翳等教育“十

例8.6分析下面程序的運行結果。

ttinclude<stdio.h>

structstu/*定義結構體

*/

{intnum;

char*name;

charsex;

floatscore;

}boyl={102,“Zhangping〃,'M',78.5},*pstu;

voidmain()

{pstu=&boyl;

printf(〃nuniber=%d\nnanie二%s\n〃,boyl.num,boyl.name);

printf(〃sex=%c\nscore=%6.2f\n\n〃,boyl.sex,boyl.score);

printf(〃number=%d\nnaine二%s\n〃,(*pstu).num,(*pstu).name);

printf(,,sex=%c\nscore=%6.2f\n\n〃,(*pstu).sex,(*pstu).score);

printf(,,number=%d\nname=%s\n,z,pstu->num,pstu->name);

printf(〃sex=%c\nscore=%6.2f\n\n〃,pstu-〉sex,pstu->score);

修|8.1結構體造翳等教育“十

程序運行結果:

number=102

name=Zhangping

sex二M

score=J*78.50

本程序序定義了一個結構體類型Stu,定義了Stu類型結構變量boyl并

作了初始化賦值,還定義了一個指向stu類型結構體的指針變量pstu。在main。

函數(shù)中,pstu被賦予boyl的地址,因此pstu指向boyl。然后在printf()語句內(nèi)用

三種形式輸出boyl的各個成員值。

造富羸等教育“十

8.2動態(tài)內(nèi)存分配與鏈表

我們存儲數(shù)量比較多的同類型或同結構的數(shù)據(jù)時,一般首先考慮數(shù)組

O然而在實際應用中,當處理一些難以確定其數(shù)量的數(shù)據(jù)時,如果用數(shù)組來處

理,必須事先分配一個足夠大的連續(xù)空間,以保證數(shù)組元素數(shù)量充分夠用,但

這樣處理時對存儲空間的一種浪費。c語言使用動態(tài)內(nèi)存分配來解決這樣的問

題,其中常用的就是鏈表。鏈表是一種常見的數(shù)據(jù)結構,它動態(tài)地進行存儲分

配,并且可以方便而又簡單地進行數(shù)據(jù)插入,刪除等操作。

普通羸等教育“十

鎏8.2動態(tài)內(nèi)存分配與鏈表

8.2.1鏈表的概念

鏈表是指若干個數(shù)據(jù)按一定的原則連接起來。這個原則為:前一個數(shù)據(jù)指

向下一個數(shù)據(jù),只有通過前一個數(shù)據(jù)項才能找到下一個數(shù)據(jù)項。

鏈表有一個“頭指針”(head),它指向鏈表的第一個元素(數(shù)據(jù)項)。鏈

表的一個元素稱為一個“結點”(node)。結點中包含兩部分內(nèi)容,第一部分是結點

數(shù)據(jù)本身,如圖8-1中的A、B、C、D所示。結點的第二部分是一個指針,它指

向下一個結點。最后一個結點稱為“表尾”,表尾結點的指針不指向任何地址,因

此為空(NULL)o

圖8T鏈表結構圖

8.2動態(tài)內(nèi)存分配與鏈表造富暈等教育“十

如果每個結點采用一個指針,將前一個結點的指針指向下一個結點,這稱為

單鏈表。如果每個結點有兩個指向其他結點的指針,則稱為雙鏈表。本節(jié)主要討論單

鏈表的運算。

由以上簡單鏈表可以看到,鏈表中的每個結點至少包含兩個域,一個域用來

存放數(shù)據(jù),其類型根據(jù)需存放的數(shù)據(jù)類型定義。另一個域用來存放下一個結點的地址

,因此必然是一個指針類型,此指針的類型應該是所指向的表結點的結構體類型。

在C語言中,可以用結構體類型來實現(xiàn)鏈表,例如:

structstudent

{intlong;

floatscore;

structstudent*next;/*指向

下一結點*/

);

其中next是結構體指針變量,用來存放下一個結點的地址,即next是指向下一個結點

造富羸等教育“十

8.2動態(tài)內(nèi)存分配與鏈表

,、[1"I,>ie-xr、.*

8.2.2動態(tài)存儲分配

C語言允許在函數(shù)執(zhí)行部分的任何地方使用動態(tài)存儲分配函數(shù)開辟或收回存

儲單元,這樣的存儲分配叫動態(tài)存儲分配。動態(tài)分配使用自由、節(jié)約內(nèi)存。

鏈表是動態(tài)分配存儲空間的,也就是說在需要的時候才開辟一個結點的存儲

空間。在C語言中提供了以下有關的函數(shù)來實現(xiàn)動態(tài)存儲分配和釋放,這些函數(shù)包含

在“stdio.h”或“malloc.h”中。

8.2動態(tài)內(nèi)存分配與鏈表造富暈等教育“十

1.mallocO函數(shù)(分配內(nèi)存空間函數(shù))

調(diào)用形式為:

void*malloc(size);

其作用是在內(nèi)存中動態(tài)獲取一個大小為size個字節(jié)的連續(xù)存儲空間。該函數(shù)將返回

一個void類型的指針,若分配成功,就返回所分配的空間的起始地址,否則,就返

回空指針(NULL)o

2.calloc函數(shù)(分配內(nèi)存空間函數(shù))

調(diào)用形式為:

void*calloc(unsignedn,unsignedsize);

其作用是在內(nèi)存中動態(tài)獲取n個大小為size個字節(jié)的存儲空間。該函數(shù)將返回一個

void類型的指針,若分配成功,就返回內(nèi)存單元的起始地址,否則,返回空指針(

NULL)。用該函數(shù)可以動態(tài)地獲取一個一維數(shù)組空間,其中n為數(shù)組元素個數(shù),每個

數(shù)組元素的大小為size個字節(jié)。

8.2動態(tài)內(nèi)存分配與鏈表造富暈等教育“十

3.free。函數(shù)(釋放內(nèi)存空間函數(shù))

調(diào)用形式為:

voidfree(void*p);

其作用是釋放由P指針所指向的內(nèi)存空間。即系統(tǒng)回收,使這段空間又可以被其他變

量所用。指針變量P是最近一次調(diào)用malloc()或callocO函數(shù)時返回的值,不能是

任意的地址。

4.realloc函數(shù)

調(diào)用形式為:

void*recalloc(void*p,unsignedsize);

其作用是將P所指的已分配的內(nèi)存空間重新分配成大小為size個字節(jié)的空間。它用于

改變已分配的空間的大小,可以增減單元數(shù)。函數(shù)返回新內(nèi)存的首地址,如果內(nèi)存

不夠,則返回空指針(NULL)o

造富羸等教育“十

鎏8.2動態(tài)內(nèi)存分配與鏈表

例8.7分配一塊區(qū)域,輸入一個學生數(shù)據(jù)。

^include<stdio.h>

ttinclude<stdlib.h>

voidmain()

{structstu/*定義結構體*/

{intnum;

char*name;

charsex;

floatscore;

}*ps;/*定義一個結構體指針變

量ps*/

ps=(structstu*)malloc(sizeof(structstu));

ps->num=102;/*輸入學生數(shù)據(jù)*/

ps->name=〃Zhangping〃;

ps-〉sex='M';

ps->score=62.5;

printf(〃number=%d\nnanie=%s\rr,ps->num,ps->name);

printf(〃sex=%c\nscore=%6.2f\n〃,ps->sex,ps->score);

free(ps);

造富羸等教育“十

8.2動態(tài)內(nèi)存分配與鏈表

,、[1"I,>ie-xr、.*

程序運行結果:

number=102

name=Zhangping

sex=M

score=J*62.50

本程序中,定義了結構體類型Stu,定義了Stu類型指針變量ps。然后分配

一塊Stu大內(nèi)存區(qū),并把首地址賦予PS,使PS指向該區(qū)域。再以PS為指向結構體的

指針變量對各成員賦值,并用printf()輸出各成員值。最后用free。函數(shù)釋放ps指

向的內(nèi)存空間。整個程序包含了申請內(nèi)存空間、使用內(nèi)存空間、釋放內(nèi)存空間三個

步驟,實現(xiàn)存儲空間的動態(tài)分配。

造富羸等教育“十

8.2動態(tài)內(nèi)存分配與鏈表

8.2.3建立和輸出鏈表

所謂動態(tài)建立鏈表是指在程序執(zhí)行過程中從無到有地建立鏈表,將一個個

新生成的結點順次鏈接入已建立的鏈表上,上一個結點的指針域存放下一個結點的

起始地址,并給各結點數(shù)據(jù)域賦值。

所謂輸出鏈表是將鏈表上各個結點的數(shù)據(jù)域中的值依次輸出,直到鏈表結

尾。

造富羸等教育“十

8.2動態(tài)內(nèi)存分配與鏈表

例8.8以三個結構體變量為結點建立一個簡單的鏈表并輸出。

^include<stdio.h>

structnode

{intdata;

structnode*next;

);

voidmain()

{structnodea,b,c,*head,*p;

head=&a;/*頭結點指向a結點*/

a.data=5;a.next=&b;/*a結點指向b結點*/

b.data=10;b.next=&c;/*b結點指向c結點*/

c.data=15;c.next=NULL;/*c結點是尾結點*/

p=head;/*使P指向a結點*/

while(p!=NULL)

{printf(〃%d—〉〃,p->data);/*輸出指針P所指向結點的數(shù)據(jù)*/

p=p->next;/*使P指向下一個結點

printf(〃NULL\n〃);

程序運行結果:

5—>10—>15—>NULL

8.2動態(tài)內(nèi)存分配與鏈表造富暈等教育“十

8.2.4鏈表的基本操作

鏈表的基本操作包括,建立并初始化鏈表,遍歷訪問鏈表(包括查找結點

、輸出結點等),刪除鏈表中的結點,在鏈表中插入結點。鏈表的各種基本操作的

步驟如下。

1.建立鏈表

①建立頭結點(或定義頭指針變量)。

②讀取數(shù)據(jù)。

③生成新結點。

④將數(shù)據(jù)存入結點的數(shù)據(jù)域中。

⑤將新結點連接到鏈表中(將新結點地址賦給上一個結

點的指針域連接到鏈表)。

⑥重復步驟②—⑤,直到尾結點為止。

普通羸等教育“十

鎏8.2動態(tài)內(nèi)存分配與鏈表

2.遍歷訪問鏈表

輸出鏈表即順序訪問鏈表中各結點的數(shù)據(jù)域,方法是:從頭結點開始,不斷

地讀取數(shù)據(jù)和下移指針變量,直到尾結點為止。

3.刪除鏈表中的一個結點

①找到要刪除結點的前驅(qū)結點。

②將要刪除結點的后驅(qū)結點的地址賦給要刪除結點的前驅(qū)

結點的指針域。

③將要刪除結點的存儲空間釋放。

4.在鏈表的某結點前插入一個結點

①開辟一個新結點并將數(shù)據(jù)存入該結點的數(shù)據(jù)域。

②找到插入點結點。

③將新結點插入到鏈表中,將新結點的地址賦給插入點上

一個結點的指針域,并將插入點的地址存入新結點的指

針域。

例8.9建立并輸出一個學生成績鏈表(假設學生成績表中只含姓名和成績)。

ttinclude<stdio.h>

ttinclude<malloc.h>

typedefstructstudent/*自定義鏈表結點數(shù)據(jù)類型名ST和指針類型

名*STU*/

{charname[20];

intscore;

structstudent*next;/*結點指針域*/

ST,*STU;

STUcreatelink(intn)/*建立一個由n個結點構成的單鏈表函數(shù),返回結點指針類型

{inti;

STUp,q,head;

if(n<=0)

return(NULL);

head=(STU)malloc(sizeof(ST));/*生成第一個結點*/

pri?nt1fc(/"〃?inpu.t1datas:\n〃\);

scanf(,z%s%d,z,head->name,&head->score);/*兩個數(shù)據(jù)之間用一個空格間隔*/

p=head;

造富羸等教育“十

8.2動態(tài)內(nèi)存分配與鏈表

,、[1"I,>ie-xr、.*

for(i=l;i<n;i++)

{q=(STU)malloc(sizeof(ST));

scanf(,z%s%d〃,q->name,&q->score)_2

p->next=q;/*連接q結點*/、_

、PF;/*P源勤q上,再準備連接下一個結點q*/

p->next=NULL;/*置尾結點指針域為空指社*/

return(head);滔曲遑立超萊南罩林表頭指針返回*/

voidlist(STUhead)/*鏈表的輸出*/

(STUp=head;/*從頭軸針由裳,依次輸出各結點的值,直到遇

NULL*/

while(p!=NULL)〃

{printf(〃%s\t%d\n〃,p->name,p->score);

、p=p->next;/*p指針順序后移一個結點*/

voidmain()

{STUh;

intn;〃

printf("inputnumberofnode:");

scanf(〃%d〃,&n);

h二create]ink(n);/*調(diào)用建立集鏈表的國基*/

list(h);耦用輸出鏈蓑的函數(shù)*/

高等教育“十

8.2動態(tài)內(nèi)存分配與鏈表

程序運行結果:

inputnumberof

node:4/

inputdatas:

A60Z

B70Z

C80Z

D90Z

A60

B70

C80

D90

造富羸等教育“十

鎏8.2動態(tài)內(nèi)存分配與鏈表

例8.10編寫一個函數(shù),在例8.9中建立的鏈表的前面插入一個結點。

^include<stdio.h>

^include<malloc.h>

/*將例8.9中typedefstructstudent直到voidlist(STUhead)函數(shù)全部插入到該

位置*/

STUincreasenodel(STUhead)

{STUs;

s=(STU)malloc(sizeof(ST));

printf(,zInputnewnodedatas:z/);

scanf(〃%s%d〃,s->name,&s->score);

s->next=head;

head's;

return(head);

)

voidmain()

{STUh;intn;

printf("inputnumberofnode:");

scanf(〃%d〃,&n);

h二createlink(n);/*調(diào)用建立單鏈表的函數(shù)*/

list(h);/*詞甬播出鏈表的函數(shù)*/

h=increasenodel(h);

list(h);

高等教育“十

8.2動態(tài)內(nèi)存分配與鏈表

程序運行結果:

inputnumberofnode:3Z

inputdatas:

A60Z

B70Z

C80/

A60

B70

C80

inputnewnodedatas:E100/

E100

A10

B20

C30

造富羸等教育“十

鎏8.2動態(tài)內(nèi)存分配與鏈表

例8.11編寫一個函數(shù),在例8.9建立的鏈表的第i個結點之后插入一個新結點。

^include<stdio.h>

ttinclude<malloc.h>

/*將例8.9中typedefstructstudent直到voidlist(STUhead)函數(shù)全部插入到該位

置*/

STUincreasenode2(STUhead,inti)

{STUs,p,q;

intj=0;/*查找第i個結點計數(shù)用*/

if(i<0)

returnNULL;/*參數(shù)i值不合理*/

s=(STU)malloc(sizeof(ST));

printf(,zinputnewnodedatas:?,);

scanf(,,%s%d〃,s->name,&s->score);

if(i=0)/*i=0表明是在第一個結點之前插入新結點*/

{s->next=head;

head's;

return(head);

q二head;/*查找新結點的位置,在P和q之間*/

0⑷造富羸等教育“十

嚓8.2動態(tài)內(nèi)存分配與鏈表

while(j<i&&q!=NULL)

{j++;

PF;

q=q->next;

)

if(j<i)

returnNULL;/*i值超過表長*/

p->next=s;/*在p和q之間,即第i個結點之后插入新結點

*/

s->next=q;

return(head);

)

voidmain()

{STUh;intn;inti;

printf("inputnumberofnode:");

scanf(〃%d〃,&n);

h二create]ink(n);/*調(diào)用建立單鏈表的函數(shù)*/

list(h),〃/*調(diào)用期出鏈表函函數(shù)*/

printf("inputnewnodenumber:");/*輸入新結點*/

scanf(〃%d〃,&i);

h=increasenode2(h,i);

list(h);

造富羸等教育“十

8.2動態(tài)內(nèi)存分配與鏈表

程序運行結果:

inputnumberofnode:3Z

inputdatas:

A60Z

B70Z

C80Z

A60

B70

C80

inputnewnodenumber:2/

inputnewnodedatas:E100/

A10

B20

E100

C30

造富羸等教育“十

鎏8.2動態(tài)內(nèi)存分配與鏈表

例8.12刪除鏈表中的表首結點函數(shù)。

ttinclude<stdio.h>

^include<malloc.h>

/*將例8.9中typedefstructstudent直到voidlist(STUhead)函數(shù)全部插入到

該位普*/

STUdeletenodel(STUhead)

{STUs;

if(head!=NULL)〃

{printf(''afterdeletedthefirstnode:\n,z);

s=head;

head=s-〉next;

free(s);

return(head);

)

voidmain()

{STUh;intn;

printf("inputnumberofnode:;

scanf(〃%d〃,&n);

h二create]ink(n);用建立單鏈表的函數(shù)*/

list(h);用輸出鏈表的函數(shù)*/

h二deletenodel(h);

list(h);

溫馨提示

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

評論

0/150

提交評論