内容正文:
7.5节:共用体
编程语言基础——C语言
同步精品课堂
高教版(第5版)
掌握国家标准《机械制图》中有关图幅、比例、字体图线等基本规定。
教学目标
一
03
熟悉共用体变量的引用方式,掌握通过成员运算符"."访问共用体成员的语法规则,能够正确引用共用体变量的各个成员
了解共用体类型数据的特点,理解共用体成员的共享内存特性,能够编写简单的程序应用共用体解决实际问题
04
掌握定义共用体变量的一般形式,能够正确使用三种方式定义共用体变量
02
理解共用体的基本概念,能够准确描述共用体与结构体的本质区别,掌握共用体在内存中的存储特点
01
教学重难点
二
03
共用体变量的引用方式,理解共用体成员的访问规则,避免在编程中出现常见错误
共用体类型数据的特点及其实际应用,特别是例题中处理学生和教师不同类型数据时的共用体设计思路
04
共用体变量的定义方法,掌握三种定义方式的语法规则和适用场景
02
共用体的基本概念,特别是共用体与结构体的本质区别,理解共用体在内存中的存储方式
01
导入新课
三
一个变量,多种身份——共用体的神奇之处
struct student {
long id;
char name[20];
float score;
};
union data {
long id;
char name[20];
float score;
};
问题1: 如果有一个盒子,同一时刻只能存放学号、姓名或成绩中的一种,如何定义?
问题2: 如何用最节省内存的方式存储学生或教师的不同类型数据?
思考: 结构体能否满足这种"多选一"的需求?
新知讲授
四
共用体是C语言中一种特殊的数据类型,它允许不同类型的数据共享同一块内存空间。与结构体不同,共用体的所有成员共享内存,同一时刻只能存储其中一个成员的值。本节将介绍共用体的基本概念、变量的定义和引用方法,以及共用体数据的特点。通过处理学生和教师数据的实例,我们将学习如何利用共用体实现内存的高效利用,解决"多选一"类型数据的存储问题。
概述
新知讲授
四
知识点1:共用体的概念
1、共用体的概念
使几个不同类型的变量共享同一段内存的结构,称为 “共用体”类型的结构。
例如:
可以把一个整型变量、一个字符型变量、一个实型变量放在同一个地址开始的内存单元中。
1000地址
整型
i 变量
字符变量ch
实型 变 量 f
这3个变量在内存中占的字节数不同,但都从同一地址开始(图中设地址为1000)存放,也就是使用覆盖技术,几个变量互相覆盖。
新知讲授
四
知识点1:共用体的概念
2、定义共用体变量的一般形式
【一般形式】
union 共用体名
{ 类型名1 共用体成员名表1;
类型名2 共用体成员名表2;
……
类型名n 共用体成员名表n;
} ;
union
{
成员表列
} 变量表列;
union //没有定义共用体类型名
{ int i;
char ch;
float f;
}a,b,c;
新知讲授
四
知识点1:共用体的概念
2、定义共用体变量的一般形式
union 共用体名
{
成员表列
} 变量表列;
union Data
{ int i;
//表示不同类型的变量i,ch,f可以存放到同一段存储单元中
char ch;
float f;
}a,b,c; //在声明类型同时定义变量
union Data //声明共用体类型
{ int i;
char ch;
float f;
};
union Data a,b,c; //用共用体类型定义变量
union 共用体名
{
成员表列
};
union 共用体名 变量表列;
新知讲授
四
知识点1:共用体的概念
3、共用体的定义说明
(1)共用体变量的定义与结构体类似,可以把类型说明和变量定义放在一起,也可以分开,还可以直接定义共用体变量而不要共用体名。
union
{
成员表列
} 变量表列;
union 共用体名
{
成员表列
} 变量表列;
union 共用体名
{
成员表列
};
union 共用体名 变量表列;
新知讲授
四
知识点1:共用体的概念
3、共用体的定义说明
(2)共用体的含义与结构体不同,共用体中的所有成员均放在同一地址开始的存储空间中,使用覆盖方式共享存储单元。共用体所占存储空间的大小取决于占用存储空间最大的那个成员。而结构体所占存储空间等于所有成员所占存储空间大小的总和。
union data1
{ int a; //占4字节
float b;//占4字节
char c; //占1字节
}ua; //共用体变量ua占4字节
struct data2
{ int a; //占4字节
float b;//占4字节
char c; //占1字节
}ub; //结构体变量ub占9字节
结构体变量实际占12字节。
【思考】为什么结构体成员所占存储空间大小的总和为9字节,但实际分配却是12字节?
那么“共用体”是否有同样的情况呢?
新知讲授
四
知识点1:共用体的概念
3、共用体的定义说明
(3)共用体变量所占存储空间是按成员的最大数据类型来分配。共用体所占存储空间还必须是基本数据类型的整数倍,所以会产生字节填充。
union data1
{ int a; //占4字节
float b;//占4字节
char c; //占1字节
}ua; //共用体变量ua占4字节
union data2
{ int a; //占4字节
float b;//占4字节
char c; //占1字节
char name[5];//占5字节
}ub; //共用体变量ub占8字节
新知讲授
四
知识点2:共用体变量的引用方式
只有先定义了共用体变量才能引用它,但应注意,不能引用共用体变量,而只能引用共用体变量中的成员。
union Data
{ int i;
char ch;
float f;
}a,b,c;
a.i //引用共用体变量中的整型变量i
a.ch //引用共用体变量中的字符变量ch
a.f //引用共用体变量中的实型变量f
printf(″%d″,a);
printf(″%d″,a.i);
新知讲授
四
知识点3:共用体类型数据的特点
(1)同一个内存段可以用来存放几种不同类型的成员,但在每一瞬时只能存放其中一种,而不是同时存放几种。也就是说,每一瞬时只有一个成员起作用,其他的成员不起作用,即不是同时都存在和起作用。
union Data
{ int i;
char ch;
float f;
}a,b,c;
1000地址
整型变量i
字符变量ch
实型变量f
1字节 2字节 3字节 4字节
因为存储空间是多个不同类型成员共用的,所以同一瞬时内只有一个成员起作用。
新知讲授
四
知识点3:共用体类型数据的特点
(2)共用体变量中起作用的成员是最后一次被赋值的成员,在对共用体变量中的一个成员赋值后,原有变量存储单元中的值就被取代。
例如:
#include <stdio.h>
union Date
{ int i;
char ch;
float f;
}a;
main()
{ a.f=3.5;
a.ch=32;
a.i=97;
printf("%f
",a.f); //输出实数0.000000
printf("%c
",a.ch); //输出字符'a'
printf("%d
",a.i); //输出整数97
}
在引用共用体变量时应十分注意当前存放在共用体变量中的究竟是哪个成员。
新知讲授
四
知识点3:共用体类型数据的特点
(3)共用体变量的地址和它的各成员的地址都是同一地址。
(4)不能对共用体变量名赋值,也不能企图引用变量名来得到一个值。又不能在定义共用体变量时对它进行初始化。
(5)共用体类型可以出现在结构体类型定义中,也可以定义共用体数组。反之,结构体也可以出现在共用体类型定义中,数组也可以作为共用体的成员。
a=1; //不能对共用体变量赋值,赋给谁?
m=a; //企图引用共用体变量名以得到一个值赋给整型变量m
union Data a={33,'a',1.5};
#include <stdio.h>
union Date
{ int i;
char ch;
float f;
}a={33,'a',1.5};
union Data a={33};
新知讲授
四
知识点3:共用体类型数据的特点
例题:有若干个人员的数据,其中有学生和教师。学生的数据中包括: 姓名、号码、性别、职业、班级。教师的数据包括: 姓名、号码、性别、职业、职务。要求用同一个表格来处理。
新知讲授
四
知识点3:共用体类型数据的特点
例题:有若干个人员的数据,其中有学生和教师。学生的数据中包括: 姓名、号码、性别、职业、班级。教师的数据包括: 姓名、号码、性别、职业、职务。要求用同一个表格来处理。
#include <stdio.h>
struct //声明无名结构体类型
{ int num; //成员num(编号)
char name[10]; //成员name(姓名)
char sex; //成员sex(性别)
char job; //成员job(职业)
union //声明无名共用体类型
{ int clas; //成员clas(班级)
char position[10]; //成员position(职务)
}category; //成员category是共用体变量
}person[2]; //定义结构体数组person,有两个元素
新知讲授
四
知识点3:共用体类型数据的特点
int main()
{ int i;
for(i=0;i<2;i++)
{ printf("please enter the data of person:
");
scanf("%d %s %c %c",&person[i].num,person[i].name,&person[i].sex,&person[i].job);//输入前4项
if(person[i].job=='s') scanf("%d",&person[i].category.clas); //如是学生,输入班级
else if(person[i].job=='t')scanf("%s",person[i].category.position); //如是教师,输入职务
else printf("Input error!"); } //如job不是's'和't',显示“输入错误”
printf("
"); printf("No.namesex job class/position
");
for(i=0;i<2;i++)
{ if (person[i].job=='s') //若是学生
printf("%-6d%-10s%-4c%-4c%-10d
",
person[i].num,person[i].name,person[i].sex,person[i].job,person[i].category.clas);
else //若是教师
printf("%-6d%-10s%-4c%-4c%-10s
",
person[i].num, person[i].name,person[i].sex,person[i].job,person[i].category.position);
} }
师生互动
五
共用体角色扮演:你是学生还是教师?
师生互动
五
共用体角色扮演:你是学生还是教师?
任务1:定义共用体(3分钟) 任务2:数据录入(3分钟)
请设计一个共用体类型
能够存储学生和教师的所有信息
要求:使用三种定义方式分别实现 为角色1和角色2创建共用体变量
并正确初始化数据
任务3:身份识别(5分钟) 互动流程
如何判断一个共用体变量
存储的是学生还是教师信息?
请写出判断逻辑代码 分组扮演(每组3-4人,共11分钟):
每组选择两个角色进行处理
教师巡视指导
代码展示(每组2分钟):
展示共用体定义代码
演示数据录入和身份识别
随堂练习
六
1.关于共用体的说法,错误的是( )
A. 共用体可以包含不同类型的数据成员
B. 共用体成员共享同一段内存空间
C. 共用体的大小等于各成员大小之和
D. 共用体同一时间只能存储一个成员的值
答案:C
解析:共用体的大小等于最大成员的大小。
随堂练习
六
2.关于共用体变量定义,错误的是( )
A. union data u1;
B. union {int a; float b;} u2;
C. data u3;
D. union data u4 = {0};
答案:C
解析:缺少union关键字。
随堂练习
六
3.关于共用体成员访问,正确的是( )
A. u.a
B. u->a
C. u:a
D. u::a
答案:A
解析:共用体变量使用点运算符访问成员。
随堂练习
六
4.关于共用体说明,正确的是( )
A. 共用体定义不分配内存
B. 共用体定义时分配内存
C. 共用体变量定义时不能初始化
D. 共用体成员只能是基本数据类型
答案:A
解析:共用体定义只是声明类型,不分配内存。
随堂练习
六
5.关于共用体大小,说法正确的是( )
A. 等于各成员大小之和
B. 可能大于各成员大小之和
C. 等于最大成员的大小
D. 由编译器决定,无法确定
答案:C
解析:共用体大小等于最大成员的大小。
随堂练习
六
6.以下代码的输出是( )
#include <stdio.h>
union test {int a; char b;};
main() {
union test t;
printf("%d", sizeof(t));
}
答案:4
解析:int占4字节,char占1字节,共用体大小为4。
随堂练习
六
7.以下代码的输出是( )
#include <stdio.h>
union test {int a; char b;};
main() {
union test t = {0x41424344};
printf("%c", t.b);
}
答案:D
解析:小端模式下,低地址存储低字节。
随堂练习
六
8.关于共用体成员,正确的是( )
A. 成员名可以重复
B. 成员类型必须不同
C. 成员必须有名称
D. 成员可以是void类型
答案:C
解析:共用体成员必须有名称。
随堂练习
六
9. 执行以下程序的输出结果是( )
#include <stdio.h>
union data {int a; float b;};
void func(union data d) {
d.a = 10;
}
main() {
union data d = {0};
func(d);
printf("%d", d.a);
}
答案:0
解析:参数是值传递,不影响实参。
课堂小结
七
谢谢
EV录屏5.4.2软件录制
Lavf58.33.100
本视频由湖南一唯信息科技开发的EV录屏软件录制, www.ieway.cn
EV录屏5.4.2软件录制
Lavf58.33.100
本视频由湖南一唯信息科技开发的EV录屏软件录制, www.ieway.cn
EV录屏5.4.2软件录制
Lavf58.33.100
本视频由湖南一唯信息科技开发的EV录屏软件录制, www.ieway.cn
EV录屏5.4.2软件录制
Lavf58.33.100
本视频由湖南一唯信息科技开发的EV录屏软件录制, www.ieway.cn
$