《C语言程序设计结构体和共用体样本教案.docx》由会员分享,可在线阅读,更多相关《C语言程序设计结构体和共用体样本教案.docx(12页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、构造体与共用体 第一讲内容说明主要内容重点难点问题提出1.构造体的概念及其根本操作2.构造体变量的引用方法3.构造体数组的运用例子:int a5;通过举例说明定义构造体类型的必要性。和根本类型变量进展比拟分析,进一步说明必需定义构造体类型。强调留意与以往变量应用的区分1.对构造体类型的理解2.构造体类型的运用构造体变量的引用前面已经介绍了根本数据类型整型、浮点型、字符型,也介绍了一种构造类型数组,数组中各元素是属于同一种类型的。例如:一个学生的学号、姓名、性别、年龄、成果、家庭地址等项,各项的数据类型并不一样(如下图) num name sex age score addr10010Li Fa
2、nm1888chengde假如将num、name、sex、age、score、addr分别定义为相互独立的简洁变量,难以反映它们之间的内在联络,如何解决此类问题呢?一、构造体类型引入处理这样的二维表数据时,通常以记录为单位进展处理, 而每条记录中包含多种数据类型,按以前所讲的数据类型没有方法处理。 故引入了构造类型。即将多个根本类型作为一个集体定义成一种新的用户自定义类型。例:Struct student int num;char name20;char sex;int age;float score;char addr30; ;说明:1Struct 是一个关键字,标记着这是一个构造体类型。2
3、Struct student是一个类型名。二、构造类型的运用步骤step1:说明所定义的构造类型的构造形式,成员构成;相当于建立数据库二维表的表构造.step2:用所定义的构造类型定义构造变量(记录变量);相当于为数据库二维表的各记录定义一个记录名.step3:通过所定义构造变量(记录变量)访问对应记录中的成员.相当于编辑数据库二维表的记录中的各项.(1)构造类型的说明:在Turbo C中, 构造也是一种数据类型, 但不同二维表所对应的构造不同,故在运用前须要对构造状况进展说明,即构造类型的说明.构造类型说明的一般格式为:比拟举例 struct 构造名 类型名1 成员变量名1; 类型名2 成员
4、变量名2; .类型名n 成员变量名n; 说明:1)struct是关键字,是构造类型的标记;2)构造名是用户所说明的构造类型的名称的标识符,而不是变量名,以后可用它来定义构造变量.3)类型名为以前所讲的各种数据类型(int, char等),也可以是已说明的构造类型。4)成员变量名是构成构造的每一个成员变量的名称,相当于数据库二维表中的各字段名.例1: struct date int year;int month;int day;例2:struct student char name12;char sex; sturct date birthday;float sc4;在C语言中,构造类型可以嵌套
5、定义,所以以上两例可以合并为:struct student char name12;char sex;struct date int year;int month;int day; birthday;float sc4;(2)构造变量的定义及构造变量的内存安排:1)构造变量的定义象其它类型的变量一样, 在运用构造变量时要先对其定义。构造变量可以是一般构造变量,构造数组,和构造指针等形式.定义构造变量有三种格式,现分别举例说明:先声明一个Struct date类型,然后在定义Struct student类型时,将成员Birthday定义为Struct date类型。 格式一: 先说明构造类型,再
6、单独进展构造变量定义.例: struct student char name12;char sex; sturct date birthday;float sc4;struct student std,pers3,*pstd; 说明:这个例子定义了三个构造类型名为student的构造变量:一般构造变量:std;构造数组变量:pers3;指向该构造类型的指针变量:*pstd.格式二: 紧跟在构造类型说明之后进展构造变量定义:例: struct student char name12;char sex; sturct date birthday;float sc4;std,pers3,*pstd;
7、 说明:假如省略变量名std,pers3,*pstd, 则变成对构造的说明.可以省略构造名,用一个无名构造类型干脆定义构造类型变量。 例: struct char name12;char sex; sturct date birthday;float sc4;std,pers3,*pstd; 这种构造类型变量定义的方式与不省略构造名的方式相比,不同之处在于:这种格式定义构造变量以后无法再定义此构造类型的其它构造变量,而带有构造名的格式则可以. 格式三: 运用typedef说明一个构造类型名,再用新类型名定义构造变量.例:typedef struct char name12;char sex;
8、sturct date birthday;float sc4;STD_GRADE;STD_GRADE std,pers3,*pstd;说明: 这里STD_GRADE为用户定义的一个构造类型的类型名.因此可用它来定义构造变量,而不再须要关键字sturct了.构造体数组和数值型数组不同之处在于每个数组元素都是一个构造体类型的数据。先提示讲解typedef留意理解难点2)构造变量的内存安排一般构造变量 如:struct student std;系统为该构造变量安排内存时,所安排的字节数为该构造变量所包含的各个成员变量所占字节数之和,即35个字节.如下图所示: Name sex year month
9、day sc0 sc1 sc2 sc312个字节1个2个2个2个4个4个4个4个构造数组变量 如:struct student pers3; 该构造数组包括3个元素,相当于3个一般构造变量,系统为该构造数组变量安排内存时,安排连续的3个与一般构造变量std所占内存空间大小相等的内存空间.如下图所示: pers pers0 pers1 per235个字节35个字节35个字节指向构造类型的指针变量: 如:struct student *pstd;系统为该指针变量安排一个存放地址的4个字节的内存空间,详细该指针变量指向哪个构造类型变量,通过为该指针变量给予某构造变量地址值来确定.如下例: struc
10、t student *pstd1,*pstd2,*pstd3;pstd1=&std; /* pstd1指向构造变量std的首地址*/pstd2=pers; /* pstd2指向构造数组pers的首地址*/pstd3=(struct student*)malloc(size of (struct student);说明: 构造变量名不是指向该构造的地址, 这与数组名的含义不同, 因此若须要求构造中第一个成员的首地址应当是:&构造变量名(3)构造变量的初始化1)给一般构造变量赋初值: 要求: .按构造变量中每个成员在构造体中的依次一一对应赋初值;.不允许跳过前边的成员给后面的成员赋初值;.可以只给
11、前面的若干个连续的成员赋初值,对于后面未赋初值的成员变量,系统自动赋值.如数值型和字符型的自动赋0.所赋初值用括起. 例:struct student char name12;char sex; sturct date birthday;float sc4; std=Zhang san,M,1981,7,3,91,81,71,61;2)给构造数组变量赋初值: 要求: 参考数组一章. 例:struct student char name12;char sex; sturct date birthday;float sc4; pers3= Zhang san,M,1981,1,1,91,81,71
12、,61, Li si , M , 1982 , 2 , 2 , 92,82,72,62,Wang wu , F,1983, 3, 3,93,83,73,63 ; 有时构造数组长度可以省略,而由初值个数来示意.(4)构造变量成员的引用和操作: 1)对构造变量成员的引用和操作:三种引用形式:构造体变量名.成员名适用于一般构造变量和构造数组变量例: std.sex=F;std.sc0=91;pers1.sc2=67; puts(per2.name);scanf(%c,&per0.sex);printf(%d-%d,std.birthday.year, std.birthday.month); 构造指
13、针变量名-成员名 (*构造指针变量名).成员名适用于指向构造类型的指针变量例:pstd-sex=M;(*psd).sex=M;pstd-sc2=87;(*pstd).sc2=87;gets(pstd-name);gets(*psd).name);scanf(%d,&pstd-birthday.day); scanf(%d,&(*pstd).birthday.day);2)通过构造指针引用构造成员变量时,+和-运算对结果的影响:用以下实例来分析:struct int a;int *s;*p;第一组引用: 对成员变量a的引用+p-a+(p-a)说明: 成员变量a自增加1.(+p)-a说明: 指针p
14、先挪动一个单位,然后引用对应的成员变量a.留意: p每挪动一个单位要挪动多少字节(p+)-a p+-a 说明: 先引用当前p所对应的成员a,引用完后,p挪动一个单位.第二组引用: 对成员变量s的引用*p-s*(p-s)说明: 引用s所指向的内存单元.*p-s+说明: 先引用s所指向的内存单元,然后指针s挪动一个单位.留意: s每挪动一个单位要挪动多少字节(*p-s)+ 说明: 指针s所指的内存单元存储的数值自增1.*p+-s *(p+-s)说明: 先引用s所指向的内存单元,然后指针p挪动一个单位.3)一样类型的构造变量之间整体赋值例:struct int a;int b;per1,per2=2
15、,3;per1=per2;留意: 整体赋值时,要保证=两边的构造变量的构造类型一样.小结 本讲主要通过二维表引出了构造体类型,然后讲解了构造体类型的构造类型定义、构造体变量定义、构造体变量的内存占用状况以及对构造体数据的正确引用。思索与练习构造体与共用体 第二讲内容说明主要内容重点难点举例结论说明引例1.构造体变量在函数中的应用2.利用构造体变量构成链表3.共用体通过举例说明定义构造体变量的指针。在主函数中声明了struct student类型,然后定义struct student类型的变量stu_1又定义了一个指针变量p它指向一个struct student类型的数据。1.用指针处理链表指向
16、构造体类型数据的指针;用指针处理链表3.构造变量在函数中的应用在C语言中,允许构造变量的成员,构造变量的整体和构造变量的地址做为实参传递给相应的形参。(1)向函数传递构造变量的成员 构造变量的成员作实参构造变量的成员可以是一般变量,数组或指针变量,它们做实参时的状况同以前七,八,九章所讲。(2)向函数传递构造变量 构造变量整体作实参单向数值传递接收者(形参)为同类型的构造变量执行时,系统会为形参开拓同样数量的内存空间来存放接收到的数据 不会影响对应的实参中的各成员值.函数返回值可以是以下状况,但通常为1):1)构造变量整体例: P195 例14.2 2)某成员变量的值3)无返回值(3)向函数传
17、递构造变量地址 构造变量的地址作实参单向地址传递接收者(形参)为同构造类型的指针变量执行时, 会影响对应的实参中的各成员值返回值可以是以下状况,但通常为1)和2):1)无返回值例1: P195 例14.1 ; 例2: P196 例:14.42)构造变量的地址例: P196 例14.33)某成员变量的值4)构造变量整体引言举例注释举例4.利用构造变量构成链表(1)介绍一种特别的构造变量在构造体中含有指向本构造变量或同类型构造变量的成员例: struct node int data;struct node *next;struct node a,b,c; 从这个构造类型的说明和构造变量的定义可以看
18、出:1)成员变量next是指向struct node这种构造类型的指针;2)a,b,c分别为struct node构造类型的变量. 此时系统会分别为a,b,c随机开拓内存空间,如下图:a.data a.nextb.data b.next c.data c.next由于成员变量next是指向struct node这种构造类型的指针,所以做如下操作:a.next=&b;b.next=&c;结果如下图:a.data a.nextb.data b.next c.data c.next这样就把构造变量a,b,c连接到了一起,形成了一个链表.这里的每个构造变量被称作链表中的结点,每个结点由两局部构成:1)
19、数据域(data) 用来存放当前结点的数值;2)指针域(next) 用来存储下一个结点的地址.(2)静态链表与动态链表1)静态链表在上面的介绍中,链接在一起的每个构造变量(结点)a,b,c都是由系统开拓了固定的不连续的内存单元,在程序执行过程中,不行能人为地安排和释放这些内存单元.从这个角度动身,这种链表被称为静态链表.2)动态链表静态链表可能存在浪存储空间的问题,若在程序执行过程中,利用动态安排函数,依据须要随时为结点开拓内存空间,不再须要时随时释放结点所占用的内存空间,就能比拟合理的利用了内存了.这样形成的链表中的每个内存单元都是由动态存储安排获得的,故称这样的链表为动态链表.下面就介绍最
20、常见的动态链表: 带头结点的单链表.左侧是一个简洁的链表构造head指向第一个元素,第一个元素又指向第二个元素直到最终一个元素,该元素不在指向其它元素,它称为“表尾”。对结点num和score成员赋值。思索举例举例 (3)带头结点的单链表什么是单链表和带头结点的单链表 如下图所示:head/98 10头指针 头结点 尾结点说明:1)用一个头指针head来指明链表的起始位置(即链表第一个结点的地址)2)设置一个头结点,这个结点的数据域中不存放数据(也可以不设置);3)链表的尾结点不存放随意结点的地址值,置成0(NULL)值.这样的链表中,每个结点没有自己的名字,但每个结点有一个指针域,用来存放下
21、一个结点的地址,因此,这种链表只能从前一结点找到后一结点,故称为单链表.一般运用单链表时,常含有头结点,故称为带有头结点的单链表.由以上图示可以看出,单链表的每个结点由两个成员变量组成:一个是整型的成员变量,一个是指向自身构造类型的指针类型成员变量.所以,结点的类型说明如下:struct slistint data;struct slist *next;typedef sturct slist SLIST;下面介绍单链表这种数据构造的相关操作:1)建立带有头结点的单链表建立空单链表: head/0头指针 头结点主要语句如下:SLIST *h, *s;h=(SLIST *)malloc(size
22、of(SLIST);s=(SLIST *)malloc(sizeof(SLIST);h-next=s;s-next=0建立非空单链表:建立非空单链表主要操作步骤如下:.读取数据;.生成新结点;.将数据存入结点的成员变量中;.将新结点插入到链表中.重复以上操作直至完毕.将结点a,b,c的起始地址分别赋值。此链表属于静态链表。开拓一个新单元图示举例举例 2)依次访问单链表中各结点的数据参考: P201 例 14.73)在单链表中插入结点 phead/98 10头指针 头结点 尾结点 s12主要操作步骤如下:.生成所要插入的新结点;.确定插入的位置;.将新结点插入到链表中.在当前指针p所指结点后插入
23、一个新结点:主要语句如下:SLIST *s;s=(SLIST *)malloc(sizeof(SLIST);s-data=x;s-next=p-next;p-next=s;s-next=0在当前指针p所指结点前插入一个新结点:参考: P200 例14.63)删除单链表中的结点 qhead/98 10头指针 头结点 尾结点主要操作步骤如下:.找到待删结点的前趋结点;.删除要删除的结点例:删除指针q所指结点的后继结点:主要语句如下:SLIST *p;p=q-next;q-next=p-next;free(p);从动态链表中删除一个结点,并不是真正从内存中把它抹掉,而是把它从链表中分别出来,只是撤消
24、原来的链接关系。为了可以做到正确的插入,必需解决两个问题:一是怎样找到插入的位置,二是怎样实现插入。 举例比拟举例七、共用体共用体也称为共同体或结合体.1.共用体类型的说明和变量定义(union) 共用体也是一种新的数据类型,共用体的说明和共用体变量的定义与构造体非常相像,只是所运用的关键字不同,构造体为struct,而共用体为union.一般形式为: union 共用体名 数据类型1 成员名1; 数据类型2 成员名2; .数据类型n 成员名n; 共用体变量名;共用体变量运用时,系统按其成员变量中占用内存字节数最多者安排内存.然后共同体中的若干个成员变量公用这一个内存位置, 该内存位置中实时更
25、新和保存程序执行时为共用体变量中的某成员赋值的数据.即在不同的时间保存不同的数据类型和不同长度的变量。下面举例说明:union un_1 int i; float x; s;在共用体变量s中, 对应的成员整型i和浮点型x公用同一内存位置.如下图: s.xs.i 2个字节2个字节高位 低位说明:1)全部成员公用一段存储区sizeof(union un_1)2)全部成员首地址一样&s=&s.i=&s.x3)若想定义变量时初始化,只能对第一个成员进展,且要对初值化数据用括起来. union un_1 int i; float x; s=12;定义共用体类型变量的三种形式2.共用体变量的引用 共用体变量的引用的方法与构造一样,依旧是三种形式。共用体变量名.成员名适用于一般共用体变量和共用体数组变量共用体指针变量名-成员名 (*共用体指针变量名).成员名适用于指向共用体类型的指针变量3.构造体和共用体的区分1)构造体和共用体都是由多个不同的数据类型成员组成,但在任何同一时刻,共用体中只存放了一个被选中的成员,而构造体中,全部成员都存在;2)对于共用体的不同成员赋值,将会对原有成员值重写,原来成员的值就不存在了,而对于构造的不同成员赋值是互不影响的.小结思索与练习
限制150内