目录
一、联合体共用体概念引入
-
有时候同一个内存空间存放类型不同,不同类型的变量共享一块空间
-
结构体元素有各自单独空间
-
共用体元素共享空间,空间大小有最大类型确定
1.1 定义一个联合体:
union Test
{
int idata;
char cdata;
double ddata;
};
1.2 定义一个联合体变量:
#include <stdio.h>
union Test
{
int idata;
char cdata;
double ddata;
};
int main()
{
union Test u1; //定义一个联合体变量
return 0;
}
1.3 联合体和结构体很像,但是有区别:
#include <stdio.h>
struct TestT //定义一个结构体
{
int idata;
char cdata;
double ddata;
};
union TestU //定义一个联合体
{
int idata;
char cdata;
double ddata;
};
int main()
{
struct TestT t1; //定义一个结构体变量
union TestU u1; //定义一个联合体变量
printf("结构体t1的大小是:%d\n",sizeof(t1)); //计算结构体t1的大小
printf("联合体u1的大小是:%d\n",sizeof(u1)); //计算联合体u1的大小
//查看结构体没一个成员变量的内存地址
printf("idata = %p\n",&t1.idata);
printf("cdata = %p\n",&t1.cdata);
printf("ddata = %p\n",&t1.ddata);
//查看联合体每一个成员变量的内存地址
printf("idata = %p\n",&u1.idata);
printf("cdata = %p\n",&u1.cdata);
printf("ddata = %p\n",&u1.ddata);
return 0;
}
/*程序运行结果:
E:\code\一阶段C语言\第九章_联合体共用体>gcc demo_union.c
E:\code\一阶段C语言\第九章_联合体共用体>a.exe
结构体t1的大小是:16
联合体u1的大小是:8
idata = 000000000061FE10
cdata = 000000000061FE14
ddata = 000000000061FE18
idata = 000000000061FE08
cdata = 000000000061FE08
ddata = 000000000061FE08
*/
-
虽然联合体和结构体看着很像,但是不一样,是有区别的
-
结构体的大小:
-
由于存储变量地址对齐的问题,结构体大小计算必须满足两条原则:
一、结构体成员的偏移量必须是成员大小的整数倍
二、结构体大小必须是所有成员大小的整数倍
-
联合的所有成员引用的是内存中的相同位置,以最大的成员的内存长度作为union的内存大小
-
联合体虽然可以有多个成员,但同一时间只能存放其中一种
二、共用体注意数据覆盖问题
-
结构体元素互不影响,共用体赋值会导致覆盖
#include <stdio.h>
struct TestT
{
int idata;
char cdata;
double ddata;
};
union TestU
{
int idata;
char cdata;
int ddata;
};
int main()
{
struct TestT t1;
union TestU u1;
printf("结构体t1的大小是:%d\n",sizeof(t1));
printf("联合体u1的大小是:%d\n",sizeof(u1));
t1.idata = 10;
t1.cdata = 'c';
t1.ddata = 2.3;
printf("idata = %p,%d\n",&t1.idata,t1.idata);
printf("cdata = %p,%c\n",&t1.cdata,t1.cdata);
printf("ddata = %p,%.2lf\n",&t1.ddata,t1.ddata);
u1.idata = 10;
u1.cdata = 'c';
u1.ddata = 20;
printf("idata = %d\n",u1.idata); //联合体数据会被覆盖
printf("idata = %p\n",&u1.idata);
printf("cdata = %p\n",&u1.cdata);
printf("ddata = %p\n",&u1.ddata);
return 0;
}
/*
E:\code\一阶段C语言\第九章_联合体共用体>gcc demo_union.c
E:\code\一阶段C语言\第九章_联合体共用体>a.exe
结构体t1的大小是:16
联合体u1的大小是:4
idata = 000000000061FE10,10
cdata = 000000000061FE14,c
ddata = 000000000061FE18,2.30
idata = 20
idata = 000000000061FE0C
cdata = 000000000061FE0C
ddata = 000000000061FE0C
*/
三、共用体开发案例
例题:有若干个人员的数据,其中有学生和老师。学生的数据中包括:年龄、姓名、号码、性别、职业、班级,老师数据包括:年龄、姓名、号码、性别、职业、科目,要求用同一个表格来处理:
#include <stdio.h>
struct Person
{
int age;
char name[32];
char telephone[32];
char sex[12];
char zhiYe;
union{
int class;
char keMu[12];
}mes;
};
int main()
{
struct Person p[2];
int i;
for(i=0; i<2; i++){
printf("情输入职业:t代表老师,s代表学生\n");
scanf("%c",&p[i].zhiYe);
if(p[i].zhiYe == 's'){
printf("请输入学生的年龄:\n");
scanf("%d",&p[i].age);
printf("请输入学生的名字:\n");
scanf("%s",&p[i].name);
printf("请输入学生的电话:\n");
scanf("%s",&p[i].telephone);
printf("请输入学生的性别:\n");
scanf("%s",&p[i].sex);
printf("请输入学生的班级:\n");
scanf("%d",&(p[i].mes.class));
}else{
printf("请输入老师的年龄:\n");
scanf("%d",&p[i].age);
printf("请输入老师的名字:\n");
scanf("%s",&p[i].name);
printf("请输入老师的电话:\n");
scanf("%s",&p[i].telephone);
printf("请输入老师的性别:\n");
scanf("%s",&p[i].sex);
printf("请输入老师的科目:\n");
scanf("%s",&(p[i].mes.keMu));
}
getchar();
}
for(i=0; i<2; i++){
if(p[i].zhiYe == 's'){
printf("学生的信息是:\n");
printf("年龄:%d,名字:%s,电话:%s,性别:%s,班级:%d\n", \
p[i].age,p[i].name,p[i].telephone,p[i].sex,p[i].mes.class);
}else{
printf("老师的信息是:\n");
printf("年龄:%d,名字:%s,电话:%s,性别:%s,科目:%s\n", \
p[i].age,p[i].name,p[i].telephone,p[i].sex,p[i].mes.keMu);
}
}
return 0;
}
/*
E:\code\一阶段C语言\第九章_联合体共用体>gcc demo_union_ex.c
E:\code\一阶段C语言\第九章_联合体共用体>a.exe
情输入职业:t代表老师,s代表学生
s
请输入学生的年龄:
21
请输入学生的名字:
shiyaho
请输入学生的电话:
19563523860
请输入学生的性别:
男
请输入学生的班级:
4
情输入职业:t代表老师,s代表学生
t
请输入老师的年龄:
35
请输入老师的名字:
chenlichen.
请输入老师的电话:
666666666666
请输入老师的性别:
男
请输入老师的科目:
linux
学生的信息是:
年龄:21,名字:shiyaho,电话:19563523860,性别:男,班级:4
老师的信息是:
年龄:35,名字:chenlichen.,电话:666666666666,性别:男,科目:linux
*/
四、枚举类型介绍
4.1 什么是枚举类型:
-
如果一个变量只有几种可能的值,比如星期几:Monday、Tuesday、Wednesday、Thursday、Friday、Saturday、Sunday
4.2 怎么定义一个枚举类型:
enum WeekDay {Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday};
-
列表中的名字可以自己定义,无需像变量一样去申请
-
C编译器把它当成常量处理,也称枚举常量
4.3 定义一个枚举类型变量:
4.3.1 枚举类型变量定义方法一:
#include <stdio.h>
enum WeekDay {Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday};
int main()
{
enum WeekDay w; //定义一个枚举类型变量
return 0;
}
4.3.2 枚举类型变量定义方法二:
#include <stdio.h>
enum WeekDay {Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday}w1,w2;
int main()
{
return 0;
}
4.4 枚举变量保存枚举常量的值:
4.4.1 只限于枚举列表的几种情况:
/*
只限于枚举列表当中的几种情况,其他情况不行
*/
#include <stdio.h>
enum WeekDay {Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday};
int main()
{
enum WeekDay w1;
w = ttt;
printf("w = %d\n",w);
return 0;
}
/*
E:\code\一阶段C语言\第九章_联合体共用体>gcc demo_enum.c
demo_enum.c: In function 'main':
demo_enum.c:9:6: error: 'ttt' undeclared (first use in this function)
w = ttt;
^~~
demo_enum.c:9:6: note: each undeclared identifier is reported only once for each function it appears in
*/
4.4.2 枚举列表的值默认从0开始:
#include <stdio.h>
enum WeekDay {Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday};
int main()
{
enum WeekDay w;
w = Monday;
printf("w = %d\n",w);
return 0;
}
/*
E:\code\一阶段C语言\第九章_联合体共用体>gcc demo_enum.c
E:\code\一阶段C语言\第九章_联合体共用体>a.exe
w = 0
*/
-
枚举列表的值默认从0开始,虽然瞅着像变量名,但是它不能被赋值
4.4.3 可以指定枚举列表中数的值:
#include <stdio.h>
enum WeekDay {Monday,Tuesday,Wednesday = 8,Thursday,Friday,Saturday,Sunday};
int main()
{
enum WeekDay w;
w = Wednesday;
printf("w = %d\n",w);
return 0;
}
/*
E:\code\一阶段C语言\第九章_联合体共用体>gcc demo_enum.c
E:\code\一阶段C语言\第九章_联合体共用体>a.exe
w = 8
*/
4.4.4 可以直接忽略enum后面的名字,定义枚举变量:
#include <stdio.h>
enum WeekDay {Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday}w1,w2;
int main()
{
w1 = Monday;
w2 = Tuesday;
printf("w1 = %d\n",w1);
printf("w2 = %d\n",w2);
return 0;
}
/*
E:\code\一阶段C语言\第九章_联合体共用体>gcc demo_enum.c
E:\code\一阶段C语言\第九章_联合体共用体>a.exe
w1 = 0
w2 = 1
*/
五、typedef关键字
5.1 typedef关键字介绍:
-
typedef关键字的作用:给已有的变量类型起一个新的名字
#include <stdio.h>
typedef char ziFu;
typedef int zhengShu;
typedef double xiaoShu;
int main()
{
ziFu cdata = 'c';
printf("cdata = %c\n",cdata);
zhengShu idata = 10;
printf("idata = %d\n",idata);
xiaoShu fdata = 2.3;
printf("fdata = %.2lf\n",fdata);
return 0;
}
/*
E:\code\一阶段C语言\第九章_联合体共用体>gcc demo_typedef.c
E:\code\一阶段C语言\第九章_联合体共用体>a.exe
cdata = c
idata = 10
fdata = 2.30
*/
-
咱们就是举一个例子,这种用法不怕被你们主管打死嘛哈哈
-
在单片机中常用的做法
/*在单片机中经常这样使用*/
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
5.2 typedef关键字和结构体配合应用:
-
typedef一般配合结构体使用,也是一种便捷,不要每次都以struct开头
5.2.1 typedef和结构体配合一:
#include <stdio.h>
struct Test
{
int idata;
char cdata;
};
typedef struct Test T;
int main()
{
T t1; //定义一个结构体变量
t1.idata = 10;
t1.cdata = '#';
printf("idata = %d,cdata = %c\n",t1.idata,t1.cdata);
return 0;
}
/*
E:\code\一阶段C语言\第九章_联合体共用体>gcc demo_typedef.c
E:\code\一阶段C语言\第九章_联合体共用体>a.exe
idata = 10,cdata = #
*/
5.2.2 typedef和结构体配合二:
#include <stdio.h>
typedef struct
{
int idata;
char cdata;
}Demo;
int main()
{
Demo d;
d.idata = 10;
d.cdata = '#';
printf("idata = %d,cdata = %c\n",d.idata,d.cdata);
return 0;
}
/*
E:\code\一阶段C语言\第九章_联合体共用体>gcc demo_typedef.c
E:\code\一阶段C语言\第九章_联合体共用体>a.exe
idata = 10,cdata = #
*/
5.3 typedef和结构体案例:
#include <stdio.h>
typedef struct
{
int num;
int age;
char name[32];
char sex[12];
char addr[32];
}Person,*pPerson;
void printInof(Person p)
{
printf("%d号姐姐是:年龄:%d,名字:%s,性别:%s,地址:%s\n",p.num,p.age,p.name,p.sex,p.addr);
}
void printInof2(pPerson pp)
{
printf("%d号姐姐是:年龄:%d,名字:%s,性别:%s,地址:%s\n",pp->num,pp->age,pp->name,pp->sex,pp->addr);
}
void printInof3(Person *p)
{
printf("%d号姐姐是:年龄:%d,名字:%s,性别:%s,地址:%s\n",p->num,p->age,p->name,p->sex,p->addr);
}
int main()
{
Person m1 = {1,19,"莉莉","女","重庆"};
Person m2 = {2,20,"美美","女","成都"};
Person m3 = {3,22,"小露","女","永州"};
printInof(m1);
printInof(m2);
printInof(m3);
pPerson pp1 = &m1;
pPerson pp2 = &m2;
pPerson pp3 = &m3;
printInof2(pp1);
printInof2(pp2);
printInof2(pp3);
Person *p1 = &m1;
Person *p2 = &m2;
Person *p3 = &m3;
printInof3(p1);
printInof3(p2);
printInof3(p3);
return 0;
}
/*
E:\code\一阶段C语言\第九章_联合体共用体>gcc demo_typedef_struct_ex.c
E:\code\一阶段C语言\第九章_联合体共用体>a.exe
1号姐姐是:年龄:19,名字:莉莉,性别:女,地址:重庆
2号姐姐是:年龄:20,名字:美美,性别:女,地址:成都
3号姐姐是:年龄:22,名字:小露,性别:女,地址:永州
1号姐姐是:年龄:19,名字:莉莉,性别:女,地址:重庆
2号姐姐是:年龄:20,名字:美美,性别:女,地址:成都
3号姐姐是:年龄:22,名字:小露,性别:女,地址:永州
1号姐姐是:年龄:19,名字:莉莉,性别:女,地址:重庆
2号姐姐是:年龄:20,名字:美美,性别:女,地址:成都
3号姐姐是:年龄:22,名字:小露,性别:女,地址:永州
*/