




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第7章其他自定义数据类型东北林业大学C
语言程序设计1第7章结构体与共用体主要内容7.1构造数据类型概述7.2结构体类型2023/1/142一个学生的信息有学号、姓名、性别、年龄、住址、成绩等。一本图书的信息有分类编号、书名、作者、出版社、出版日期、价格、库存量等。如何描述这些类型不同的相关数据?7.1构造数据类型概述?信息管理结构体——一种构造类型数据
结构体由若干不同类型的数据项组成,构成结构体的各个数据项称为结构体成员。2023/1/143
struct结构体名{数据类型1成员名1;数据类型2成员名2;……数据类型n成员名n;
};7.2结构体类型7.2.1结构体与结构体类型的定义结构体类型定义的一般形式:
struct为关键字;结构体名是用户定义的类型标识。{}中是组成该结构体的成员。成员的数据类型可以是C语言所允许的任何数据类型。2023/1/144例如图书类型的定义:
structbookcard{charnum[10];/*图书分类编号是字符数组类型*/charname[30];/*书名是字符数组类型*/
charauthor[30];/*作者是字符数组类型*/charpublisher[60];/*出版社是字符数组类型*/
floatprice;/*价格是单精度实型*/
intn;/*库存量是整型*/
};7.2结构体类型7.2.1结构体与结构体类型的定义2023/1/145例如学生类型的定义:structstudent{charnum[8];/*学号是字符数组类型*/charname[30];/*姓名是字符数组类型*/charsex;/*性别是字符型
*/intage;/*年龄是整型
*/
charaddr[60];/*住址是字符数组类型*/intscore[6];/*成绩是整型数组类型*/
};7.2结构体类型7.2.1结构体与结构体类型的定义2023/1/1467.2结构体类型7.2.2结构体变量的定义、引用与初始化1.结构体类型变量的定义
利用已定义的结构体类型名定义变量struct结构体名
变量名表;例如:structbookcardbook1[100];structstudents[30],t1,t2;结构体变量的各个成员在内存中占用连续存储区域,结构体变量所占内存大小为结构体中每个成员所占用内存的长度之和。2023/1/147类型与变量是不同的概念。应先定义一个结构体类型,而后再定义结构体变量。系统对类型不分配空间,仅对变量分配空间。只能对变量赋值、存取或运算,而不能对一个类型赋值、存取或运算。成员也可以是结构体变量。对结构中的成员,可以单独使用,它的作用与地位相当于普通变量。成员名可与程序中的变量名相同时,也可与不同结构体类型的成员名相同,二者代表不同的对象。
structdate{intyear,month,day;};structstudent{charnum[8];charname[30];charsex;
structdatebirthday;/*成员为结构体类型*/
charaddr[60];intscore[6];
};7.2结构体类型结构体类型与变量的说明2023/1/1487.2.2结构体变量的定义、引用与初始化1.结构体类型变量的定义
在定义结构体类型的同时定义变量例如:structstudent{charnum[8],name[20],sex;intage;floatscore;
}st[30];struct结构体名{
成员定义表;
}变量名表;2023/1/1491.结构体类型变量的定义
直接定义结构体类型变量
例如:struct{charnum[8],name[20],sex;intage;floatscore;
}st[30],a,b,c;struct{
成员定义表;
}变量名表;7.2.2结构体变量的定义、引用与初始化2023/1/14102.结构体变量的初始化
【例7-4】结构体变量的初始化。structdate{intyear,month,day;};structstudent{charnum[8],name[20],sex;structdatebirthday;floatscore;}a={“40826011","Liming",'M',{1991,2,9},87.5},b={“40826025","Zhangqiang",'F',{1990,5,12},85},c;
如果初值个数少于结构体成员个数,
则将无初值对应的成员赋以0值。
如果初值个数多于结构体成员个数,
则编译出错。7.2.2结构体变量的定义、引用与初始化2023/1/14112.结构体变量的初始化
【例7-5】结构体数组的初始化。structs{charnum[8],name[20],sex;floatscore;}stu[3]={{“40826011","Liming",'M',87.5},
{“40826025","Zhangqiang",‘F',85},{“40826032","Wangxinping",'F',90}};
元素的个数可以省略,根据赋初值时
结构体常量的个数确定数组元素的个数
7.2.2结构体变量的定义、引用与初始化2023/1/14123.结构体变量的运算
用sizeof运算符计算结构体变量所占内存空间
structdate{intyear,month,day;};structstudent{charnum[8],name[20],sex;structdatebirthday;floatscore;}a;
sizeof(a)
的结果为8+20+1+12+4=45
sizeof(structstudent)
的结果为45
7.2.2结构体变量的定义、引用与初始化2023/1/14133.结构体变量的运算
同类型结构体变量之间的赋值运算结构体变量之间进行赋值时,系统将按成员一一对应赋值。structdate{intyear,month,day;};structstudent{charnum[8],name[20],sex;structdatebirthday;floatscore;}a={“40826011","Liming",'M',{1977,12,9},87.5},b,c;c=a;7.2.2结构体变量的定义、引用与初始化2023/1/14143.结构体变量的运算
对结构体变量进行取址运算
structdate{intyear,month,day;};structstudent{charnum[8],name[20],sex;structdatebirthday;floatscore;}a;对结构体变量a进行
&a运算,可以得到a的首地址,它是结构体类型指针。
7.2.2结构体变量的定义、引用与初始化2023/1/14154.结构体变量成员的引用
结构体变量成员引用的一般形式:结构体变量名.成员名
结构体变量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
结构体变量的各个成员可进行何种运算,由该成员的数据类型决定
7.2.2结构体变量的定义、引用与初始化2023/1/1416【例7-6】编写一个统计选票的程序。structcandidate{charname[20];/*name为候选人姓名*/
intcount;/*count为候选人得票数*/}list[]={{"invalid",0},{"Zhang",0},{“Wang",0},
{“Li",0},{“Zhao",0},{“Liu",0}};7.2.2结构体变量的定义、引用与初始化2023/1/1417main(){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);/*输入所投候选人编号*/
}7.2.2结构体变量的定义、引用与初始化2023/1/1418for(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);}7.2.2结构体变量的定义、引用与初始化2023/1/14197.2结构体类型1.结构体指针变量的定义
结构体指针变量定义的一般形式:
struct结构体名
*指针变量名;structdate{intyear,month,day;}*q;例如:structstudent*p;p是指向structstudent结构体变量的指针变量
7.2.3结构体的指针2023/1/14207.2.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×2023/1/1421
【例】输入今天的日期,然后输出该日期。
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);
}7.2.3结构体的指针Entertodaydate(YYYY/MM/DD):2006/06/23Today:2006/6/232023/1/14223.指向结构体数组的指针
【例7-7】利用结构体指针输出一组化学元素名称及其原子量。structlist{inti;charname[4];floatw;}tab[4]={{1,"H",1.008},{2,"He",4.0026},{3,"Li",6.941},{4,"Be",9.01218}};7.2.3结构体的指针2023/1/14233.指向结构体数组的指针
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);}pppppNoNameAtomicWeight1H1.0082He4.00263Li
6.9414Be
9.012187.2.3结构体的指针2023/1/1424【例7-8】分析自增自减运算对程序结果的影响。structcode{inti;charch;}a[]={{1000,‘E'},{2000,‘F'},{3000,‘G'},{4000,‘H'}};(接后面)7.2.3结构体的指针2023/1/1425main(){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);}p1001‘H'30011001F2000H300030017.2.3结构体的指针2023/1/14267.2结构体类型7.2.4链表——结构体的应用①链表中每个元素称为一个结点。②构成链表的结点必须是结构体类型数据。1.链表的基本结构
head17822008324610855736图7-2动态单向链表示意图C3246H1085A5736INULL1782
2008
③相邻结点的地址不一定是连续的,依靠指针将
它们连接起来。structnode{charc;structnode*next;};2023/1/1427
C语言提供了相关的存储管理库函数。这里仅介绍其中三个,它们的原型说明在“stdlib.h”头文件和“alloc.h”头文件中,使用这三个函数时,应选择其中一个头文件包含到源程序中。⑴动态分配存储区函数malloc()函数原型:void
*malloc(unsignedsize);调用格式:malloc(size)功能:在内存分配一个size字节的存储区。调用
结果为新分配的存储区的首地址,是一个void
类型指针。若分配失败,则返回NULL(即0)。7.2.4链表2.动态分配和释放存储单元
在ANSIC标准中,关键字void有两种用法。第一种用法,可将无返回值的函数定义为void类型第二种用法,用void
*
定义指针,这是一个指向非具体数据类型的指针,称为无类型指针。2023/1/1428【例7-9】调用malloc函数分配所需存储单元。#include<stdlib.h>
#include<stdio.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);}将函数返回值转换成结构体指针
7.2.4链表p->n=5p->next=0nnext5NULLp2023/1/1429⑵动态分配存储区函数calloc()函数原型:
void
*calloc(unsignedintn,unsignedintsize);调用格式:calloc(n,size)功能:在内存分配一个n倍size字节的存储区。
调用结果为新分配的存储区的首地址,是一个void
类型指针。若分配失败,则返回NULL(即0)。2.动态分配和释放存储单元
7.2.4链表2023/1/1430【例7-10】调用calloc函数分配所需存储单元。#include<stdlib.h>main(){inti,*ip;ip=(int*)calloc(10,4);for(i=0;i<10;i++)scanf("%d",ip+i);for(i=0;i<10;i++)printf("%d",*(ip+i));printf("\n");}动态分配了10个存放整型数据的存储单元
7.2.4链表2023/1/1431⑶释放动态分配存储区函数free()函数原型:void
free(void
*p);2.动态分配和释放存储单元
此函数无返回值实参必须是一个指向动态分配存储区
的指针,它可以是任何类型的指针变量。调用格式:free(p)功能:释放p所指向的动态分配的存储区。7.2.4链表2023/1/1432q
建立链表就是根据需要一个一个地开
辟新结点,在结点中存放数据并建立结点
之间的链接关系。
【例7-11】建立一个学生电话簿
的单向链表函数。3.建立单向链表头指针h设为NULL读入一个学生姓名当姓名长度不为0开辟新结点p=NEW数据送入新结点
strcpy(p->name,name)
gets(p->tel);p->next=NULLh==NULLTFh指向第一个连接新结点结点h=pq->next=pq指向新的尾结点q=p
读入一个学生姓名图7-3建立单向链表NULLhppq
7.2.4链表2023/1/1433#include<stdlib.h>#include<stdio.h>#include<string.h>#defineNEW(structnode*)malloc(sizeof(structnode))structnode{charname[20],tel[9];structnode*next;};7.2.4链表2023/1/1434structnode*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);/*结束程序运行*/}7.2.4链表2023/1/1435strcpy(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;}7.2.4链表main(){structnode*head;……head=create();……}2023/1/1436【例7-12】输出学生电话簿链表函数。4.输出单向链表中各结点信息
p指向第一个结点
p=head
当p不为NULL输出结点数据p指向下一个结点:p=p->next图7-5输出链表的N-S图headppppNULL7.2.4链表2023/1/1437#include<stdio.h>#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);……}2023/1/1438在链表中,如果要删除第i个结点,一般是将第(i-1)
个结点直接与第(i+1)个结点相连接,然后再释放第i个
结点的存储单元。5.删除单向链表中指定的结点headNULL第i-1个结点第i个结点第i+1个结点
7.2.4链表2023/1/1439【例7-13】删除学生电话簿链表中指定学生的信息。headp(a)删除第一个结点(head=p->next)7.2.4链表2023/1/1440headp(b)删除中间结点或尾结点(q->next=p->next)p
q7.2.4链表2023/1/1441headppp(c)未找到指定的结点(strcmp(x,p->name)!=0)
7.2.4链表2023/1/1442
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)图7-9删除链表中指定结点的N-S图删除
第一个结点
删除中间结点或尾结点
删除结点工
作分两步:查找结点删除结点学生姓名当姓名不同并且不是尾结点循环7.2.4链表2023/1/1443#include<stdio.h>
#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指针向表尾移动*/查找结点
2023/1/1444
if(strcmp(x,p->name)==0)
{if(p==head)head=p->next;/*删除头结点*/
else
q->next=p->next;/*删除中间或尾结点*/
free(p);/*释放被删除的结点*/
}
elseprintf("Notfound.");/*未找到指定的结点*/
h=head;returnh;}7.2.4链表2023/1/1445将一个新结点插入到链表中,首先要寻找插入的位置。如果要求在第i个结点前插入,可设置三个工作指针p0、p和q,p0是指向待插入结点的指针。利用p和q指针查找第i个结点,找到后再将新结点链接到链表上。
6.在单向链表中插入结点headNULL第i个结点ppqqp0p新的第i个结点7.2.4链表2023/1/1446headp(a)在表头插入结点(head=p0;p0->next=p)p07.2.4链表2023/1/1447head(b)在表中间插入结点(q->next=p0;p0->next=p)pqp07.2.4链表2023/1/1448headpp(c)在表尾追加结点(p->next=p0;p0->next=NULL)
q
p07.2.4链表pq
2023/1/1449【例7-14】在学生电话簿链表中插入一个学生的信息。要求将新的信息插入在指定学生信息之前,如果未找到指定学生,则追加在链表尾部。
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图7-11在链表指定位置前插入结点的N-S图当姓名不同并且不是尾结点循环空表时
插入
结点在表尾
追加结点
插入结点工
作分两步:查找插
入位置连接
新结点在表头
插入结点
在表中间
插入结点
7.2.4链表2023/1/1450#include<stdio.h>#include<stdlib.h>#include<string.h>#defineNEW(structnode*)malloc(sizeof(structnode))structnode{charname[20],tel[9];structnode*next;};7.2.4链表2023/1/1451structnode*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;}
查找插入点
7.2.4链表2023/1/1452
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;}7.2.4链表2023/1/1453【例7-15】学生电话簿链表管理程序。编制此程序可利用例
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 卡丁车安全管理办法
- 曲靖流浪犬管理办法
- 学院组织员管理办法
- 机加工星级管理办法
- 学员服务与管理办法
- 商务拓展部管理办法
- 机电电钳工管理办法
- 医疗投诉管理办法法
- 水库小船舶管理办法
- 沉没物打捞管理办法
- 20道中国人民财产保险股份有限公司保险理赔员岗位常见面试问题含HR常问问题考察点及参考回答
- 肥料登记申请书表格
- 2023电动汽车快换电池箱通信协议
- 房山区G107大修工程施工组织方案
- 《人才池 人才培育的靶心战略》读书笔记思维导图
- JJG 10-2005专用玻璃量器
- GB/T 5907.4-2015消防词汇第4部分:火灾调查
- BB/T 0019-2000包装容器方罐与扁圆罐
- 超市生鲜蔬菜培训资料
- 2020浙江高考英语一轮复习课件:专题十二-文章
- 新编物理基础学(上下册)课后习题详细答案 王少杰 顾社主编
评论
0/150
提交评论