第12章结构体和共用体

上传人:汽*** 文档编号:579145344 上传时间:2024-08-26 格式:PPT 页数:118 大小:6.25MB
返回 下载 相关 举报
第12章结构体和共用体_第1页
第1页 / 共118页
第12章结构体和共用体_第2页
第2页 / 共118页
第12章结构体和共用体_第3页
第3页 / 共118页
第12章结构体和共用体_第4页
第4页 / 共118页
第12章结构体和共用体_第5页
第5页 / 共118页
点击查看更多>>
资源描述

《第12章结构体和共用体》由会员分享,可在线阅读,更多相关《第12章结构体和共用体(118页珍藏版)》请在金锄头文库上搜索。

1、结构体和共用体结构体和共用体第第 1 章章12.1 12.1 构造数据类型构造数据类型构造数据类型构造数据类型12.2 12.2 结构体类型和结构体变量结构体类型和结构体变量结构体类型和结构体变量结构体类型和结构体变量12.3 12.3 结构体数组结构体数组结构体数组结构体数组12.4 12.4 结构体指针结构体指针结构体指针结构体指针12.5 12.5 用结构体变量和结构体变量的指针用结构体变量和结构体变量的指针用结构体变量和结构体变量的指针用结构体变量和结构体变量的指针 作函数参数作函数参数作函数参数作函数参数12.6 12.6 用指针处理链表用指针处理链表用指针处理链表用指针处理链表12

2、.7 12.7 共用体类型和共用体类型和共用体类型和共用体类型和枚枚举类型举类型举类型举类型 12.8 12.8 补充补充补充补充 二进制数类型本不存在内存里存的内容,你认为它是什么,它就内存里存的内容,你认为它是什么,它就是什么是什么在早期的机器指令及汇编语言中,数据对在早期的机器指令及汇编语言中,数据对象均用二进制数表示,没有类型的概念象均用二进制数表示,没有类型的概念一般的CPU只支持两种类型整数、浮点数整数、浮点数12.112.1从基本数据类型到抽象数据类型从基本数据类型到抽象数据类型从基本数据类型到抽象数据类型从基本数据类型到抽象数据类型在高级语言引入了基本数据类型整型、浮点型、字符

3、型等整型、浮点型、字符型等不同语言会定义不同的基本类型不同语言会定义不同的基本类型基本数据类型并不能方便地解决所有问题基本数据类型并不能方便地解决所有问题 有些语言(如有些语言(如PL/1PL/1)中试图规定较多的类型,如)中试图规定较多的类型,如数组、树、栈等,但实践证明不是个好办法数组、树、栈等,但实践证明不是个好办法12.112.1从基本数据类型到抽象数据类型从基本数据类型到抽象数据类型从基本数据类型到抽象数据类型从基本数据类型到抽象数据类型 用户自己构造数据类型用户自己构造数据类型用户自己构造数据类型用户自己构造数据类型- -复合数据类型复合数据类型复合数据类型复合数据类型由基本数据类

4、型迭代派生而来,表示复杂的数据对象由基本数据类型迭代派生而来,表示复杂的数据对象由基本数据类型迭代派生而来,表示复杂的数据对象由基本数据类型迭代派生而来,表示复杂的数据对象 典型的代表就是典型的代表就是典型的代表就是典型的代表就是“结构体结构体结构体结构体” 抽象数据类型(抽象数据类型(抽象数据类型(抽象数据类型(Abstract Data TypeAbstract Data Type,简称,简称,简称,简称ADTADT)在复合数据类型基础上增加了对数据的操作在复合数据类型基础上增加了对数据的操作在复合数据类型基础上增加了对数据的操作在复合数据类型基础上增加了对数据的操作 抽象数据类型进而进化

5、为抽象数据类型进而进化为抽象数据类型进而进化为抽象数据类型进而进化为“ “类类类类(Class)”(Class)”这是一个跨时代的进步这是一个跨时代的进步这是一个跨时代的进步这是一个跨时代的进步ClassClass是是是是Object-OrientedObject-Oriented的一个重要概念的一个重要概念的一个重要概念的一个重要概念12.112.1从基本数据类型到抽象数据类型从基本数据类型到抽象数据类型从基本数据类型到抽象数据类型从基本数据类型到抽象数据类型12.2.1为什么要定义结构体类型在程序里表示一个人(姓名、年龄、性别在程序里表示一个人(姓名、年龄、性别),),怎么表示?怎么表示?

6、想表示多个人呢?想表示多个人呢?如何用计算机程序实现下述表格的管理?如何用计算机程序实现下述表格的管理? 数组的解决方法数组的解决方法数据的内存管理方式 数组的解决方法分配内存不集中,寻址效率不高分配内存不集中,寻址效率不高 对数组赋初值时,易发生错位对数组赋初值时,易发生错位 结构显得零散,不易管理结构显得零散,不易管理希望的内存分配图 结构体类型的声明声明了一个结构体类型声明了一个结构体类型构成结构体的变量构成结构体的变量称为结构体的成员称为结构体的成员(Structure Member)结构体的名字结构体的名字称为结构体标称为结构体标签签(Structure Tag)结构体类型的声明结构

7、体模板结构体模板(Structure Template)Dont forget the semicolon!形成一个类型声明的样板形成一个类型声明的样板形成一个类型声明的样板形成一个类型声明的样板用于生成结构体变量用于生成结构体变量用于生成结构体变量用于生成结构体变量但并未声明结构体变量但并未声明结构体变量但并未声明结构体变量但并未声明结构体变量因而编译器不为其分配内存因而编译器不为其分配内存因而编译器不为其分配内存因而编译器不为其分配内存 (1 1)先定义结构体类型,再定义变量名)先定义结构体类型,再定义变量名(2 2)在定义类型的同时定义变量)在定义类型的同时定义变量(3 3)直接定义结构

8、体变量(不指定结构体标签)直接定义结构体变量(不指定结构体标签)12.2.212.2.2结构体结构体结构体结构体变量变量变量变量的定义的定义的定义的定义12.2.3用typedef定义数据类型structstruct studentstudent stu1, stu2;stu1, stu2;/*It works*/*It works*/studentstudent stu1, stu2; stu1, stu2; /*Can this work?*/*Can this work?*/structstruct stu1, stu2; stu1, stu2; /*Can this work?*/*C

9、an this work?*/STUDENTSTUDENT stu1, stu2;stu1, stu2; /*It works!*/*It works!*/关键字关键字typedef为一种为一种已存在的已存在的类型定义一个类型定义一个别名别名,并未定义新类型,并未定义新类型STUDENT与与struct student类型是类型是同义词同义词等价于等价于12.2.412.2.4结构体变量的初始化结构体变量的初始化结构体变量的初始化结构体变量的初始化等价于等价于注意!注意!嵌套的结构体(嵌套的结构体(Nested StructureNested Structure)就是在一个)就是在一个结构体内

10、包含了另一个结构体作为其成员结构体内包含了另一个结构体作为其成员 12.2.5嵌套的结构体结构体定义结构体定义可以嵌套可以嵌套访问结构体变量的成员必须使用成员选择运算符(也称圆点运算符) 12.2.6结构体变量的引用 当出现结构体嵌套时,必须当出现结构体嵌套时,必须当出现结构体嵌套时,必须当出现结构体嵌套时,必须以级联方式访问结构体成员以级联方式访问结构体成员以级联方式访问结构体成员以级联方式访问结构体成员【例12.1】演示结构体变量的赋值和引用方法12.2.6结构体变量的引用按结构体的成员顺序逐按结构体的成员顺序逐一对相应成员进行赋值一对相应成员进行赋值格式符格式符%02d中中2d前面的前导

11、符前面的前导符0表示输表示输出数据时,若左边有多余位,则补出数据时,若左边有多余位,则补0 【例例12.112.1】若要从键若要从键盘输入结盘输入结构体变量构体变量stu1stu1的内的内容,那么容,那么程序如何程序如何修改?修改?两个地址有何不同?两个地址有何不同? 【例例12.112.1】若要从键若要从键盘输入结盘输入结构体变量构体变量stu1stu1的内的内容,那么容,那么程序如何程序如何修改?修改?结构体成员的地址与结构体成员的地址与该成员在结构体中所该成员在结构体中所处的位置及其所占内处的位置及其所占内存的字节数相关存的字节数相关结构体变量的地址结构体变量的地址&stu2是该变量所占

12、是该变量所占内存空间的首地址内存空间的首地址12.2.7结构体所占内存的字节数struct 类型用内存字节数 = ?是所有成员变量的内存总和吗?printf(%dn, sizeof(printf(%dn, sizeof(structstruct samplesample);); 用运算符用运算符用运算符用运算符sizeofsizeof获得结构体大小获得结构体大小获得结构体大小获得结构体大小sizeofsizeof( (变量或表达式变量或表达式变量或表达式变量或表达式) )sizeofsizeof( (类型类型类型类型) )12printf(%dn, sizeof(printf(%dn, siz

13、eof(SAMPLESAMPLE);); 【例例例例12.212.2】12.2.7结构体所占内存的字节数事实上,所有数据类型在内存中都是从事实上,所有数据类型在内存中都是从偶数偶数偶数偶数地址开始存放的地址开始存放的且结构所占的实际空间一般是按照机器字长对齐的且结构所占的实际空间一般是按照机器字长对齐的不同的编译器、平台,对齐方式会有变化不同的编译器、平台,对齐方式会有变化结构体变量的成员的存储结构体变量的成员的存储对齐规则对齐规则对齐规则对齐规则是与机器相关的是与机器相关的具有特定数据类型的具有特定数据类型的数据项大小数据项大小数据项大小数据项大小也是与机器相关的也是与机器相关的所以一个结构

14、体在内存中的存储格式也是与机器相关的所以一个结构体在内存中的存储格式也是与机器相关的chchf fchch12.3结构体数组的定义和初始化12.3结构体数组的定义和初始化建立了数据库中的多条记录,每条对应一个学生信息建立了数据库中的多条记录,每条对应一个学生信息 【例12.3】利用结构体数组计算每个学生的平均分教学进程教学进程教学进程教学进程 【例例例例】 有有N个学生的信息(包括学号,姓名,成绩),个学生的信息(包括学号,姓名,成绩),要求要求:按照成绩的高低按照成绩的高低顺序存储并输出各学生的信息。顺序存储并输出各学生的信息。#include#include#include#include

15、void main()void main() struct student struct student int num; int num; char name20; char name20; int score; int score; s6=1,aaa,59,2,bbb,78,3,ccc,85, s6=1,aaa,59,2,bbb,78,3,ccc,85, 4,ddd,64,5,eee,98,6,fff,83;4,ddd,64,5,eee,98,6,fff,83;/ / struct student temp_stu;struct student temp_stu; int i,j,max,

16、temp; int i,j,max,temp; char temp_name20; 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.sc

17、ore;si.score=smax.score;smax.score=temp; printf(num name scoren); for(i=0;ipt - studentID = 1; studentID = 1;12.4结构体指针的定义和初始化ptstu1成员成员1成员成员2成员成员3成员成员4成成员员5 当结构体当结构体当结构体当结构体嵌套嵌套嵌套嵌套时,如何访问结构体时,如何访问结构体时,如何访问结构体时,如何访问结构体指针变量所指向的结构体成员?指针变量所指向的结构体成员?指针变量所指向的结构体成员?指针变量所指向的结构体成员?stu1.stu1. birthday.birthda

18、y. year = 1999; year = 1999; (*pt).(*pt). birthday.birthday. year = 1999; year = 1999;pt -pt - birthday.birthday. year = 1999; year = 1999;STUDENTSTUDENT stu1;stu1; STUDENTSTUDENT * *pt = pt = & &stu1;stu1;12.4结构体指针的定义和初始化 STUDENTSTUDENT stu30;stu30; STUDENTSTUDENT * *pt;pt; pt = stu; pt = stu; 如何定义

19、指向如何定义指向如何定义指向如何定义指向结构体数组结构体数组结构体数组结构体数组的指针?的指针?的指针?的指针? STUDENTSTUDENT * *pt = stu;pt = stu;等价于等价于STUDENTSTUDENT * *pt = &stu0;pt = &stu0;等价于等价于ptstu30stu0stu1stu2stu3stu4stu5.stu29使用使用使用使用pt+pt+,使,使,使,使ptpt指向指向指向指向stu1stu1pt - pt - studentIDstudentID等价于等价于等价于等价于 stu1. stu1. studentIDstudentIDpt12.

20、412.4结构体结构体结构体结构体指针指针指针指针的定义和初始化的定义和初始化的定义和初始化的定义和初始化 STUDENTSTUDENT stu30;stu30; STUDENTSTUDENT * *pt = stu; pt = stu; 如何访问如何访问如何访问如何访问结构体数组指针结构体数组指针结构体数组指针结构体数组指针指向的指向的指向的指向的结构体成员?结构体成员?结构体成员?结构体成员? stu30stu0stu1stu2stu3stu4stu5.stu29教学进程教学进程教学进程教学进程 #include struct student int num; char name20; c

21、har sex; int age; ;【例例例例】 有有有有3 3个学生的信息,放在结构体数组中,要求用指针变量输出个学生的信息,放在结构体数组中,要求用指针变量输出个学生的信息,放在结构体数组中,要求用指针变量输出个学生的信息,放在结构体数组中,要求用指针变量输出 全部学生的信息。全部学生的信息。全部学生的信息。全部学生的信息。 struct student stu3=10101,Li Lin,M, 18, 10102,Zhang Fun,M, 19, 10104,Wang Min,F,20;void main() struct student *p; printf( No. Name se

22、x agen); for (p=stu;pnum, p-name, p-sex, p-age);图9-8教学进程教学进程教学进程教学进程注意:注意:(1)如果的初值为如果的初值为stu,即指向第一个元,即指向第一个元素,则加后素,则加后p就指向下一个元素。就指向下一个元素。 (+p)-num先使自加,先使自加, 然后得到它指向的元素中然后得到它指向的元素中 的的num成员值(即成员值(即10102)。)。 (p+)-num先得到先得到-num的值的值 (即(即10101),然后使),然后使 自加,指向自加,指向stu1。(2) p=&st1.nump=&st1.num;是错误的;是错误的;是错

23、误的;是错误的指向结构体数组的指针指向结构体数组的指针图9-812.5向函数传递结构体向函数传递结构体的单个成员复制单个成员的内容函数内对结构内容的修改不影响原结构向函数传递结构体的完整结构向函数传递结构体的首地址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/23Before function call:1999/04/23After function call:1999/0

24、4/23After function call:1999/04/23结构体结构体结构体结构体变量变量变量变量作函数参数作函数参数作函数参数作函数参数 【例例例例12.412.4】struct date int year; int month; int day;void func(struct date *p*p) p-p-year = 2000; p-p-month = 5; p-p-day = 22;Before function call:1999/04/23Before function call:1999/04/23After function call:After function

25、call:2000/05/222000/05/22结构体结构体结构体结构体指针指针指针指针作函数参数作函数参数作函数参数作函数参数指针作函数形参指针作函数形参实参必须为地址值实参必须为地址值 【例例例例12.512.5】struct date int year; int month; int day;struct datestruct date func(struct date p p) p.p.year = 2000; p.p.month = 5; p.p.day = 22; return p;return p;Before function call:1999/04/23Before fu

26、nction call:1999/04/23After function call:After function call:2000/05/222000/05/22结构体变量结构体变量结构体变量结构体变量作函数作函数作函数作函数返回值返回值返回值返回值 【例例例例12.612.6】12.5向函数传递结构体向函数传递结构体的完整结构复制整个结构体成员的内容,多个值复制整个结构体成员的内容,多个值函数内对结构内容的修改不影响原结构函数内对结构内容的修改不影响原结构内容传递更直观,但内容传递更直观,但开销大开销大向函数传递结构体的首地址用用结构体数组结构体数组/ /结构体指针作结构体指针作函数参数函

27、数参数仅复制结构体的首地址,一个值仅复制结构体的首地址,一个值修改结构体指针所指向的结构体的内容修改结构体指针所指向的结构体的内容指针传递效率高指针传递效率高教学进程教学进程教学进程教学进程【例例例例】 有有N个结构体变量个结构体变量stu,内含学号、姓名和,内含学号、姓名和3门课程的成门课程的成绩,要求输出平均成绩最高的学生的信息。绩,要求输出平均成绩最高的学生的信息。#include #define N 3struct student /要把结构体类型定义为全局的要把结构体类型定义为全局的 int num; char name20; float score3; float aver; ;

28、void main() void input(struct 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,&stu-score0, &stu-score1, &stu-score2); stu-aver=(stu

29、-score0+stu-score1+stu-score2)/3; stu+; */ struct student max(struct student stu) int i, max=0; for(i=1;istumax.aver) max=i; return stumax;void print(struct student stu) printf(“%d%s%f%f%f%f”, stu.num,stu.name,stu.score0,stu.score1,stu.score2);12.5向函数传递结构体 【例12.7】修改例12.3程序,用结构体数组作函数参数编程并输出计算学生的平均分 1

30、2.5向函数传递结构体 【例12.7】修改例12.3程序,用结构体数组作函数参数编程并输出计算学生的平均分 12.5向函数传递结构体 【例12.7】修改例12.3程序,用结构体数组作函数参数编程并输出计算学生的平均分 12.5向函数传递结构体 【例12.7】修改例12.3程序,用结构体数组作函数参数编程并输出计算学生的平均分 下面的结构是什么意思?下面的结构是什么意思? struct struct temp temp intint data; data; structstruct temp pt; temp pt;CBCB下的错误提示:下的错误提示: field pt has incomple

31、te typefield pt has incomplete typeVCVC下的错误提示:下的错误提示: pt uses undefined struct temppt uses undefined struct temp下面的结构是什么意思呢?下面的结构是什么意思呢? struct struct temp temp intint data; data; structstruct temp *pt; temp *pt;结构体声明时不能结构体声明时不能包含本结构体类型包含本结构体类型成员,成员,系统将无法系统将无法为这样的结构体类为这样的结构体类型分配内存型分配内存 可包含指向本结构体可包含指

32、向本结构体类型的指针变量类型的指针变量问题的提出问题的提出问题的提出问题的提出12.6动态数据结构单向链表structstruct Link Link intint data;data; structstruct Link *next; Link *next;datanextheaddatanextdatanextdataNULL 链表链表(Linked TableLinked Table): :线性表的链式存储结构线性表的链式存储结构特点:用一组任意的存储单元存储线性表的数特点:用一组任意的存储单元存储线性表的数特点:用一组任意的存储单元存储线性表的数特点:用一组任意的存储单元存储线性表的数

33、据;存储单元可以是连续的,也可是不连续的据;存储单元可以是连续的,也可是不连续的据;存储单元可以是连续的,也可是不连续的据;存储单元可以是连续的,也可是不连续的链表的定义datanextheaddatanextdatanextdataNULL 链表链表(Linked tableLinked table): :线性表的链式存储结构线性表的链式存储结构为表示每个元素与后继元素的逻辑关系,除存为表示每个元素与后继元素的逻辑关系,除存为表示每个元素与后继元素的逻辑关系,除存为表示每个元素与后继元素的逻辑关系,除存储元素本身信息外,还要存储其直接后继信息储元素本身信息外,还要存储其直接后继信息储元素本身

34、信息外,还要存储其直接后继信息储元素本身信息外,还要存储其直接后继信息两部分信息组两部分信息组成一个节点成一个节点structstruct Link Link intint data;data; structstruct Link *next; Link *next;datanextheaddatanextdatanextdataNULL数据域:存储数据数据域:存储数据元素信息元素信息指针域:存储直接指针域:存储直接后继的节点信息后继的节点信息链表的定义链表的定义链表的定义链表的定义 链表链表(Linked TableLinked Table): :线性表的链式存储结构线性表的链式存储结构为表

35、示每个元素与后继元素的逻辑关系,除存为表示每个元素与后继元素的逻辑关系,除存为表示每个元素与后继元素的逻辑关系,除存为表示每个元素与后继元素的逻辑关系,除存储元素本身信息外,还要存储其直接后继信息储元素本身信息外,还要存储其直接后继信息储元素本身信息外,还要存储其直接后继信息储元素本身信息外,还要存储其直接后继信息structstruct Link Link intint data;data; structstruct Link *next; Link *next;n个节点链接成一个链表(因为只包含一个指针域,故又个节点链接成一个链表(因为只包含一个指针域,故又称线性链表或单向链表)称线性链表

36、或单向链表)链表是一种常见的重要的数据结构链表是一种常见的重要的数据结构, ,是动态地进行存储分配的一是动态地进行存储分配的一种结构。种结构。链表的组成:链表的组成: 头指针:存放一个地址,该地址指向一个元素头指针:存放一个地址,该地址指向一个元素 结点:用户需要的实际数据和链接节点的指针结点:用户需要的实际数据和链接节点的指针结点的动态分配结点的动态分配结点的动态分配结点的动态分配用结构体建立链表:用结构体建立链表:struct student int num; float score; struct student *next ;; 其中成员其中成员num和和score用来存放结点中的有用

37、数据(用户需要用到用来存放结点中的有用数据(用户需要用到的数据),的数据),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

38、;b.score=90; c. num=99107; c.score=85; c. num=99107; c.score=85; 1. 1. 建立简单的静态链表建立简单的静态链表建立简单的静态链表建立简单的静态链表【例例例例】 建立上图所示的简链表建立上图所示的简链表,它由各学生数据的节点组成。,它由各学生数据的节点组成。输出各节点中的数据。输出各节点中的数据。 head=&a; a.next=&b; b.next=&c; c.next=NULL; p=head; do printf(%ld %5.1fn“ ,p-num,p-score); p=p-next; while(p!=NULL);

39、教学进程教学进程教学进程教学进程教学进程教学进程教学进程教学进程 所谓建立动态链表是指在程序执行过程中从无所谓建立动态链表是指在程序执行过程中从无到有地建立起一个链表,即一个一个地开辟结点和到有地建立起一个链表,即一个一个地开辟结点和输入各结点数据,并建立起前后相链的关系。输入各结点数据,并建立起前后相链的关系。2. 2.建立动态链表建立动态链表建立动态链表建立动态链表教学进程教学进程教学进程教学进程教学进程教学进程教学进程教学进程 void *malloc(unsigned int size);void *malloc(unsigned int size);在内存的动态存储区分配一个长度为在

40、内存的动态存储区分配一个长度为在内存的动态存储区分配一个长度为在内存的动态存储区分配一个长度为sizesize的连续空间。此函数返回值是一个分配的连续空间。此函数返回值是一个分配的连续空间。此函数返回值是一个分配的连续空间。此函数返回值是一个分配域起始地址(类型域起始地址(类型域起始地址(类型域起始地址(类型voidvoid)。如果此函数未能成功执行,则返回空指针()。如果此函数未能成功执行,则返回空指针()。如果此函数未能成功执行,则返回空指针()。如果此函数未能成功执行,则返回空指针(NULLNULL)void *calloc(unsigned n, unsigned size);void

41、 *calloc(unsigned n, unsigned size); 在内存动态存储区分配在内存动态存储区分配在内存动态存储区分配在内存动态存储区分配n n个长度为个长度为个长度为个长度为sizesize的连续空间。函数返回一个指向分配域的连续空间。函数返回一个指向分配域的连续空间。函数返回一个指向分配域的连续空间。函数返回一个指向分配域起始位置的指针。如果分配不成功,则返回起始位置的指针。如果分配不成功,则返回起始位置的指针。如果分配不成功,则返回起始位置的指针。如果分配不成功,则返回NULLNULL 用用用用calloccalloc函数可以为一维数组开辟动态存储空间,函数可以为一维数组

42、开辟动态存储空间,函数可以为一维数组开辟动态存储空间,函数可以为一维数组开辟动态存储空间,n n为数组元素个数,每个元为数组元素个数,每个元为数组元素个数,每个元为数组元素个数,每个元素长度为素长度为素长度为素长度为sizesize。void free ( void *p)void free ( void *p) 释放由释放由释放由释放由p p指向的动态存储区,使这部分内存区能被其他变量使用。指向的动态存储区,使这部分内存区能被其他变量使用。指向的动态存储区,使这部分内存区能被其他变量使用。指向的动态存储区,使这部分内存区能被其他变量使用。P P是最近一是最近一是最近一是最近一次调用次调用次调

43、用次调用calloccalloc或或或或mallocmalloc函数时返回的值。函数时返回的值。函数时返回的值。函数时返回的值。freefree函数无返回值。函数无返回值。函数无返回值。函数无返回值。在链表中查找指定元素在链表中查找指定元素在链表中查找指定元素在链表中查找指定元素教学进程教学进程教学进程教学进程建立链表的函数如下建立链表的函数如下: #include #include #define LEN sizeof(struct student) /令令LEN代表代表struct student类型数据的长度类型数据的长度 struct student int num; float sc

44、ore; struct student *next; 【例例例例】 写一函数建立一个有写一函数建立一个有2名学生学号和成绩的单向动态链表。名学生学号和成绩的单向动态链表。教学进程教学进程教学进程教学进程void main() struct student *head, *p; head=p=( struct student*) malloc(LEN); scanf(“%d,%f”,&p-num,&p-score); p=( struct student*) malloc(LEN); scanf(“%d,%f”,&p-num,&p-score); head-next=p; pnext=NULL;

45、 p=head; printf(“%d,%f”, p-num, p-score); p=p-next; printf(“%d,%f”, -num, p-score);例:写一个函数建立/输出一个有n名学生数据的单向动态链表对链表的综合操作对链表的综合操作(包括对结点的插入删除)(包括对结点的插入删除)链表的建立向链表中添加一个新节点data = Anodedata = Bnodedata = C nodehead空指针空指针空指针空指针NULLNULLNULLNULL表示表示表示表示链表结尾链表结尾链表结尾链表结尾链表的头指针:链表的头指针:链表的头指针:链表的头指针:访问链表的关键访问链表的

46、关键访问链表的关键访问链表的关键链表操作总结链表操作总结链表的建立若原链表为空表(head = NULL) ,则将新建节点p置为头节点 head(1)head = p(1)head = pdatanext p新建节点新建节点新建节点新建节点(2) pr = ppr(3) pr-next = NULLdatanext新建节点新建节点新建节点新建节点p链表的建立若原链表为非空,则将新建节点p添加到表尾 (1) pr-next = p(1) pr-next = p(2) pr = pheaddataprpr(3) pr-next = NULLnext根据上述思想编写向链表添加节点数据的程序如下:根据

47、上述思想编写向链表添加节点数据的程序如下:#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;struct link *head = NULL; /* 链表头指针链表头指针 */printf(Do you want to append a new no

48、de(Y/N)?);scanf( %c,&c); /* %c前面有一个空格前面有一个空格 */while (c=Y | c=y) head = AppendNode(head);/* 向向head为头指针的链表末尾添加节点为头指针的链表末尾添加节点 */DisplyNode(head); /* 显示当前链表中的各节点信息显示当前链表中的各节点信息 */printf(Do you want to append a new node(Y/N)?);scanf( %c,&c); /* %c前面有一个空格前面有一个空格 */ i+; printf(%d new nodes have been apen

49、ded!n, i);DeleteMemory(head); /* 释放所有动态分配的内存释放所有动态分配的内存 */return 0;/* 函数功能:新建一个节点并添加到链表末尾,返回添加节点后的链表的头指针函数功能:新建一个节点并添加到链表末尾,返回添加节点后的链表的头指针 */struct link *AppendNode(struct link *head)struct link *p = NULL, *pr = head;int data;p = (struct link *)malloc(sizeof(struct link); /* 让让p指向新建节点指向新建节点 */if (p

50、= NULL) /* 若为新建节点申请内存失败,则退出程序若为新建节点申请内存失败,则退出程序 */printf(No enough memory to allocate!n);exit(0); if (head = NULL) /* 若原链表为空表若原链表为空表 */ head = p; /* 将新建节点置为头节点将新建节点置为头节点 */else /* 若原链表为非空,则将新建节点添加到表尾若原链表为非空,则将新建节点添加到表尾 */ while (pr-next != NULL) /* 若未到表尾,则移动若未到表尾,则移动pr直到直到pr指向表尾指向表尾 */ pr = pr-next;

51、 /* 让让pr指向下一个节点指向下一个节点 */pr-next = p; /* 让末节点的指针域指向新建节点让末节点的指针域指向新建节点 */printf(Input node data:);scanf(%d, &data); /* 输入节点数据输入节点数据 */p-data = data; /* 将新建节点的数据域赋值为输入的节点数据值将新建节点的数据域赋值为输入的节点数据值 */ p-next = NULL; /* 将新建节点置为表尾将新建节点置为表尾 */return head; /* 返回添加节点后的链表的头指针返回添加节点后的链表的头指针 */* 函数的功能:显示链表中所有节点的节

52、点号和该节点中数据项内容函数的功能:显示链表中所有节点的节点号和该节点中数据项内容 */void DisplyNode(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指向的链表中所有节点占用的内存指向的链表中所有

53、节点占用的内存 */void DeleteMemory(struct link *head)struct link *p = head, *pr = NULL;while (p != NULL) /* 若不是表尾,则释放节点占用的内存若不是表尾,则释放节点占用的内存 */pr = p; /* 在在pr中保存当前节点的指针中保存当前节点的指针 */p = p-next; /* 让让p指向下一个节点指向下一个节点 */free(pr); /* 释放释放pr指向的当前节点占用的内存指向的当前节点占用的内存 */ 链表的删除操作若原链表为空表,则退出程序 若待删除节点p是头节点,则将head指向当前节

54、点的下一个节点即可删除当前节点 datanext(1) head = p-next(1) head = p-nexthead待删除节点待删除节点待删除节点待删除节点datanext p头节点头节点头节点头节点( (2 2) ) free(p)free(p)链表的删除操作若待删除节点不是头节点,则将前一节点的指针域指向当前节点的下一节点即可删除当前节点(1) pr-next = p-next(1) pr-next = p-nextdatanextdatanext待删除节点待删除节点待删除节点待删除节点datanext p中间节点中间节点中间节点中间节点datanext 若已搜索到表尾若已搜索到表

55、尾若已搜索到表尾若已搜索到表尾(p-next = NULLp-next = NULL)仍未找仍未找仍未找仍未找到待删除节点,则显示到待删除节点,则显示到待删除节点,则显示到待删除节点,则显示“ “未找到未找到未找到未找到” ” ( (2 2) ) free(p)free(p)#include #include struct link *AppendNode(struct link *head);void DisplyNode(struct link *head);void DeleteMemory(struct link *head);struct link *DeleteNode(struc

56、t 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,&c); /* %c前面有一个空格前面有一个空格 */while (c=Y | c=y) head = AppendNode(head);DisplyNode(head); /* 显示当前链表中的各节点信息显示

57、当前链表中的各节点信息 */printf(Do you want to append a new node(Y/N)?);scanf( %c,&c); /* %c前面有一个空格前面有一个空格 */ i+; printf(%d new nodes have been apended!n, i);head = DeleteNode(head, 20);DisplyNode(head); DeleteMemory(head); /* 释放所有动态分配的内存释放所有动态分配的内存 */return 0;/* 函数功能:新建一个节点并添加到链表末尾,返回添加节点后的链表的头指针函数功能:新建一个节点并添

58、加到链表末尾,返回添加节点后的链表的头指针 */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) /* 若原链表为空表,则将新建节点置为首节点若原链表为空表,则将新建节

59、点置为首节点 */head = p; else /* 若原链表为非空,则将新建节点添加到表尾若原链表为非空,则将新建节点添加到表尾 */ while (pr-next != NULL)/* 若未到表尾,则移动若未到表尾,则移动pr直到直到pr指向表尾指向表尾 */ pr = pr-next; /* 让让pr指向下一个节点指向下一个节点 */pr-next = p; /* 将新建节点添加到链表的末尾将新建节点添加到链表的末尾 */pr = p; /* 让让pr指向新建节点指向新建节点 */printf(Input node data:);scanf(%d, &data); /* 输入节点数据输入

60、节点数据 */pr-data = data;pr-next = NULL; /* 将新建节点置为表尾将新建节点置为表尾 */return head; /* 返回添加节点后的链表的头节点指针返回添加节点后的链表的头节点指针 */* 函数的功能:显示链表中所有节点的节点号和该节点中数据项内容函数的功能:显示链表中所有节点的节点号和该节点中数据项内容 */void DisplyNode(struct link *head)struct link *p = head;intj = 1;while (p != NULL) /* 若不是表尾,则循环打印若不是表尾,则循环打印 */printf(%5d%10

61、dn, 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 =

62、p-next; /* 让让p指向下一个节点指向下一个节点 */free(pr); /* 释放释放pr指向的当前节点占用的内存指向的当前节点占用的内存 */ /*函数功能:从函数功能:从head指向的链表中删除一个节点,返回删除节点后的链表的头指针指向的链表中删除一个节点,返回删除节点后的链表的头指针 */struct link *DeleteNode(struct link *head, int nodeData)struct link *p = head, *pr = head;if (head = NULL) /* 若链表为空表,则退出程序若链表为空表,则退出程序 */printf(Lin

63、ked Table is empty!n);return(head);while (nodeData != p-data & p-next != NULL)/* 未找到且未到表尾未找到且未到表尾 */pr = p;p = p-next; if (nodeData = p-data)/* 若找到节点若找到节点nodeData,则删除该节点,则删除该节点 */ if (p = head) /* 若待删除节点为首节点,则让若待删除节点为首节点,则让head指向第指向第2个节点个节点 */ head = p-next; else /*若待删除节点不是首节点,则将前一节点的指针指向当前节点的下一节点若待

64、删除节点不是首节点,则将前一节点的指针指向当前节点的下一节点*/ pr-next = p-next; free(p); /* 释放为已删除节点分配的内存释放为已删除节点分配的内存 */ else /* 没有找到待删除节点没有找到待删除节点 */ printf(This Node has not been found!n); return head; /* 返回删除节点后的链表的头节点指针返回删除节点后的链表的头节点指针 */链表的插入操作若原链表为空表,则将新节点p作为头节点,让head指向新节点p head待插入节点待插入节点待插入节点待插入节点data p(1) head(1) head

65、= p = pp = (struct link *)malloc(sizeof(struct link);p = (struct link *)malloc(sizeof(struct link);p-next = NULL;p-next = NULL;p-data = nodeData;p-data = nodeData;链表的插入操作若原链表为非空,则按节点值(假设已按升序排序)的大小确定插入新节点的位置若在头节点前插入新节点,则将新节点的指针域指向原链表的头节点,且让head指向新节点head待插入节点待插入节点待插入节点待插入节点datanext p(2) head = p(2) he

66、ad = pdatanextdatanextdata(1) p-next = head(1) p-next = headdatanext链表的插入操作若在链表中间插入新节点,则将新节点的指针域指向下一节点且让前一节点的指针域指向新节点待插入节点待插入节点待插入节点待插入节点datanext p(2) pr-next = p(2) pr-next = pdatanextdatanextdata(1) p-next = pr-next(1) p-next = pr-nextprdatanext链表的插入操作若在表尾插入新节点,则末节点指针域指向新节点待插入节点待插入节点待插入节点待插入节点data

67、next p(1) pr-next = p(1) pr-next = pprdata原末节点原末节点原末节点原末节点next链表的输出遍历链表的所有节点headdatanextdatanextdatapppp#include #include struct link *AppendNode(struct link *head);void DisplyNode(struct link *head);void DeleteMemory(struct link *head);struct link *InsertNode(struct link *head, int nodeData);struct

68、 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,&c); /* %c前面有一个空格前面有一个空格 */while (c=Y | c=y) head = AppendNode(head);DisplyNode(head); /* 显示当前链表中的各节点信息显示当前链表中的各节点信息 */printf(Do you want t

69、o append a new node(Y/N)?);scanf( %c,&c); /* %c前面有一个空格前面有一个空格 */ i+; printf(%d new nodes have been apended!n, i);head = InsertNode(head, 20);DisplyNode(head); DeleteMemory(head); /* 释放所有动态分配的内存释放所有动态分配的内存 */return 0;/* 函数功能:新建一个节点并添加到链表末尾,返回添加节点后的链表的头指针函数功能:新建一个节点并添加到链表末尾,返回添加节点后的链表的头指针 */struct lin

70、k *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 /* 若原链表为

71、非空,则将新建节点添加到表尾若原链表为非空,则将新建节点添加到表尾 */ while (pr-next != NULL)/* 若未到表尾,则移动若未到表尾,则移动pr直到直到pr指向表尾指向表尾 */ pr = pr-next; /* 让让pr指向下一个节点指向下一个节点 */ pr-next = p; /* 将新建节点添加到链表的末尾将新建节点添加到链表的末尾 */ pr = p; /* 让让pr指向新建节点指向新建节点 */ printf(Input node data:); scanf(%d, &data); /* 输入节点数据输入节点数据 */ pr-data = data; pr-n

72、ext = NULL; /* 将新建节点置为表尾将新建节点置为表尾 */ return head; /* 返回添加节点后的链表的头节点指针返回添加节点后的链表的头节点指针 */* 函数的功能:显示链表中所有节点的节点号和该节点中数据项内容函数的功能:显示链表中所有节点的节点号和该节点中数据项内容 */void DisplyNode(struct link *head)struct link *p = head;intj = 1;while (p != NULL) /* 若不是表尾,则循环打印若不是表尾,则循环打印 */printf(%5d%10dn, j, p-data);/* 打印第打印第j

73、个节点的数据个节点的数据 */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指向下一个节点指向下一

74、个节点 */free(pr); /* 释放释放pr指向的当前节点占用的内存指向的当前节点占用的内存 */ /* 函数功能:在已按升序排序的链表中插入一个节点,返回插入节点后的链表头指针函数功能:在已按升序排序的链表中插入一个节点,返回插入节点后的链表头指针 */struct link *InsertNode(struct link *head, int nodeData)struct link *pr = head, *p = head, *temp = NULL;p = (struct link *)malloc(sizeof(struct link);/* 让让p指向待插入节点指向待插入节

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

76、表尾,则继续找若未找到待插入节点的位置且未到表尾,则继续找 */ 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指向新节点指向新节

77、点 */ else /* 若在链表中间插入新节点若在链表中间插入新节点 */ pr = temp; p-next = pr-next;/* 将新节点的指针域指向下一节点将新节点的指针域指向下一节点 */ pr-next = p; /* 让前一节点的指针域指向新节点让前一节点的指针域指向新节点 */ else /* 若在表尾插入新节点若在表尾插入新节点 */ pr-next = p; /* 让末节点的指针域指向新节点让末节点的指针域指向新节点 */ return head; /* 返回插入新节点后的链表头指针返回插入新节点后的链表头指针head的值的值 */用户自定义的数据类型用户自定义的数据类

78、型结构体(StructStruct)把把关系紧密关系紧密且且逻辑相关逻辑相关的多种不同类型的变量,组织的多种不同类型的变量,组织到统一的名字之下到统一的名字之下占用占用相邻相邻的一段内存单元的一段内存单元共用体,也称联合(UnionUnion)把把情形互斥情形互斥但但逻辑相关逻辑相关的多种不同类型的变量,组织的多种不同类型的变量,组织到统一的名字之下到统一的名字之下占用占用同一段同一段内存单元,每一时刻只有一个数据起作用内存单元,每一时刻只有一个数据起作用12.7共用体和枚举类型共用体和枚举类型12.7.1共用体structstruct sample sample shortshort i;

79、i; charchar ch; ch; floatfloat f; f;0x0037b00unionunion sample sample shortshort i; i; charchar ch; ch; floatfloat f; f;printf(%dn, sizeof(struct sample);printf(%dn, sizeof(struct sample);i ichchf fprintf(%dn, sizeof(union sample);printf(%dn, sizeof(union sample);i ichchf f 【例例例例12.812.8】12.7.1共用体si

80、zeof(union number)取决于占空间最多占空间最多的那个成员变量0x0037b00同一内存单元在每一瞬时只能存放其中一种类型的成员同一内存单元在每一瞬时只能存放其中一种类型的成员起作用的成员是起作用的成员是最后一次存放最后一次存放最后一次存放最后一次存放的成员,不能作为函数参数的成员,不能作为函数参数不能进行比较操作,只能对第一个成员初始化不能进行比较操作,只能对第一个成员初始化f f12.7.112.7.1共用体共用体共用体共用体12.7.112.7.1共用体共用体共用体共用体12.7.2枚举数据类型枚举(枚举(EnumerationEnumeration)数据类型)数据类型描述

81、的是一组整型值的集合用于当某些量仅由有限个数据值组成时 enum 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 2其值为其值为1 112.8.1 12.8.1 用用用用typedeftypedef命名已有类型命名已有类型命名已有类型命名已有类型 可以用可以用typedef

82、typedef声明新的类型名来代替已有的类型名声明新的类型名来代替已有的类型名 例:例:typedef int COUNT;typedef int COUNT; typedef real REAL; typedef real REAL; 这样,以下两行等价:这样,以下两行等价: int i,j; float a,b; int i,j; float a,b; COUNT i,j; REAL a,b; COUNT i,j; REAL a,b; 可以声明结构体类型:可以声明结构体类型: typedef structtypedef struct int month; int month; int da

83、y; int day; int year; int year; DATE; DATE;DATE birthday;(DATE birthday;(不要写成不要写成不要写成不要写成struct DATE birthday;)struct DATE birthday;)DATE *p; (pDATE *p; (p为指向此结构体类型数据的指针为指向此结构体类型数据的指针为指向此结构体类型数据的指针为指向此结构体类型数据的指针) )12.8 12.8 补充补充补充补充 还可以进一步:还可以进一步:(1 1)typedef int NUM100;(typedef int NUM100;(声明声明NUMN

84、UM为整型数组类型为整型数组类型) ) NUM n; NUM n; (定义(定义n n为整型数组变量)为整型数组变量) (2) typedef char *STRING; (2) typedef char *STRING;(声明(声明STRINGSTRING为字符指针类型)为字符指针类型) STRING p,s10; STRING p,s10; (定义(定义p p为字符指针变量,为字符指针变量,s s为指针数组)为指针数组) 归纳起来,声明一个新的类型名的方法是:归纳起来,声明一个新的类型名的方法是: (1 1)先按定义变量的方法写出定义体(如:)先按定义变量的方法写出定义体(如:int i;

85、int i;) (2 2)将变量名换成新类型名(如:将)将变量名换成新类型名(如:将i i换成换成COUNTCOUNT) (3 3)在最前面加上)在最前面加上typedeftypedef(例如:(例如:typedef int COUNT )typedef int COUNT ) (4 4)然后可以用新类型名去定义变量)然后可以用新类型名去定义变量再以定义上述的数组类型为例来说明:再以定义上述的数组类型为例来说明: (1 1)先按定义数组变量的形式书写:)先按定义数组变量的形式书写:int n100;int n100; (2 2)将变量名)将变量名 n n 换成自己指定的类型名:换成自己指定的类

86、型名:int NUM100;int NUM100; (3 3)在最前面加上)在最前面加上typedeftypedef,得到,得到typedef int NUM100;typedef int NUM100; (4 4) 用来定义变量:用来定义变量:NUM n;NUM n;12.8.2位段(补充)位段(补充)C语言允许在一个结构体中以位为单位来指定其成员所占内存长语言允许在一个结构体中以位为单位来指定其成员所占内存长度,这种以位为单位的成员称为度,这种以位为单位的成员称为“位段位段”或或“位域位域”(bit field)。)。利用位段能够用较少的位数存储数据。利用位段能够用较少的位数存储数据。 s

87、truct 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从另一字节开头起存放从另一字节开头起存放注意:注意:存储单元中位段的空间分配方向因机器而异,存储单元中位

88、段的空间分配方向因机器而异, 但是用户不必过问细节但是用户不必过问细节对位段中的数据引用方法对位段中的数据引用方法 data.a=2; data.b=7; data.c=9;注意:位段允许的最大值范围注意:位段允许的最大值范围说明:说明:(1)位段成员的类型必须指定为)位段成员的类型必须指定为unsigned 或或int类型类型(2)若某一位段要从另一个字开始存放,可以用以下形式定义:)若某一位段要从另一个字开始存放,可以用以下形式定义: unsigned a:1; 一个存储单元一个存储单元 unsigned b:2; unsigned :0; unsigned c:3; (另一个存储单元)(

89、另一个存储单元) 上述存储单元可能是一个字节,也可能是上述存储单元可能是一个字节,也可能是2个字节,视不同的个字节,视不同的编译系统而异编译系统而异(3)一个位段必须存储在同一存储单元中,不能跨两个单元)一个位段必须存储在同一存储单元中,不能跨两个单元(4)可以定义无名位段)可以定义无名位段 unsigned a:1; unsigned :2; (这两位空间不用)(这两位空间不用) unsigned b:3; unsigned c:4;(5)位段的长度不能大于存储单元的长度,也)位段的长度不能大于存储单元的长度,也不能定义位不能定义位 段数组段数组。(6)位段可以用整型格式符输出)位段可以用整

90、型格式符输出 printf(“%d,%d,%d”,data.a,data.b,data.c);(7)位段可以在数值表达式中引用,它会被系统自动转换)位段可以在数值表达式中引用,它会被系统自动转换 成整型数:成整型数:data.a+5/data.b本章小结本章小结1. C语言中有两类数据:一类是系统已经定义好的语言中有两类数据:一类是系统已经定义好的标准数据类型标准数据类型,也称也称基类型基类型,如:,如:int、long、char、float、double等,可以直接等,可以直接使用;另一类是使用;另一类是用户根据需要自己设计的数据类型用户根据需要自己设计的数据类型,必须先声明,必须先声明,然

91、后才能使用,如:结构体、共用体等。然后才能使用,如:结构体、共用体等。2. 结构体由若干个数据成员组成的,他们可以是不同类型的。结构体由若干个数据成员组成的,他们可以是不同类型的。3. 同类型的结构体变量可以相互赋值,但不能用结构体变量名对同类型的结构体变量可以相互赋值,但不能用结构体变量名对结构体进行整体输入输出。可以对结构体变量的成员进行赋值、结构体进行整体输入输出。可以对结构体变量的成员进行赋值、比较、输入输出等操作。比较、输入输出等操作。4. 引用结构体成员的方法有:引用结构体成员的方法有: 结构体变量结构体变量.成员名成员名 “.”成员运算符成员运算符 (*指针变量)指针变量).成员

92、名成员名 指针变量是指向结构体变量的指针变量是指向结构体变量的 p-成员运算符成员运算符 p是指向结构体变量的指针变量是指向结构体变量的指针变量教学进程教学进程教学进程教学进程5. 结构体变量的指针结构体变量的指针就是结构体变量的起始地址。就是结构体变量的起始地址。6. 把结构体变量和指向结构体变量的指针结合起来,把结构体变量和指向结构体变量的指针结合起来,可以建立动态数据结构。了解可以建立动态数据结构。了解链表链表的建立操作的的建立操作的思路。思路。7. 共用体共用体与结构体不同,其成员与结构体不同,其成员共享共享同一段存储空同一段存储空间,因此各成员的值不会同时存在,在某一瞬间,间,因此各成员的值不会同时存在,在某一瞬间,只有最后一次被赋值的成员是有意义的。只有最后一次被赋值的成员是有意义的。8. 枚举类型是把可能的值全部一一列出来,枚举变枚举类型是把可能的值全部一一列出来,枚举变量的值只能是其中的一个。量的值只能是其中的一个。教学进程教学进程教学进程教学进程本章小结本章小结

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > 工作计划

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号