结构体及共用体课件_第1页
结构体及共用体课件_第2页
结构体及共用体课件_第3页
结构体及共用体课件_第4页
结构体及共用体课件_第5页
已阅读5页,还剩179页未读 继续免费阅读

下载本文档

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

文档简介

第9章结构体与共用体北京科技大学计算机系C

语言程序设计.1第9章结构体与共用体北京科技大学计算机系C语言程序第9章结构体与共用体9.1结构体9.2共用体9.3枚举类型与类型命名.2022/10/312第9章结构体与共用体9.1结构体.2022/10/222一个学生的信息有学号、姓名、性别、年龄、住址、成绩等。一本图书的信息有分类编号、书名、作者、出版社、出版日期、价格、库存量等。如何描述这些类型不同的相关数据?9.1结构体9.1.1结构体与结构体类型的定义?信息管理结构体——一种构造类型数据

结构体由若干不同类型的数据项组成,构成结构体的各个数据项称为结构体成员。.2022/10/313一个学生的信息有学号、姓名、性别、年龄、住址、成绩等

struct结构体名{数据类型1成员名1;数据类型2成员名2;……数据类型n成员名n;

};9.1结构体9.1.1结构体与结构体类型的定义结构体类型定义的一般形式:

struct为关键字;结构体名是用户定义的类型标识。{}中是组成该结构体的成员。成员的数据类型可以是C语言所允许的任何数据类型。.2022/10/314struct结构体名9.1结构体9.1.1结构体与例如图书类型的定义:

structbookcard{charnum[10];/*图书分类编号是字符数组类型*/charname[30];/*书名是字符数组类型*/

charauthor[30];/*作者是字符数组类型*/charpublisher[60];/*出版社是字符数组类型*/

floatprice;/*价格是单精度实型*/

intn;/*库存量是整型*/

};9.1结构体9.1.1结构体与结构体类型的定义.2022/10/315例如图书类型的定义:9.1结构体9.1.1结构体与结构例如学生类型的定义:structstudent{charnum[8];/*学号是字符数组类型*/charname[30];/*姓名是字符数组类型*/charsex;/*性别是字符型

*/intage;/*年龄是整型

*/

charaddr[60];/*住址是字符数组类型*/intscore[6];/*成绩是整型数组类型*/

};9.1结构体9.1.1结构体与结构体类型的定义.2022/10/316例如学生类型的定义:9.1结构体9.1.1结构体与结构体9.1结构体9.1.2结构体变量的定义与初始化1.结构体类型变量的定义

利用已定义的结构体类型名定义变量struct结构体名

变量名表;例如:structbookcardbook1[100];structstudents[30],t1,t2;结构体变量的各个成员在内存中占用连续存储区域,结构体变量所占内存大小为结构体中每个成员所占用内存的长度之和。structstudentnum8个字节name30个字节sex1个字节age2个字节addr60个字节score12个字节.2022/10/3179.1结构体9.1.2结构体变量的定义与初始化1.结构类型与变量是不同的概念。应先定义一个结构体类型,而后再定义结构体变量。系统对类型不分配空间,仅对变量分配空间。只能对变量赋值、存取或运算,而不能对一个类型赋值、存取或运算。成员也可以是结构体变量。对结构中的成员,可以单独使用,它的作用与地位相当于普通变量。成员名可与程序中的变量名相同时,也可与不同结构体类型的成员名相同,二者代表不同的对象。

structdate{intyear,month,day;};structstudent{charnum[8];charname[30];charsex;

structdatebirthday;/*成员为结构体类型*/

charaddr[60];intscore[6];

};9.1结构体结构体类型与变量的说明num8个字节name30个字节sex1个字节birthdayyear2个字节month2个字节day2个字节addr60个字节score12个字节.2022/10/318类型与变量是不同的概念。成员也可以是结构体变量。对结构中的成9.1.2结构体变量的定义和初始化1.结构体类型变量的定义

在定义结构体类型的同时定义变量例如:structstudent{charnum[8],name[20],sex;intage;floatscore;

}st[30];struct结构体名{

成员定义表;

}变量名表;.2022/10/3199.1.2结构体变量的定义和初始化1.结构体类型变量的定1.结构体类型变量的定义

直接定义结构体类型变量

例如:struct{charnum[8],name[20],sex;intage;floatscore;

}st[30],a,b,c;struct{

成员定义表;

}变量名表;9.1.2结构体变量的定义和初始化.2022/10/31101.结构体类型变量的定义直接定义结构体类型变量例如:s2.结构体变量的初始化

【例9.4】结构体变量的初始化。structdate{intyear,month,day;};structstudent{charnum[8],name[20],sex;structdatebirthday;floatscore;}a={"9606011","Liming",'M',{1977,12,9},83},b={"9608025","Zhangliming",'F',{1978,5,10},87},c;

如果初值个数少于结构体成员个数,

则将无初值对应的成员赋以0值。

如果初值个数多于结构体成员个数,

则编译出错。9.1.2结构体变量的定义和初始化.2022/10/31112.结构体变量的初始化【例9.4】结构体变量的初始化。2.结构体变量的初始化

【例9.5】结构体数组的初始化。structs{charnum[8],name[20],sex;floatscore;}stu[3]={{"9606011","Liming",'M',87.5},

{"9606012","Zhangjiangguo",'M',79},{"9606013","Wangping",'F',90}};

元素的个数可以省略,根据赋初值时

结构体常量的个数确定数组元素的个数

9.1.2结构体变量的定义和初始化.2022/10/31122.结构体变量的初始化【例9.5】结构体数组的初始化。3.结构体变量的运算

用sizeof运算符计算结构体变量所占内存空间

structdate{intyear,month,day;};structstudent{charnum[8],name[20],sex;structdatebirthday;floatscore;}a;

sizeof(a)

的结果为8+20+1+6+4=39

sizeof(structstudent)

的结果为39

9.1.2结构体变量的定义和初始化.2022/10/31133.结构体变量的运算用sizeof运算符计算结构体变量所3.结构体变量的运算

同类型结构体变量之间的赋值运算结构体变量之间进行赋值时,系统将按成员一一对应赋值。structdate{intyear,month,day;};structstudent{charnum[8],name[20],sex;structdatebirthday;floatscore;}a={"9606011","Liming",'M',{1977,12,9},83},b,c;c=a;9.1.2结构体变量的定义和初始化.2022/10/31143.结构体变量的运算同类型结构体变量之间的赋值运算结构体3.结构体变量的运算

对结构体变量进行取址运算

structdate{intyear,month,day;};structstudent{charnum[8],name[20],sex;structdatebirthday;floatscore;}a;对结构体变量a进行

&a运算,可以得到a的首地址,它是结构体类型指针。

9.1.2结构体变量的定义和初始化.2022/10/31153.结构体变量的运算对结构体变量进行取址运算struc4.结构体变量成员的引用

结构体变量成员引用的一般形式:结构体变量名.成员名

结构体变量a的各成员可分别表示为a.num、、a.sex、a.birthday、a.score

structdate{intyear,month,day;};structstudent{charnum[8],name[20],sex;structdatebirthday;floatscore;}a;“.”是分量运算符,运算级别最高。a.birthday.year

a.birthday.month

a.birthday.day

结构体变量的各个成员可进行何种运算,由该成员的数据类型决定

9.1.2结构体变量的定义和初始化.2022/10/31164.结构体变量成员的引用结构体变量成员引用的一般形式:【例9.6】编写一个统计选票的程序。structcandidate{charname[20];/*name为候选人姓名*/

intcount;/*count为候选人得票数*/}list[]={{"invalid",0},{"Zhao",0},{"Qian",0},

{"Sun",0},{"Li",0},{"Zhou",0}};9.1.2结构体变量的定义和初始化.2022/10/3117【例9.6】编写一个统计选票的程序。9.1.2结构体变量的main(){inti,n;printf("Entervote\n");

scanf("%d",&n);/*输入所投候选人编号,编号从1开始*/

while(n!=-1)/*当输入编号为-1时,表示投票结束*/

{

if(n>=1&&n<=5)

list[n].count++;/*有效票,则相应候选人计票成员加1*/

else

{printf("invalid\n");list[0].count++;}/*无效票,list[0]的计票成员加1*/

scanf("%d",&n);/*输入所投候选人编号*/

}9.1.2结构体变量的定义和初始化.2022/10/3118main()9.1.2结构体变量的定义和初始化.2022for(i=1;i<=5;i++)printf("%s:%d\n",list[i].name,list[i].count);printf("%s:%d\n",list[0].name,list[0].count);}9.1.2结构体变量的定义和初始化.2022/10/3119for(i=1;i<=5;i++)9.1.2结构体变9.1结构体1.结构体指针变量的定义

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

struct结构体名

*指针变量名;structdate{intyear,month,day;}*q;例如:structstudent*p;p是指向structstudent结构体变量的指针变量

9.1.3结构体的指针.2022/10/31209.1结构体1.结构体指针变量的定义结构体指针变量定义9.1.3结构体的指针2.结构体成员的三种引用形式

用结构体变量名的引用形式:

d.year

d.month

d.daystructdate{intyear,month,day;}d,*p=&d;

用结构体指针变量的引用形式:(*p).year(*p).month(*p).dayp->yearp->monthp->day“->”是指向结构体成员运算符,优先级为一级

p=&d.year×.2022/10/31219.1.3结构体的指针2.结构体成员的三种引用形式用结

【例9_a】输入今天的日期,然后输出该日期。

main() {structdate/*在函数中定义结构体类型*/

{

intyear,month,day;

}today,*p=&today;/*定义结构体变量及其指针*/

printf("Entertodaydate(YYYY/MM/DD):"); scanf("%d/%d/%d",&today.year,&today.month,

&today.day);printf("Today:%d/%d/%d\n",p->year,p->month,p->day);

}9.1.3结构体的指针Entertodaydate(YYYY/MM/DD):2006/06/23Today:2006/6/23.2022/10/3122【例9_a】输入今天的日期,然后输出该日期。9.1.3结3.指向结构体数组的指针

【例9.7】利用结构体指针输出一组化学元素名称及其原子量。structlist{inti;charname[4];floatw;}tab[4]={{1,"H",1.008},{2,"He",4.0026},{3,"Li",6.941},{4,"Be",9.01218}};tab数组1Htab[0]1.0082Hetab[1]4.00263Litab[2]6.9414Betab[3]9.012189.1.3结构体的指针.2022/10/31233.指向结构体数组的指针【例9.7】利用结构体指针输出一3.指向结构体数组的指针

main(){structlist*p;printf("No\tName\tAtomicWeight\n");for(p=tab;p<tab+4;p++)printf("%d\t%s\t%f\n",p->i,p->name,p->w);}tab数组1Htab[0]1.0082Hetab[1]4.00263Litab[2]6.9414Betab[3]9.01218pppppNoNameAtomicWeight1H1.0082He4.00263Li

6.9414Be

9.012189.1.3结构体的指针.2022/10/31243.指向结构体数组的指针main()tab数组1Hta【例9.8】分析自增自减运算对程序结果的影响。structcode{inti;charch;}a[]={{100,'A'},{200,'B'},{300,'C'},{400,'D'}};(接后面)a数组100a[0]'A'200a[1]'B'300a[2]'C'400a[3]'D'9.1.3结构体的指针.2022/10/3125【例9.8】分析自增自减运算对程序结果的影响。a数组100amain(){structcode*p=a;printf("%d\t",++p->i);printf("%c\t",(++p)->ch);printf("%d\t",(p++)->i);printf("%c\t",++p->ch);printf("%d\t",p->i++);printf("%d\n",p->i);}a数组100a[0]'A'200a[1]'B'300a[2]'C'400a[3]'D'p101'D'301101B200D3003019.1.3结构体的指针.2022/10/3126main()a数组100a[0]'A'200a[1]'B'9.1结构体9.1.4函数间结构体数据的传递方法一:在函数之间直接传递结构体数据。方法二:在函数之间传递结构体指针。方法三:利用全局结构体变量传递结构体数据。

.2022/10/31279.1结构体9.1.4函数间结构体数据的传递方法一:在函

【例9.9】编制一个复数乘法函数,采用值传递的方

法传送数据。structcomplex/*定义存放复数的结构体类型*/{floatre;/*re成员用于存放复数的实部*/

floatim;/*im成员用于存放复数的虚部*/};9.1.4函数间结构体数据的传递.2022/10/3128【例9.9】编制一个复数乘法函数,采用值传递的方

法传structcomplexmultiplier(structcomplexcx,

structcomplexcy){structcomplexcz;cz.re=cx.re*cy.re-cx.im*cy.im;cz.im=cx.re*cy.im+cx.im*cy.re;return(cz);}

形参是结构体变量。调用此函数时,

系统将分别为形参cx和cy各分配一个

sizeof(structcomplex)大小的内存空间,

每个成员都要一一传递。

9.1.4函数间结构体数据的传递.2022/10/3129structcomplexmultiplier(strumain(){structcomplexx,y,z;x.re=3.2;x.im=1.5;y.re=2.7;y.im=4.6;z=multiplier(x,y);/*实参是结构体变量*/printf("%f+%fi\n",z.re,z.im);/*以复数形式输出*/}9.1.4函数间结构体数据的传递.2022/10/3130main()9.1.4函数间结构体数据的传递.2022/

【例9.10】编制一个复数乘法函数,采用传递指针

的方法达到传送数据的目的。structcomplex{floatre,im;};voidmultiplier(structcomplex*px,

structcomplex*py,structcomplex*pz){pz->re=px->re*py->re-px->im*py->im;pz->im=px->re*py->im+px->im*py->re;}9.1.4函数间结构体数据的传递.2022/10/3131【例9.10】编制一个复数乘法函数,采用传递指针

的方法main(){structcomplexx,y,z;x.re=3.2;x.im=1.5;y.re=2.7;y.im=4.6;multiplier(&x,&y,&z);/*实参是结构体变量的地址*/printf("(%f+%fi)*(%f+%fi)=%f+%fi\n",x.re,x.im,

y.re,y.im,z.re,z.im);}9.1.4函数间结构体数据的传递.2022/10/3132main()9.1.4函数间结构体数据的传递.2022/9.1结构体9.1.5结构体的应用——链表①链表中每个元素称为一个结点。②构成链表的结点必须是结构体类型数据。1.链表的基本结构

head100010323284129613822008图9.2动态单向链表示意图C3284H1296A1382I2008NNULL1000

1032

③相邻结点的地址不一定是连续的,依靠指针将

它们连接起来。structnode{charc;structnode*next;};.2022/10/31339.1结构体9.1.5结构体的应用——链表①链表中每个

C语言提供了相关的存储管理库函数。这里仅介绍其中三个,它们的原型说明在“stdlib.h”头文件和“alloc.h”头文件中,使用这三个函数时,应选择其中一个头文件包含到源程序中。⑴动态分配存储区函数malloc()函数原型:void

*malloc(unsignedsize);调用格式:malloc(size)功能:在内存分配一个size字节的存储区。调用

结果为新分配的存储区的首地址,是一个void

类型指针。若分配失败,则返回NULL(即0)。9.1.5结构体的应用——链表2.动态分配和释放存储单元

在ANSIC标准中,关键字void有两种用法。第一种用法,可将无返回值的函数定义为void类型第二种用法,用void

*

定义指针,这是一个指向非具体数据类型的指针,称为无类型指针。.2022/10/3134C语言提供了相关的存储管理库函数。这里仅介绍其中三【例9.11】调用malloc函数分配所需存储单元。#include<stdlib.h>main(){structst{intn;structst*next;}*p;p=(structst*)malloc(sizeof(structst));p->n=5;p->next=NULL;printf("p->n=%d\tp->next=%x\n",p->n,p->next);}将函数返回值转换成结构体指针

9.1.5结构体的应用——链表p->n=5p->next=0nnext5NULLp.2022/10/3135【例9.11】调用malloc函数分配所需存储单元。将函数返⑵动态分配存储区函数calloc()函数原型:

void

*calloc(unsignedintn,unsignedintsize);调用格式:calloc(n,size)功能:在内存分配一个n倍size字节的存储区。

调用结果为新分配的存储区的首地址,是一个void

类型指针。若分配失败,则返回NULL(即0)。2.动态分配和释放存储单元

9.1.5结构体的应用——链表.2022/10/3136⑵动态分配存储区函数calloc()2.动态分配和释放【例9.12】调用calloc函数分配所需存储单元。#include<stdlib.h>main(){inti,*ip;ip=(int*)calloc(10,2);for(i=0;i<10;i++)scanf("%d",ip+i);for(i=0;i<10;i++)printf("%d",*(ip+i));printf("\n");}动态分配了10个存放整型数据的存储单元

9.1.5结构体的应用——链表.2022/10/3137【例9.12】调用calloc函数分配所需存储单元。动态分配⑶释放动态分配存储区函数free()函数原型:void

free(void

*p);2.动态分配和释放存储单元

此函数无返回值实参必须是一个指向动态分配存储区

的指针,它可以是任何类型的指针变量。调用格式:free(p)功能:释放p所指向的动态分配的存储区。9.1.5结构体的应用——链表.2022/10/3138⑶释放动态分配存储区函数free()2.动态分配和释放q

建立链表就是根据需要一个一个地开

辟新结点,在结点中存放数据并建立结点

之间的链接关系。

【例9.13】建立一个学生电话簿

的单向链表函数。3.建立单向链表头指针h设为NULL读入一个学生姓名当姓名长度不为0开辟新结点p=NEW

strcpy(p->name,name)gets(p->tel)p->next=NULLh==NULLTFh指向第一个连接新结点结点h=pq->next=pq指向新的尾结点q=p

读入一个学生姓名图9.3建立单向链表NULLhpChang62783410NULLWang63212986NULLpq

9.1.5结构体的应用——链表.2022/10/3139q建立链表就是根据需要一个一个地开#include<stdlib.h>#include<string.h>#defineNEW(structnode*)malloc(sizeof(structnode))structnode{charname[20],tel[9];structnode*next;};9.1.5结构体的应用——链表.2022/10/3140#include<stdlib.h>9.1.5结构体的应structnode*create(){staticstructnode*h;structnode*p,*q;charname[20];

h=NULL;printf("name:");gets(name);while(strlen(name)!=0)/*当输入的姓名不是空串循环*/

{

p=NEW;/*开辟新结点*/

if(p==NULL)/*p为NULL,新结点分配失败*/{printf("Allocationfailure\n");exit(0);/*结束程序运行*/}9.1.5结构体的应用——链表.2022/10/3141structnode*create()9.1.5结构strcpy(p->name,name);/*为新结点中的成员赋值*/

printf("tel:");gets(p->tel);

p->next=NULL;

if(h==NULL)/*h为空,表示新结点为第一个结点*/

h=p;/*头指针指向第一个结点*/

else/*h不为空*/

q->next=p;/*新结点与尾结点相连接*/

q=p;/*使q指向新的尾结点*/

printf("name:");gets(name);

}

returnh;}9.1.5结构体的应用——链表main(){structnode*head;……head=create();……}.2022/10/3142strcpy(p->name,name);【例9.14】输出学生电话簿链表函数。4.输出单向链表中各结点信息Chang62783410Li68752341NULLWang63212986

p指向第一个结点

p=head

当p不为NULL输出结点数据p指向下一个结点:p=p->next图9.5输出链表的N-S图headppppNULL9.1.5结构体的应用——链表.2022/10/3143【例9.14】输出学生电话簿链表函数。4.输出单向链表中各#include<stdlib.h>#include<string.h>#defineNEW(structnode*)malloc(sizeof(structnode))structnode{charname[20],tel[9];structnode*next;};voidprlist(structnode*head){structnode*p;

p=head;while(p!=NULL)

{printf("%s\t%s\n",p->name,p->tel);

p=p->next;

}}main(){structnode*head;……head=create();prlist(head);……}.2022/10/3144#include<stdlib.h>voidprlist.2022/10/3145.2022/10/2245在链表中,如果要删除第i个结点,一般是将第(i-1)

个结点直接与第(i+1)个结点相连接,然后再释放第i个

结点的存储单元。5.删除单向链表中指定的结点headNULL第i-1个结点第i个结点第i+1个结点

9.1.5结构体的应用——链表.2022/10/3146在链表中,如果要删除第i个结点,一般是将第(i-【例9.15】删除学生电话簿链表中指定学生的信息。headpChang62783410Li68752341NULLWang63212986(a)删除第一个结点(head=p->next)9.1.5结构体的应用——链表.2022/10/3147【例9.15】删除学生电话簿链表中指定学生的信息。headpChang62783410Li68752341NULLWang63212986(b)删除中间结点或尾结点(q->next=p->next)p

q9.1.5结构体的应用——链表.2022/10/3148headpChang62783410Li687headpChang62783410Li68752341NULLWang63212986pp(c)未找到指定的结点(strcmp(x,p->name)!=0)

qq

9.1.5结构体的应用——链表.2022/10/3149headpChang62783410Li687

p=headwhile(strcmp(x,p->name)!=0&&p->next!=NULL)q指针跟随p指针后移查找(q=p;p=p->next;)strcmp(x,p->name)==0TFp==headTFhead=p->nextq->next=p->next没找到

free(p)图9.9删除链表中指定结点的N-S图删除

第一个结点

删除中间结点或尾结点

删除结点工

作分两步:查找结点删除结点学生姓名当姓名不同并且不是尾结点循环9.1.5结构体的应用——链表.2022/10/3150p=head删除

第一个结点删除中间结点或尾#include<stdlib.h>#include<string.h>#defineNEW(structnode*)malloc(sizeof(structnode))structnode{charname[20],tel[9];structnode*next;};structnode*delnode(structnode*head,char*x){structnode*p,*q;staticstructnode*h;if(head==NULL)

{printf("Thisisaemptylist.");/*空链表情况*/

returnhead;}

p=head;while(strcmp(x,p->name)!=0&&p->next!=NULL)

{

q=p;p=p->next;}/*q指针尾随p指针向表尾移动*/查找结点

.2022/10/3151#include<stdlib.h>structnode

if(strcmp(x,p->name)==0)

{if(p==head)head=p->next;/*删除第一个结点*/

else

q->next=p->next;/*删除中间或尾结点*/

free(p);/*释放被删除的结点*/

}

elseprintf("Notfound.");/*未找到指定的结点*/

h=head;returnh;}9.1.5结构体的应用——链表.2022/10/3152if(strcmp(x,p->name)==0)9.1将一个新结点插入到链表中,首先要寻找插入的位置。如果要求在第i个结点前插入,可设置三个工作指针p0、p和q,p0是指向待插入结点的指针。利用p和q指针查找第i个结点,找到后再将新结点链接到链表上。

6.在单向链表中插入结点headNULL第i个结点ppqqp0p新的第i个结点9.1.5结构体的应用——链表.2022/10/3153将一个新结点插入到链表中,首先要寻找插入的位置。headpChang62783410Li68752341NULLWang63212986(a)在表头插入结点(head=p0;p0->next=p)Zhao62758421p09.1.5结构体的应用——链表.2022/10/3154headpChang62783410Li687523headChang62783410Li68752341NULLWang63212986(b)在表中间插入结点(q->next=p0;p0->next=p)pqZhao62758421p09.1.5结构体的应用——链表.2022/10/3155headChang62783410Li68752headpChang62783410Li68752341NULLWang63212986p(c)在表尾追加结点(p->next=p0;p0->next=NULL)

q

Zhao62758421p0Zhao62758421NULL9.1.5结构体的应用——链表pq

.2022/10/3156headpChang62783410Li687【例9.16】在学生电话簿链表中插入一个学生的信息。要求将新的信息插入在指定学生信息之前,如果未找到指定学生,则追加在链表尾部。

head==NULLTFp=headhead=p0while(strcmp(x,p->name)!=0&&p->next!=NULL)p0->nextq指针跟随p指针后移查找(q=p;p=p->next;)=NULLstrcmp(x,p->name)==0TFp==headTFp->next=p0head=p0q->next=p0p0->next=NULLp0->next=p图9.11在链表指定位置前插入结点的N-S图当姓名不同并且不是尾结点循环空表时

插入

结点在表尾

追加结点

插入结点工

作分两步:查找插

入位置连接

新结点在表头

插入结点

在表中间

插入结点

9.1.5结构体的应用——链表.2022/10/3157【例9.16】在学生电话簿链表中插入一个学生的信息。要求将新#include<stdlib.h>#include<string.h>#defineNEW(structnode*)malloc(sizeof(structnode))structnode{charname[20],tel[9];structnode*next;};9.1.5结构体的应用——链表.2022/10/3158#include<stdlib.h>9.1.5结构体的应structnode*insert(structnode*head,structnode*p0,

char*x){structnode*p,*q;staticstructnode*h;if(head==NULL)

{head=p0;/*空表时,插入结点*/

p0->next=NULL;

}else

{

p=head;while(strcmp(x,p->name)!=0&&p->next!=NULL)

{

q=p;p=q->next;}

查找插入点

9.1.5结构体的应用——链表.2022/10/3159structnode*insert(structnod

if(strcmp(x,p->name)==0)

{if(p==head)head=p0;/*在表头插入结点*/

else

q->next=p0;/*在表中间插入结点*/

p0->next=p;

}else

{

p->next=p0;/*在表尾插入结点*/

p0->next=NULL;

}

}

h=head;returnh;}9.1.5结构体的应用——链表.2022/10/3160if(strcmp(x,p->name)==【例9.17】学生电话簿链表管理程序。编制此程序可利用例9.13至例9.16的4个函数完成链表的建立、输出、删除和插入等功能,这里只需编制一个main函数完成对这4个函数的调用。#include<stdlib.h>#defineNEW(structnode*)malloc(sizeof(structnode))structnode{charname[20],tel[9];structnode*next;};9.1.5结构体的应用——链表.2022/10/3161【例9.17】学生电话簿链表管理程序。编制main(){structnode*create(),*delnode(structnode*,char*);structnode*insert(structnode*,structnode*,char*);voidprlist(structnode*);structnode*head=NULL,*stu;chars[80],name[20];intc;9.1.5结构体的应用——链表.2022/10/3162main()9.1.5结构体的应用——链表.2022/1do

{do

{printf("\n****MENU****\n");printf("1.Createalist\n");printf("2.Printalist\n");printf("3.Deleteanode\n");printf("4.Insertanode\n");printf("0.Quit\n");printf("Enteryourchoice(0-4):");gets(s);c=atoi(s);

}while(c<0||c>4);可以先选择1建立一个链表,然后根据需要选择功能2、功能3、功能4、直到选择0退出程序的运行

9.1.5结构体的应用——链表.2022/10/3163do可以先选择1建立一个链表,然后根据需要选择功能2、功能3switch(c)

{case1:head=create();break;case2:prlist(head);break;case3:printf("\nInputanamedeleted:\n");gets(name);head=delnode(head,name);break;case4:stu=NEW;printf("\nInputanewnode\n");printf("name:");gets(stu->name);printf("tel:");gets(stu->tel);

stu->next=NULL;printf("\nInsertposition\n");printf("name:");gets(name);

head=insert(head,stu,name);

}}while(c);}9.1.5结构体的应用——链表.2022/10/3164switch(c)9.1.5结构体的应用——链表.20结构体类型解决了如何描述一个逻辑上相关,但数据类型不同的一组分量的集合。在需要节省内存储空间时,c语言还提供了一种由若干个不同类型的数据项组成,但共享同一存储空间的构造类型。9.2共用体9.2.1共用体与共用体类型的定义共用体——一种构造类型数据

共用体由若干不同类型的数据项组成,构成共用体的各个数据项称为共用体成员。由于共享的特性,只有最新存储的数据是有效的。.2022/10/3165结构体类型解决了如何描述一个逻辑上相关,但数据类型不

union共用体名{数据类型1成员名1;数据类型2成员名2;……数据类型n成员名n;

};9.2共用体9.2.1共用体与共用体类型的定义共用体类型定义的一般形式:

union为关键字;共用体名是用户定义的类型标识。{}中是组成该共用体的成员。成员的数据类型可以是C语言所允许的任何数据类型。.2022/10/3166union共用体名9.2共用体9.2.1共用体与共例如:

unionutype{

inti;charch;longl;charc[4];

};9.2共用体9.2.1共用体与共用体类型的定义

定义了一个unionutype共用体

类型,共用体类型定义不分配内存空间,只是说明此类型数据的组成情况。

.2022/10/3167例如:9.2共用体9.2.1共用体与共用体类型的定义u1变量chu1变量iu1变量l9.2共用体9.2.2共用体变量的定义与初始化1.共用体变量的定义

利用已定义的共用体类型名定义变量union共用体名

变量名表;例如:unionutypeu1,u2;按照共用体类型的组成,系统为定义的共用体变量分配内存单元。共用体变量所占内存大小等于共用体中占用内存的长度最长的成员。u1变量cc[0]c[1]c[2]c[3].2022/10/3168u1变量chu1变量iu1变量l9.2共用体9.2.2共9.2.2共用体变量的定义与初始化1.共用体变量的定义

在定义共用体类型的同时定义变量例如:

unionutype{

inti;charch;longl;charc[4];

}a,b,c;union共用体名{

成员定义表;

}变量名表;.2022/10/31699.2.2共用体变量的定义与初始化1.共用体变量的定义1.共用体变量的定义

直接定义共用体类型变量

例如:

union{

inti;charch;longl;charc[4];

}a,b,c;union{

成员定义表;

}变量名表;9.2.2共用体变量的定义与初始化.2022/10/31701.共用体变量的定义直接定义共用体类型变量例如:2.共用体变量的运算

用sizeof运算符计算共用体变量所占内存空间

unionutype{

inti;charch;longl;charc[4];

}a,b,c;

sizeof(a)

的结果为4

sizeof(unionutype)

的结果为4

9.2.2共用体变量的定义与初始化.2022/10/31712.共用体变量的运算用sizeof运算符计算共用体变量所2.共用体变量的运算

同类型共用体变量之间的赋值运算共用体变量之间进行赋值时,系统仅赋当前有效

成员的值(即最新存储的数据)。

unionutype{

inti;charch;longl;charc[4];

}a,*p=&a;对共用体变量进行取址运算9.2.2共用体变量的定义与初始化.2022/10/31722.共用体变量的运算同类型共用体变量之间的赋值运算3.共用体变量成员的引用

共用体变量成员的引用有三种形式。例如:

unionu{charu1;intu2;}x,*p=&x;

用共用体变量名的引用形式:

x.u1

x.u2

用共用体指针变量的引用形式:(*p).u1(*p).u2p->u1p->u29.2.2共用体变量的定义与初始化.2022/10/31733.共用体变量成员的引用共用体变量成员的引用有三种形式。4.共用体变量赋初值

【例9.18】共用体变量赋初值。unionu{charu1;intu2;};main(){unionua={0x9741};printf("1.%c%x\n",a.u1,a.u2);a.u1='a';printf("2.%c%x\n",a.u1,a.u2);}

共用体类型变量在定义时只能对第一

个成员进行赋初值。

由于第一个成员是字符型,用一个字

节,所以对于初值0x9741仅能接受0x41,

初值的高字节被截去。

1.A412.a61对u2成员的引用是无意义的9.2.2共用体变量的定义与初始化.2022/10/31744.共用体变量赋初值【例9.18】共用体变量赋初值。main(){union{longn;intk;charc;}un;un.n=0x12345678;printf("%lx\n",un.n);printf("%x\n",un.k);printf("%x\n",un.c);un.c='A';printf("%ld\n",un.n);printf("%d\n",un.k);printf("%c\n",un.c);}0x780x560x340x12低地址高地址9.2.2共用体变量的定义与初始化1234567856787830541984122081A高地址低地址0x120x340x560x4100010010001101000101011001000001.2022/10/3175main()0x780x560x340x12低地址高地址9enum是关键字;枚举名和枚举常量是标识符;枚举常量之间用逗号分隔。例如:enumweekday{Sun,Mon,Tue,Wed,Thu,Fri,Sat};enumcolor1{blue,green,red};enumflag{false,true};9.3枚举类型与类型命名9.3.1枚举类型1.枚举类型的定义

枚举类型定义的一般形式:

enum

枚举名{枚举常量取值表};

枚举是一个具有有限个整型符号常量的

集合,这些整型符号常量称为枚举常量。每个枚举类型都必须进行类型的定义,

定义时必须将其所有的枚举常量一一列举,

以便限定此枚举类型变量的取值范围。

.2022/10/3176enum是关键字;例如:9.3枚举类型与类型命名.1枚举类型2.枚举常量的整型值

隐式定义:按照类型定义时枚举常量列举的顺序分别代表0、1、2、……等整型值。

例如:enumweekday{Sun,Mon,Tue,Wed,Thu,Fri,Sat};0123456

在枚举类型中,每个枚举常量都代表一

个整型值。在定义枚举类型的同时可隐式或

显式地定义枚举常量所代表的值。

.2022/10/31779.3.1枚举类型2.枚举常量的整型值隐式定义:例如:2.枚举常量的整型值

显式定义:

在定义类型的同时指定枚举常量的值,其中如有未指定值的枚举常量,则根据前面的枚举常量的值依次递增1。例如:enumop{plus=43,minus=45,multiply=42,divide=47};enumworkday{Mon=1,Tue,Wed,Thu,Fri};23459.3.1枚举类型.2022/10/31782.枚举常量的整型值显式定义:例如:23459.3.1例如:enumflagfg;enumcolor1c1;enumcolor2{blank,brown,yellow,white}c2;enum{lightblue,lightgreen,lightred}c3;3.枚举变量的定义

枚举类型变量定义的三种形式:①enum

枚举名枚举变量名表;②enum

枚举名{枚举常量取值表}枚举变量表;③enum{枚举常量取值表}枚举变量表;9.3.1枚举类型.2022/10/3179例如:3.枚举变量的定义枚举类型变量定义的三种形式:9.4.枚举数据的运算

⑴用sizeof运算符计算枚举变量所占内存空间⑵赋值运算

fg=true;c1=red;c2=yellow;c3=lightblue;

c3=white;枚举变量中存放的是整型值,每个枚举变量占用2个字节

〤是enumcolor2类型的枚举值9.3.1枚举类型.2022/10/31804.枚举数据的运算⑴用sizeof运算符计算枚举变量所4.枚举数据的运算

⑶关系运算⑷

取址运算enumcolor2{blank,brown,yellow,white}c2;enumflagfg;

&c2、

&fgtrue>falseSun>Sat真(1)

假(0)

按枚举类型数据所代表的整型值进行比较

9.3.1枚举类型.2022/10/31814.枚举数据的运算⑶关系运算⑷取址运算true>5.枚举数据的输入输出

枚举变量的输入

枚举变量的输出

方法一:直接输出枚举变量中存放的整型值。枚举变量作为整型变量进行输入。例如:scanf("%d",&fg);1含义不直观

fg=true;printf("%d",fg);9.3.1枚举类型在C系统中,不能直接对

温馨提示

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

评论

0/150

提交评论