第8章 全国计算机等级考试计算机二级C语言 结构体 和共用体_第1页
第8章 全国计算机等级考试计算机二级C语言 结构体 和共用体_第2页
第8章 全国计算机等级考试计算机二级C语言 结构体 和共用体_第3页
第8章 全国计算机等级考试计算机二级C语言 结构体 和共用体_第4页
第8章 全国计算机等级考试计算机二级C语言 结构体 和共用体_第5页
已阅读5页,还剩88页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

造富羸等教育“十

第8章结构体和共用体

前面的章节中已经介绍了各种基本数据类型、数组和指针

。但只有这些数据类型还难以处理一些比较复杂的数据结构。本章

将以前面介绍的数据类型为基础,进一步介绍结构体类型、共用体

类型和枚举类型。

普通羸等教育“十

第8章结构体和共用体

8.1结构体

8.2动态内存分配与链表

8.3共用体类型n

8.4枚举类型

8.5用户自定义类型n

8.6程序举例n

造富羸等教育“十

8.1结构体

SI鼠

修|8.1结构体造翳等教育“十

8.1.1结构类型定义

在实际问题中,一组数据往往具有不同的数据类型。例如,在学生登记表

中,姓名应为字符型;学号可为整型或字符型;年龄应为整型;性别应为字符型;成

绩可为整型或实型。但这些显然不能用一个数组来存放这一组数据。因为数组中各

元素的类型和长度都必须一致,以便于编译系统处理。为了解决这个问题,C语言

中给出了另一种构造数据类型一“结构体”。

“结构体”是一种构造类型,它是由若干“成员”组成的。每一个成员可

以是一个基本数据类型或者又是一个构造类型。结构体既然是一种“构造”而成的

数据类型,那么在说明和使用之前必须先定义它,也就是构造它。如同在说明和调

用函数之前要先定义函数一样。

修|8.1结构体造翳等教育“十

定义一个结构体类型的一般形式为:

struct结构体名

{

结构成员的说明;

);

成员表由若干个成员组成,每个成员都是该结构体的一个组成部分。对每个成员也

必须作类型说明,其形式为:

类型说明符成员名;

成员名的命名应符合标识符的书写规定。例如:

structstu

{intnum;

charname[20];

charsex;

floatscore;

);

修|8.1结构体造翳等教育“十

在这个结构体定义中,结构体名为stu,该结构体由4个成员组成。第一

个成员为num,整型变量;第二个成员为name,字符数组变量;第三个成员为sex

,字符变量;第四个成员为score,实型变量。应注意在括号“}”后的分号是不

可少的。结构体定义之后,即可进行变量说明。凡说明为结构体Stu的变量都由上

述4个成员组成。由此可见,结构是一种复杂的数据类型,是数目固定,类型不同

的若干有序变量的集合。

修|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结构体造翳等教育“十

第三种方法与第二种方法的区别在于第三种方法中省去了结构体名,而直

接给出结构体变量。三种方法中说明的boyl,boy2变量都具有相同的结构。说明了

boyl,boy2变量为stu类型后,即可向这两个变量中的各个成员赋值。

在上述Stu结构体定义中,所有的成员都是基本数据类型或数组类型。成员

也可以又是一个结构体类型,即构成了嵌套的结构体。

修|8.1结构体造翳等教育“十

例如:首先定义一个结构体date,由

structdate

month(月)、day(日)、year(年)三个成员组

{intmonth;

intday;成。在定义并说明变量boyl和boy2时,

intyear;其中的成员birthday被说明为data结构体类

};型。成员名可与程序中其它变量同名,互不

struct

{intnum;干扰。结构体变量成员的表示方法,在程序

charname[20];中使用结构体变量时,往往不把它作为一个

charsex;整体来使用。

structdatebirthday;

floatscore;

Jboyl,boy2;

说明:结构体在内存中存储容量是各成员容量之和,这是与后面联合体的重要区别。

修|8.1结构体造翳等教育“十

8.1.3结构体变量的引用

一般情况下,不能对一个结构体变量作为整体引用,只能引用其中的成员。

结构体变量中成员引用的一般形式为:

结构体变量名.成员名

其中,是域成员运算符,是C语言中优先级最高的运算符之一。

例如:boyl.num即第一个人的学号,boy2.sex即第二个人的性别。如果成

员本身又是一个结构体,则必须逐级找到最低级的成员才能使用。

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

独使用,与普通变量完全相同。

修|8.1结构体造翳等教育“十

8.1.4结构体变量的赋值

对于结构体变量,只有以下两种情况可以对结构体变量赋值。

(1)结构体变量整体赋值

例如:

boy2=boyl;

(2)取结构体变量地址

例如:

&boy2;

&boyl;

注意:结构体变量名是地址常量,含义与数组名和函数名相同,不能对结构体变量做

整体输入/输出。例如:

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()函数动态地输入sex和score成员值,然后把boyl的所有成员的值

整体赋予boy2。最后分别输出boy2的各个成员值。

修|8.1结构体造翳等教育“十

8.1.5结构体变量的初始化

如果结构体变量为全局变量或者静态变量,则可以对它做初始

化赋值。对局部或自动结构体变量不能做初始化赋值。

修|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。函数中,把boyl的值整体赋予boy2,然后用两个printf()语句

输出boy2各成员的值。

修|8.1结构体造翳等教育“十

例8.3静态结构体变量初始化。

ttinclude<stdio.h>

voidmain()

{staticstructstu/*定义静态结构体*/

{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都定义为静态局部的结构体变量,同样可以做初始化赋

值。

修|8.1结构体造翳等教育“十

8.1.6结构体数组

一个结构体变量可以处理一个对象,如果有多个对象,则需要多个结构体变

量,数组的元素也可以是结构体类型的,因此可以构成结构体数组。结构体数组的每

一个元素都是具有相同结构体类型的下标结构体变量。在实际应用中,经常用结构体

数组来表示具有相同数据结构的一个群体。如一个班的学生档案,一个车间职工的工

资表等

人、°结构体数组的定义方法和结构体变量相似,也有三种方式:

(1)先定义结构体类型,再定义结构体数组。

例如:

structstu

{intnum;

char*name;

charsex;

floatscore;

);

structstuboy[5];

定义了一个结构体数组boy,共有5个元素,boy[0]-boy[4]每个数组元素

都具有structstu的结构体形式。o

8.1结构体高等教育“十

(2)在定义结构体类型的同时定义结构体数组。

例如:

structstu

{intnum;

char*name;

charsex;

floatscore;

}boy[5];

(3)直接定义结构体数组。

例如:

struct

{intnum;

char*name;

charsex;

floatscore;

}boy[5];

修|8.1结构体造翳等教育“十

对外部结构体数组或静态结构体数组可以做初始化赋值。例如:

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}};

当对全部元素做初始化赋值时,也可不给出数组长度。

修|8.1结构体造翳等教育“十

例8.4计算学生的平均成绩和不及格的人数。

^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}};

/*对结构体数组元素初始化*/

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

本例程序中定义了一个外部结构体数组boy,共5个元素,并作了初

始化赋值。在main函数中用for语句逐个累加各元素的score成员值存于s之

中,如score的值小于60(不及格),即计数器C加1,循环完毕后计算平均成绩

,并输出全班总分、平均分及不及格人数。

普通羸等教育“十

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,用来

表示姓名和电话号码。在主函数中定义man为具有mem类型的结构体数组。在for

语句中,用gets()函数分别输入各个元素中两个成员的值。然后又在for语句中用

printf()语句输出各元素中两个成员值。

修|8.1结构体造翳等教育“十

8.1.7指向结构体变量的指针变量

结构体指针变量是一个指针变量,用来指向改变量所分配的存储区域的首

地址。结构体指针变量还可以用来指向结构体数组中的元素。结构体指针与以前介

绍的各种指针在特性和使用方法上完全相同。结构体指针变量的运算也按照C语言的

地址计算规则进行的。例如,结构体指针变量加1将指向内存中下一个结构体变量,

结构体指针变量自身地址值的增加量取决于它所指向的结构体变量的数据长度(

sizeof()函数获取)。总之,结构体指针变量是指向一个结构体变量的指针变量。

修|8.1结构体造翳等教育“十

1.结构体指针变量的定义

定义结构体指针变量的一般形式为:

struct结构体类型名*结构指针变量名;

例如:

structstu

{intnum;

char*name;

charsex;

floatscore;

}boy,*pstu;

pstu=&boy;

也可以定义结构体类型后再定义结构体指针变量。

结构体名和结构体变量是两个不同的概念,不能混淆。结构体名只能表示一

个结构体形式,编译系统并不对它分配内存空间。只有当某变量被说明为这种类型的

结构时,才对该变量分配存储空间。有了结构指针变量,就能更方便地访问结构变量

的各个成员。

修|8.1结构体造翳等教育“十

2.结构体指针变量的赋值

结构体指针变量必须先赋值后使用。赋值是把结构体变量的首地址赋给该指

针变量,不能把结构名赋给该指针变量。例如,不能写成pstu二&stu;。

注意:pstu已为指向一个结构体类型的指针变量,它只能指向结构体变量而

不能指向它其中一个成员。换句话说:pstu只能存放结构体变量的地址。例如,不能写

成pstu二&stu.num;o

修|8.1结构体造翳等教育“十

3.结构体指针变量的引用

定义好一个结构体指针变量之后,就可以对该指针变量进行各种操作。例

如,给一个结构体变量指针赋一个地址值,输出一个结构体变量指针的成员值,访

问结构体变量指针所指向的变量的成员等。引用结构体指针变量的一般形式为:

(*结构指针变量).成员名;

结构指针变量-〉成员名;

例如:

(*pstu).num;

pstu-〉num;

应该注意0^$的)两侧的括号不可少,因为成员符的优先级高于

“*”。如去掉括号写作*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。

函数中,pstu被赋予boyl的地址,因此pstu指向boyl。然后在printf()语句内用

三种形式输出boyl的各个成员值。

造富羸等教育“十

8.2动态内存分配与链表

我们存储数量比较多的同类型或同结构的数据时,一般首先考虑数组

O然而在实际应用中,当处理一些难以确定其数量的数据时,如果用数组来处

理,必须事先分配一个足够大的连续空间,以保证数组元素数量充分够用,但

这样处理时对存储空间的一种浪费。c语言使用动态内存分配来解决这样的问

题,其中常用的就是链表。链表是一种常见的数据结构,它动态地进行存储分

配,并且可以方便而又简单地进行数据插入,删除等操作。

普通羸等教育“十

鎏8.2动态内存分配与链表

8.2.1链表的概念

链表是指若干个数据按一定的原则连接起来。这个原则为:前一个数据指

向下一个数据,只有通过前一个数据项才能找到下一个数据项。

链表有一个“头指针”(head),它指向链表的第一个元素(数据项)。链

表的一个元素称为一个“结点”(node)。结点中包含两部分内容,第一部分是结点

数据本身,如图8-1中的A、B、C、D所示。结点的第二部分是一个指针,它指

向下一个结点。最后一个结点称为“表尾”,表尾结点的指针不指向任何地址,因

此为空(NULL)o

图8T链表结构图

8.2动态内存分配与链表造富晕等教育“十

如果每个结点采用一个指针,将前一个结点的指针指向下一个结点,这称为

单链表。如果每个结点有两个指向其他结点的指针,则称为双链表。本节主要讨论单

链表的运算。

由以上简单链表可以看到,链表中的每个结点至少包含两个域,一个域用来

存放数据,其类型根据需存放的数据类型定义。另一个域用来存放下一个结点的地址

,因此必然是一个指针类型,此指针的类型应该是所指向的表结点的结构体类型。

在C语言中,可以用结构体类型来实现链表,例如:

structstudent

{intlong;

floatscore;

structstudent*next;/*指向

下一结点*/

);

其中next是结构体指针变量,用来存放下一个结点的地址,即next是指向下一个结点

造富羸等教育“十

8.2动态内存分配与链表

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

8.2.2动态存储分配

C语言允许在函数执行部分的任何地方使用动态存储分配函数开辟或收回存

储单元,这样的存储分配叫动态存储分配。动态分配使用自由、节约内存。

链表是动态分配存储空间的,也就是说在需要的时候才开辟一个结点的存储

空间。在C语言中提供了以下有关的函数来实现动态存储分配和释放,这些函数包含

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

8.2动态内存分配与链表造富晕等教育“十

1.mallocO函数(分配内存空间函数)

调用形式为:

void*malloc(size);

其作用是在内存中动态获取一个大小为size个字节的连续存储空间。该函数将返回

一个void类型的指针,若分配成功,就返回所分配的空间的起始地址,否则,就返

回空指针(NULL)o

2.calloc函数(分配内存空间函数)

调用形式为:

void*calloc(unsignedn,unsignedsize);

其作用是在内存中动态获取n个大小为size个字节的存储空间。该函数将返回一个

void类型的指针,若分配成功,就返回内存单元的起始地址,否则,返回空指针(

NULL)。用该函数可以动态地获取一个一维数组空间,其中n为数组元素个数,每个

数组元素的大小为size个字节。

8.2动态内存分配与链表造富晕等教育“十

3.free。函数(释放内存空间函数)

调用形式为:

voidfree(void*p);

其作用是释放由P指针所指向的内存空间。即系统回收,使这段空间又可以被其他变

量所用。指针变量P是最近一次调用malloc()或callocO函数时返回的值,不能是

任意的地址。

4.realloc函数

调用形式为:

void*recalloc(void*p,unsignedsize);

其作用是将P所指的已分配的内存空间重新分配成大小为size个字节的空间。它用于

改变已分配的空间的大小,可以增减单元数。函数返回新内存的首地址,如果内存

不够,则返回空指针(NULL)o

造富羸等教育“十

鎏8.2动态内存分配与链表

例8.7分配一块区域,输入一个学生数据。

^include<stdio.h>

ttinclude<stdlib.h>

voidmain()

{structstu/*定义结构体*/

{intnum;

char*name;

charsex;

floatscore;

}*ps;/*定义一个结构体指针变

量ps*/

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

ps->num=102;/*输入学生数据*/

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动态内存分配与链表

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

程序运行结果:

number=102

name=Zhangping

sex=M

score=J*62.50

本程序中,定义了结构体类型Stu,定义了Stu类型指针变量ps。然后分配

一块Stu大内存区,并把首地址赋予PS,使PS指向该区域。再以PS为指向结构体的

指针变量对各成员赋值,并用printf()输出各成员值。最后用free。函数释放ps指

向的内存空间。整个程序包含了申请内存空间、使用内存空间、释放内存空间三个

步骤,实现存储空间的动态分配。

造富羸等教育“十

8.2动态内存分配与链表

8.2.3建立和输出链表

所谓动态建立链表是指在程序执行过程中从无到有地建立链表,将一个个

新生成的结点顺次链接入已建立的链表上,上一个结点的指针域存放下一个结点的

起始地址,并给各结点数据域赋值。

所谓输出链表是将链表上各个结点的数据域中的值依次输出,直到链表结

尾。

造富羸等教育“十

8.2动态内存分配与链表

例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所指向结点的数据*/

p=p->next;/*使P指向下一个结点

printf(〃NULL\n〃);

程序运行结果:

5—>10—>15—>NULL

8.2动态内存分配与链表造富晕等教育“十

8.2.4链表的基本操作

链表的基本操作包括,建立并初始化链表,遍历访问链表(包括查找结点

、输出结点等),删除链表中的结点,在链表中插入结点。链表的各种基本操作的

步骤如下。

1.建立链表

①建立头结点(或定义头指针变量)。

②读取数据。

③生成新结点。

④将数据存入结点的数据域中。

⑤将新结点连接到链表中(将新结点地址赋给上一个结

点的指针域连接到链表)。

⑥重复步骤②—⑤,直到尾结点为止。

普通羸等教育“十

鎏8.2动态内存分配与链表

2.遍历访问链表

输出链表即顺序访问链表中各结点的数据域,方法是:从头结点开始,不断

地读取数据和下移指针变量,直到尾结点为止。

3.删除链表中的一个结点

①找到要删除结点的前驱结点。

②将要删除结点的后驱结点的地址赋给要删除结点的前驱

结点的指针域。

③将要删除结点的存储空间释放。

4.在链表的某结点前插入一个结点

①开辟一个新结点并将数据存入该结点的数据域。

②找到插入点结点。

③将新结点插入到链表中,将新结点的地址赋给插入点上

一个结点的指针域,并将插入点的地址存入新结点的指

针域。

例8.9建立并输出一个学生成绩链表(假设学生成绩表中只含姓名和成绩)。

ttinclude<stdio.h>

ttinclude<malloc.h>

typedefstructstudent/*自定义链表结点数据类型名ST和指针类型

名*STU*/

{charname[20];

intscore;

structstudent*next;/*结点指针域*/

ST,*STU;

STUcreatelink(intn)/*建立一个由n个结点构成的单链表函数,返回结点指针类型

{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);/*两个数据之间用一个空格间隔*/

p=head;

造富羸等教育“十

8.2动态内存分配与链表

,、[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);/*调用建立集链表的国基*/

list(h);耦用输出链蓑的函数*/

高等教育“十

8.2动态内存分配与链表

程序运行结果:

inputnumberof

node:4/

inputdatas:

A60Z

B70Z

C80Z

D90Z

A60

B70

C80

D90

造富羸等教育“十

鎏8.2动态内存分配与链表

例8.10编写一个函数,在例8.9中建立的链表的前面插入一个结点。

^include<stdio.h>

^include<malloc.h>

/*将例8.9中typedefstructstudent直到voidlist(STUhead)函数全部插入到该

位置*/

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);/*调用建立单链表的函数*/

list(h);/*词甬播出链表的函数*/

h=increasenodel(h);

list(h);

高等教育“十

8.2动态内存分配与链表

程序运行结果:

inputnumberofnode:3Z

inputdatas:

A60Z

B70Z

C80/

A60

B70

C80

inputnewnodedatas:E100/

E100

A10

B20

C30

造富羸等教育“十

鎏8.2动态内存分配与链表

例8.11编写一个函数,在例8.9建立的链表的第i个结点之后插入一个新结点。

^include<stdio.h>

ttinclude<malloc.h>

/*将例8.9中typedefstructstudent直到voidlist(STUhead)函数全部插入到该位

置*/

STUincreasenode2(STUhead,inti)

{STUs,p,q;

intj=0;/*查找第i个结点计数用*/

if(i<0)

returnNULL;/*参数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动态内存分配与链表

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);/*调用建立单链表的函数*/

list(h),〃/*调用期出链表函函数*/

printf("inputnewnodenumber:");/*输入新结点*/

scanf(〃%d〃,&i);

h=increasenode2(h,i);

list(h);

造富羸等教育“十

8.2动态内存分配与链表

程序运行结果:

inputnumberofnode:3Z

inputdatas:

A60Z

B70Z

C80Z

A60

B70

C80

inputnewnodenumber:2/

inputnewnodedatas:E100/

A10

B20

E100

C30

造富羸等教育“十

鎏8.2动态内存分配与链表

例8.12删除链表中的表首结点函数。

ttinclude<stdio.h>

^include<malloc.h>

/*将例8.9中typedefstructstudent直到voidlist(STUhead)函数全部插入到

该位普*/

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);用建立单链表的函数*/

list(h);用输出链表的函数*/

h二deletenodel(h);

list(h);

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论