第12章结构体和共用体.ppt

上传人:sccc 文档编号:4872814 上传时间:2023-05-20 格式:PPT 页数:118 大小:6.25MB
返回 下载 相关 举报
第12章结构体和共用体.ppt_第1页
第1页 / 共118页
第12章结构体和共用体.ppt_第2页
第2页 / 共118页
第12章结构体和共用体.ppt_第3页
第3页 / 共118页
第12章结构体和共用体.ppt_第4页
第4页 / 共118页
第12章结构体和共用体.ppt_第5页
第5页 / 共118页
点击查看更多>>
资源描述

《第12章结构体和共用体.ppt》由会员分享,可在线阅读,更多相关《第12章结构体和共用体.ppt(118页珍藏版)》请在三一办公上搜索。

1、二进制数类型本不存在内存里存的内容,你认为它是什么,它就是什么在早期的机器指令及汇编语言中,数据对象均用二进制数表示,没有类型的概念一般的CPU只支持两种类型整数、浮点数,12.1从基本数据类型到抽象数据类型,在高级语言引入了基本数据类型整型、浮点型、字符型等不同语言会定义不同的基本类型基本数据类型并不能方便地解决所有问题有些语言(如PL/1)中试图规定较多的类型,如数组、树、栈等,但实践证明不是个好办法,12.1从基本数据类型到抽象数据类型,用户自己构造数据类型-复合数据类型由基本数据类型迭代派生而来,表示复杂的数据对象典型的代表就是“结构体”抽象数据类型(Abstract Data Typ

2、e,简称ADT)在复合数据类型基础上增加了对数据的操作抽象数据类型进而进化为“类(Class)”这是一个跨时代的进步Class是Object-Oriented的一个重要概念,12.1从基本数据类型到抽象数据类型,12.2.1为什么要定义结构体类型,在程序里表示一个人(姓名、年龄、性别),怎么表示?想表示多个人呢?如何用计算机程序实现下述表格的管理?,数组的解决方法,数组的解决方法,数据的内存管理方式,数组的解决方法,分配内存不集中,寻址效率不高 对数组赋初值时,易发生错位 结构显得零散,不易管理,希望的内存分配图,结构体类型的声明,声明了一个结构体类型,构成结构体的变量称为结构体的成员(Str

3、ucture Member),结构体的名字称为结构体标签(Structure Tag),结构体类型的声明,结构体模板(Structure Template),Dont forget the semicolon!,形成一个类型声明的样板用于生成结构体变量但并未声明结构体变量因而编译器不为其分配内存,(1)先定义结构体类型,再定义变量名,(2)在定义类型的同时定义变量,(3)直接定义结构体变量(不指定结构体标签),12.2.2结构体变量的定义,12.2.3用typedef定义数据类型,struct student stu1,stu2;/*It works*/student stu1,stu2;/*

4、Can this work?*/struct stu1,stu2;/*Can this work?*/STUDENT stu1,stu2;/*It works!*/,关键字typedef为一种已存在的类型定义一个别名,并未定义新类型,STUDENT与struct student类型是同义词,等价于,12.2.4结构体变量的初始化,等价于,注意!,嵌套的结构体(Nested Structure)就是在一个结构体内包含了另一个结构体作为其成员,12.2.5嵌套的结构体,结构体定义可以嵌套,访问结构体变量的成员必须使用成员选择运算符(也称圆点运算符),12.2.6结构体变量的引用,当出现结构体嵌套时

5、,必须以级联方式访问结构体成员,【例12.1】演示结构体变量的赋值和引用方法,12.2.6结构体变量的引用,按结构体的成员顺序逐一对相应成员进行赋值,格式符%02d中2d前面的前导符0表示输出数据时,若左边有多余位,则补0,【例12.1】若要从键盘输入结构体变量stu1的内容,那么程序如何修改?,两个地址有何不同?,【例12.1】若要从键盘输入结构体变量stu1的内容,那么程序如何修改?,结构体成员的地址与该成员在结构体中所处的位置及其所占内存的字节数相关,结构体变量的地址&stu2是该变量所占内存空间的首地址,12.2.7结构体所占内存的字节数,struct 类型用内存字节数=?是所有成员变

6、量的内存总和吗?,printf(%dn,sizeof(struct sample);,用运算符sizeof获得结构体大小sizeof(变量或表达式)sizeof(类型),12,Why?,printf(%dn,sizeof(SAMPLE);,【例12.2】,12.2.7结构体所占内存的字节数,事实上,所有数据类型在内存中都是从偶数地址开始存放的且结构所占的实际空间一般是按照机器字长对齐的不同的编译器、平台,对齐方式会有变化结构体变量的成员的存储对齐规则是与机器相关的具有特定数据类型的数据项大小也是与机器相关的所以一个结构体在内存中的存储格式也是与机器相关的,非所有成员变量的内存总和,12个字节,

7、12.3结构体数组的定义和初始化,12.3结构体数组的定义和初始化,建立了数据库中的多条记录,每条对应一个学生信息,【例12.3】利用结构体数组计算每个学生的平均分,教学进程,【例】有N个学生的信息(包括学号,姓名,成绩),要求:按照成绩的高低顺序存储并输出各学生的信息。#include#includevoid main()struct student int num;char name20;int score;s6=1,aaa,59,2,bbb,78,3,ccc,85,4,ddd,64,5,eee,98,6,fff,83;/struct student temp_stu;int i,j,ma

8、x,temp;char temp_name20;,for(i=0;i6;i+)max=i;for(j=i+1;j=5;j+)if(smax.scoresj.score)max=j;/*temp_stu=si;si=smax;smax=temp_stu;*/temp=si.num;si.num=smax.num;smax.num=temp;strcpy(temp_name,si.name);strcpy(si.name,smax.name);strcpy(smax.name,temp_name);temp=si.score;si.score=smax.score;smax.score=temp;

9、,printf(num name scoren);for(i=0;i6;i+)printf(%d%s%dn,si.num,si.name,si.score);,12.4结构体指针的定义和初始化,pt,stu1,STUDENT stu1;STUDENT*pt;pt=,如何定义指向结构体变量的指针?,STUDENT*pt=,等价于,12.4结构体指针的定义和初始化,如何访问结构体指针变量所指向的结构体成员呢?,STUDENT stu1;STUDENT*pt=,pt,stu1,通过stu1和成员选择运算符访问结构体成员stu1.studentID=1;通过pt和指向运算符访问结构体成员(*pt).s

10、tudentID=1;pt-studentID=1;,12.4结构体指针的定义和初始化,pt,stu1,当结构体嵌套时,如何访问结构体指针变量所指向的结构体成员?,stu1.birthday.year=1999;(*pt).birthday.year=1999;pt-birthday.year=1999;,STUDENT stu1;STUDENT*pt=,12.4结构体指针的定义和初始化,STUDENT stu30;STUDENT*pt;pt=stu;,如何定义指向结构体数组的指针?,STUDENT*pt=stu;,等价于,STUDENT*pt=,等价于,pt,stu30,使用pt+,使pt指

11、向stu1pt-studentID等价于 stu1.studentID,pt,12.4结构体指针的定义和初始化,STUDENT stu30;STUDENT*pt=stu;,如何访问结构体数组指针指向的结构体成员?,stu30,教学进程,#include struct student int num;char name20;char sex;int age;,【例】有3个学生的信息,放在结构体数组中,要求用指针变量输出 全部学生的信息。,struct student stu3=10101,Li Lin,M,18,10102,Zhang Fun,M,19,10104,Wang Min,F,20;v

12、oid main()struct student*p;printf(No.Name sex agen);for(p=stu;pnum,p-name,p-sex,p-age);,图9-8,教学进程,注意:如果的初值为stu,即指向第一个元素,则加后p就指向下一个元素。(+p)-num先使自加,然后得到它指向的元素中 的num成员值(即10102)。(p+)-num先得到-num的值(即10101),然后使 自加,指向stu1。,(2)p=&st1.num;是错误的,指向结构体数组的指针,图9-8,12.5向函数传递结构体,向函数传递结构体的单个成员复制单个成员的内容函数内对结构内容的修改不影响原

13、结构向函数传递结构体的完整结构向函数传递结构体的首地址,struct date int year;int month;int day;void func(struct date p)p.year=2000;p.month=5;p.day=22;,Before function call:1999/04/23,After function call:1999/04/23,结构体变量作函数参数,【例12.4】,struct date int year;int month;int day;void func(struct date*p)p-year=2000;p-month=5;p-day=22;,

14、Before function call:1999/04/23,After function call:2000/05/22,结构体指针作函数参数,指针作函数形参实参必须为地址值,【例12.5】,struct date int year;int month;int day;struct date func(struct date p)p.year=2000;p.month=5;p.day=22;return p;,Before function call:1999/04/23,After function call:2000/05/22,结构体变量作函数返回值,【例12.6】,12.5向函数传

15、递结构体,向函数传递结构体的完整结构复制整个结构体成员的内容,多个值函数内对结构内容的修改不影响原结构内容传递更直观,但开销大向函数传递结构体的首地址用结构体数组/结构体指针作函数参数仅复制结构体的首地址,一个值修改结构体指针所指向的结构体的内容指针传递效率高,教学进程,【例】有N个结构体变量stu,内含学号、姓名和3门课程的成绩,要求输出平均成绩最高的学生的信息。,#include#define N 3struct student/要把结构体类型定义为全局的 int num;char name20;float score3;float aver;void main()void input(s

16、truct student stu);struct student max(struct student stu);void print(struct student stu);struct student stuN,*p=stu;input(p);print(max(p);,教学进程,void input(struct student stu)int i;for(i=0;inum,stu-name,12.5向函数传递结构体,【例12.7】修改例12.3程序,用结构体数组作函数参数编程并输出计算学生的平均分,12.5向函数传递结构体,【例12.7】修改例12.3程序,用结构体数组作函数参数编程

17、并输出计算学生的平均分,12.5向函数传递结构体,【例12.7】修改例12.3程序,用结构体数组作函数参数编程并输出计算学生的平均分,12.5向函数传递结构体,【例12.7】修改例12.3程序,用结构体数组作函数参数编程并输出计算学生的平均分,下面的结构是什么意思?struct temp int data;struct temp pt;CB下的错误提示:field pt has incomplete typeVC下的错误提示:pt uses undefined struct temp下面的结构是什么意思呢?struct temp int data;struct temp*pt;,可包含指向本结

18、构体类型的指针变量,问题的提出,12.6动态数据结构单向链表,struct Link int data;struct Link*next;,链表(Linked Table):线性表的链式存储结构特点:用一组任意的存储单元存储线性表的数据;存储单元可以是连续的,也可是不连续的,链表的定义,链表(Linked table):线性表的链式存储结构为表示每个元素与后继元素的逻辑关系,除存储元素本身信息外,还要存储其直接后继信息,两部分信息组成一个节点,struct Link int data;struct Link*next;,数据域:存储数据元素信息,指针域:存储直接后继的节点信息,链表的定义,链表

19、(Linked Table):线性表的链式存储结构为表示每个元素与后继元素的逻辑关系,除存储元素本身信息外,还要存储其直接后继信息,struct Link int data;struct Link*next;,n个节点链接成一个链表(因为只包含一个指针域,故又称线性链表或单向链表),链表是一种常见的重要的数据结构,是动态地进行存储分配的一种结构。链表的组成:头指针:存放一个地址,该地址指向一个元素 结点:用户需要的实际数据和链接节点的指针,结点的动态分配,用结构体建立链表:struct student int num;float score;struct student*next;;其中成员n

20、um和score用来存放结点中的有用数据(用户需要用到的数据),next是指针类型的成员,它指向struct student类型数据(这就是next所在的结构体类型),教学进程,教学进程,#include struct student long num;float score;struct student*next;void main()struct student a,b,c,*head,*p;a.num=99101;a.score=89.5;b.num=99103;b.score=90;c.num=99107;c.score=85;,1.建立简单的静态链表,【例】建立上图所示的简链表,它由

21、各学生数据的节点组成。输出各节点中的数据。,head=,教学进程,教学进程,所谓建立动态链表是指在程序执行过程中从无到有地建立起一个链表,即一个一个地开辟结点和输入各结点数据,并建立起前后相链的关系。,2.建立动态链表,教学进程,教学进程,void*malloc(unsigned int size);在内存的动态存储区分配一个长度为size的连续空间。此函数返回值是一个分配域起始地址(类型void)。如果此函数未能成功执行,则返回空指针(NULL),void*calloc(unsigned n,unsigned size);在内存动态存储区分配n个长度为size的连续空间。函数返回一个指向分配

22、域起始位置的指针。如果分配不成功,则返回NULL 用calloc函数可以为一维数组开辟动态存储空间,n为数组元素个数,每个元素长度为size。,void free(void*p)释放由p指向的动态存储区,使这部分内存区能被其他变量使用。P是最近一次调用calloc或malloc函数时返回的值。free函数无返回值。,在链表中查找指定元素,教学进程,建立链表的函数如下:#include#include#define LEN sizeof(struct student)/令LEN代表struct student类型数据的长度 struct student int num;float score;s

23、truct student*next;,【例】写一函数建立一个有2名学生学号和成绩的单向动态链表。,教学进程,void main()struct student*head,*p;head=p=(struct student*)malloc(LEN);scanf(“%d,%f”,例:写一个函数建立/输出一个有n名学生数据的单向动态链表,对链表的综合操作(包括对结点的插入删除),链表的建立,向链表中添加一个新节点,空指针NULL表示链表结尾,链表的头指针:访问链表的关键,链表操作总结,链表的建立,若原链表为空表(head=NULL),则将新建节点p置为头节点,(1)head=p,(2)pr=p,(

24、3)pr-next=NULL,链表的建立,若原链表为非空,则将新建节点p添加到表尾,(1)pr-next=p,(2)pr=p,(3)pr-next=NULL,next,根据上述思想编写向链表添加节点数据的程序如下:#include#include struct link*AppendNode(struct link*head);void DisplyNode(struct link*head);void DeleteMemory(struct link*head);struct linkint data;struct link*next;,int main()int i=0;char c;st

25、ruct link*head=NULL;/*链表头指针*/printf(Do you want to append a new node(Y/N)?);scanf(%c,/*函数功能:新建一个节点并添加到链表末尾,返回添加节点后的链表的头指针*/struct link*AppendNode(struct link*head)struct link*p=NULL,*pr=head;int data;p=(struct link*)malloc(sizeof(struct link);/*让p指向新建节点*/if(p=NULL)/*若为新建节点申请内存失败,则退出程序*/printf(No eno

26、ugh memory to allocate!n);exit(0);,if(head=NULL)/*若原链表为空表*/head=p;/*将新建节点置为头节点*/else/*若原链表为非空,则将新建节点添加到表尾*/while(pr-next!=NULL)/*若未到表尾,则移动pr直到pr指向表尾*/pr=pr-next;/*让pr指向下一个节点*/pr-next=p;/*让末节点的指针域指向新建节点*/printf(Input node data:);scanf(%d,/*返回添加节点后的链表的头指针*/,/*函数的功能:显示链表中所有节点的节点号和该节点中数据项内容*/void Disply

27、Node(struct link*head)struct link*p=head;int j=1;while(p!=NULL)/*若不是表尾,则循环打印节点的值*/printf(%5d%10dn,j,p-data);/*打印第j个节点的数据*/p=p-next;/*让p指向下一个节点*/j+;,/*函数功能:释放head指向的链表中所有节点占用的内存*/void DeleteMemory(struct link*head)struct link*p=head,*pr=NULL;while(p!=NULL)/*若不是表尾,则释放节点占用的内存*/pr=p;/*在pr中保存当前节点的指针*/p=p

28、-next;/*让p指向下一个节点*/free(pr);/*释放pr指向的当前节点占用的内存*/,链表的删除操作,若原链表为空表,则退出程序 若待删除节点p是头节点,则将head指向当前节点的下一个节点即可删除当前节点,(1)head=p-next,head,(2)free(p),链表的删除操作,若待删除节点不是头节点,则将前一节点的指针域指向当前节点的下一节点即可删除当前节点,(1)pr-next=p-next,若已搜索到表尾(p-next=NULL)仍未找到待删除节点,则显示“未找到”,(2)free(p),#include#include struct link*AppendNode(s

29、truct link*head);void DisplyNode(struct link*head);void DeleteMemory(struct link*head);struct link*DeleteNode(struct link*head,int nodeData);struct linkint data;struct link*next;,int main()int i=0;char c;struct link*head=NULL;/*链表头指针*/printf(Do you want to append a new node(Y/N)?);scanf(%c,/*函数功能:新建

30、一个节点并添加到链表末尾,返回添加节点后的链表的头指针*/struct link*AppendNode(struct link*head)struct link*p=NULL;struct link*pr=head;intdata;p=(struct link*)malloc(sizeof(struct link);/*让p指向新建节点*/if(p=NULL)printf(No enough memory to allocate!n);exit(0);,if(head=NULL)/*若原链表为空表,则将新建节点置为首节点*/head=p;else/*若原链表为非空,则将新建节点添加到表尾*/w

31、hile(pr-next!=NULL)/*若未到表尾,则移动pr直到pr指向表尾*/pr=pr-next;/*让pr指向下一个节点*/pr-next=p;/*将新建节点添加到链表的末尾*/pr=p;/*让pr指向新建节点*/printf(Input node data:);scanf(%d,/*返回添加节点后的链表的头节点指针*/,/*函数的功能:显示链表中所有节点的节点号和该节点中数据项内容*/void DisplyNode(struct link*head)struct link*p=head;intj=1;while(p!=NULL)/*若不是表尾,则循环打印*/printf(%5d%1

32、0dn,j,p-data);/*打印第j个节点的数据*/p=p-next;/*让p指向下一个节点*/j+;,/*函数功能:释放head指向的链表中所有节点占用的内存*/void DeleteMemory(struct link*head)struct link*p=head,*pr=NULL;while(p!=NULL)/*若不是表尾,则释放节点占用的内存*/pr=p;/*在pr中保存当前节点的指针*/p=p-next;/*让p指向下一个节点*/free(pr);/*释放pr指向的当前节点占用的内存*/,/*函数功能:从head指向的链表中删除一个节点,返回删除节点后的链表的头指针*/stru

33、ct link*DeleteNode(struct link*head,int nodeData)struct link*p=head,*pr=head;if(head=NULL)/*若链表为空表,则退出程序*/printf(Linked Table is empty!n);return(head);while(nodeData!=p-data,if(nodeData=p-data)/*若找到节点nodeData,则删除该节点*/if(p=head)/*若待删除节点为首节点,则让head指向第2个节点*/head=p-next;else/*若待删除节点不是首节点,则将前一节点的指针指向当前节点

34、的下一节点*/pr-next=p-next;free(p);/*释放为已删除节点分配的内存*/else/*没有找到待删除节点*/printf(This Node has not been found!n);return head;/*返回删除节点后的链表的头节点指针*/,链表的插入操作,若原链表为空表,则将新节点p作为头节点,让head指向新节点p,(1)head=p,p=(struct link*)malloc(sizeof(struct link);p-next=NULL;p-data=nodeData;,链表的插入操作,若原链表为非空,则按节点值(假设已按升序排序)的大小确定插入新节点的

35、位置若在头节点前插入新节点,则将新节点的指针域指向原链表的头节点,且让head指向新节点,(2)head=p,(1)p-next=head,链表的插入操作,若在链表中间插入新节点,则将新节点的指针域指向下一节点且让前一节点的指针域指向新节点,(2)pr-next=p,(1)p-next=pr-next,链表的插入操作,若在表尾插入新节点,则末节点指针域指向新节点,(1)pr-next=p,next,链表的输出,遍历链表的所有节点,#include#include struct link*AppendNode(struct link*head);void DisplyNode(struct li

36、nk*head);void DeleteMemory(struct link*head);struct link*InsertNode(struct link*head,int nodeData);struct linkint data;struct link*next;,int main()int i=0;char c;struct link*head=NULL;/*链表头指针*/printf(Do you want to append a new node(Y/N)?);scanf(%c,/*函数功能:新建一个节点并添加到链表末尾,返回添加节点后的链表的头指针*/struct link*A

37、ppendNode(struct link*head)struct link*p=NULL;struct link*pr=head;intdata;p=(struct link*)malloc(sizeof(struct link);/*让p指向新建节点*/if(p=NULL)printf(No enough memory to allocate!n);exit(0);,if(head=NULL)/*若原链表为空表,则将新建节点置为首节点*/head=p;else/*若原链表为非空,则将新建节点添加到表尾*/while(pr-next!=NULL)/*若未到表尾,则移动pr直到pr指向表尾*/

38、pr=pr-next;/*让pr指向下一个节点*/pr-next=p;/*将新建节点添加到链表的末尾*/pr=p;/*让pr指向新建节点*/printf(Input node data:);scanf(%d,/*返回添加节点后的链表的头节点指针*/,/*函数的功能:显示链表中所有节点的节点号和该节点中数据项内容*/void DisplyNode(struct link*head)struct link*p=head;intj=1;while(p!=NULL)/*若不是表尾,则循环打印*/printf(%5d%10dn,j,p-data);/*打印第j个节点的数据*/p=p-next;/*让p指

39、向下一个节点*/j+;,/*函数功能:释放head指向的链表中所有节点占用的内存*/void DeleteMemory(struct link*head)struct link*p=head,*pr=NULL;while(p!=NULL)/*若不是表尾,则释放节点占用的内存*/pr=p;/*在pr中保存当前节点的指针*/p=p-next;/*让p指向下一个节点*/free(pr);/*释放pr指向的当前节点占用的内存*/,/*函数功能:在已按升序排序的链表中插入一个节点,返回插入节点后的链表头指针*/struct link*InsertNode(struct link*head,int nod

40、eData)struct link*pr=head,*p=head,*temp=NULL;p=(struct link*)malloc(sizeof(struct link);/*让p指向待插入节点*/if(p=NULL)/*若为新建节点申请内存失败,则退出程序*/printf(No enough memory!n);exit(0);p-next=NULL;/*为待插入节点的指针域赋值为空指针*/p-data=nodeData;/*为待插入节点数据域赋值为nodeData*/if(head=NULL)/*若原链表为空表*/head=p;/*待插入节点作为头节点*/,else/*若未找到待插入节

41、点的位置且未到表尾,则继续找*/while(pr-data next!=NULL)temp=pr;/*在temp中保存当前节点的指针*/pr=pr-next;/*pr指向当前节点的下一节点*/if(pr-data=nodeData)if(pr=head)/*若在头节点前插入新节点*/p-next=head;/*将新节点的指针域指向原链表的头节点*/head=p;/*让head指向新节点*/else/*若在链表中间插入新节点*/pr=temp;p-next=pr-next;/*将新节点的指针域指向下一节点*/pr-next=p;/*让前一节点的指针域指向新节点*/else/*若在表尾插入新节点*

42、/pr-next=p;/*让末节点的指针域指向新节点*/return head;/*返回插入新节点后的链表头指针head的值*/,用户自定义的数据类型,结构体(Struct)把关系紧密且逻辑相关的多种不同类型的变量,组织到统一的名字之下占用相邻的一段内存单元共用体,也称联合(Union)把情形互斥但逻辑相关的多种不同类型的变量,组织到统一的名字之下占用同一段内存单元,每一时刻只有一个数据起作用,12.7共用体和枚举类型,12.7.1共用体,struct sample short i;char ch;float f;,union sample short i;char ch;float f;,p

43、rintf(%dn,sizeof(struct sample);,8个字节,i,ch,f,4个字节,printf(%dn,sizeof(union sample);,【例12.8】,12.7.1共用体,sizeof(union number)取决于占空间最多的那个成员变量,同一内存单元在每一瞬时只能存放其中一种类型的成员起作用的成员是最后一次存放的成员,不能作为函数参数不能进行比较操作,只能对第一个成员初始化,f,4个字节,12.7.1共用体,12.7.1共用体,12.7.2枚举数据类型,枚举(Enumeration)数据类型描述的是一组整型值的集合用于当某些量仅由有限个数据值组成时 enum

44、 weeks SUN,MON,TUE,WED,THU,FRI,SAT;enum weeks today;enum response no,yes,none;enum response answer;today=TUE;answer=yes;enum response no=-1,yes=1,none=0;,其值为2,其值为1,12.8.1 用typedef命名已有类型,可以用typedef声明新的类型名来代替已有的类型名 例:typedef int COUNT;typedef real REAL;这样,以下两行等价:int i,j;float a,b;COUNT i,j;REAL a,b;可以

45、声明结构体类型:typedef struct int month;int day;int year;DATE;,DATE birthday;(不要写成struct DATE birthday;)DATE*p;(p为指向此结构体类型数据的指针),12.8 补充,还可以进一步:(1)typedef int NUM100;(声明NUM为整型数组类型)NUM n;(定义n为整型数组变量)(2)typedef char*STRING;(声明STRING为字符指针类型)STRING p,s10;(定义p为字符指针变量,s为指针数组),归纳起来,声明一个新的类型名的方法是:(1)先按定义变量的方法写出定义体

46、(如:int i;)(2)将变量名换成新类型名(如:将i换成COUNT)(3)在最前面加上typedef(例如:typedef int COUNT)(4)然后可以用新类型名去定义变量再以定义上述的数组类型为例来说明:(1)先按定义数组变量的形式书写:int n100;(2)将变量名 n 换成自己指定的类型名:int NUM100;(3)在最前面加上typedef,得到typedef int NUM100;(4)用来定义变量:NUM n;,12.8.2位段(补充)C语言允许在一个结构体中以位为单位来指定其成员所占内存长度,这种以位为单位的成员称为“位段”或“位域”(bit field)。利用位段

47、能够用较少的位数存储数据。struct packed_data unsigned a:2;unsigned b:6;unsigned c:4;unsigned d:4;int i;data;,也可以使各个位段不恰好占满一个字节 struct packed_data unsigned a:2;unsigned b:3;unsigned c:4;int i;data;此时,abc共占9位,不到2个字节,其后7位空间闲置不用,i从另一字节开头起存放注意:存储单元中位段的空间分配方向因机器而异,但是用户不必过问细节,对位段中的数据引用方法 data.a=2;data.b=7;data.c=9;注意:位

48、段允许的最大值范围,说明:(1)位段成员的类型必须指定为unsigned 或int类型(2)若某一位段要从另一个字开始存放,可以用以下形式定义:unsigned a:1;一个存储单元 unsigned b:2;unsigned:0;unsigned c:3;(另一个存储单元)上述存储单元可能是一个字节,也可能是2个字节,视不同的编译系统而异(3)一个位段必须存储在同一存储单元中,不能跨两个单元,(4)可以定义无名位段 unsigned a:1;unsigned:2;(这两位空间不用)unsigned b:3;unsigned c:4;(5)位段的长度不能大于存储单元的长度,也不能定义位 段数组

49、。(6)位段可以用整型格式符输出 printf(“%d,%d,%d”,data.a,data.b,data.c);(7)位段可以在数值表达式中引用,它会被系统自动转换 成整型数:data.a+5/data.b,本章小结,1.C语言中有两类数据:一类是系统已经定义好的标准数据类型,也称基类型,如:int、long、char、float、double等,可以直接使用;另一类是用户根据需要自己设计的数据类型,必须先声明,然后才能使用,如:结构体、共用体等。2.结构体由若干个数据成员组成的,他们可以是不同类型的。3.同类型的结构体变量可以相互赋值,但不能用结构体变量名对结构体进行整体输入输出。可以对结构体变量的成员进行赋值、比较、输入输出等操作。4.引用结构体成员的方法有:结构体变量.成员名“.”成员运算符(*指针变量).成员名 指针变量是指向结构体变量的 p-成员运算符 p是指向结构体变量的指针变量,教学进程,5.结构体变量的指针就是结构体变量的起始地址。6.把结构体变量和指向结构体变量的指针结合起来,可以建立动态数据结构。了解链表的建立操作的思路。7.共用体与结构体不同,其成员共享同一段存储空间,因此各成员的值不会同时存在,在某一瞬间,只有最后一次被赋值的成员是有意义的。8.枚举类型是把可能的值全部一一列出来,枚举变量的值只能是其中的一个。,教学进程,本章小结,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 建筑/施工/环境 > 农业报告


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号