联合体/共用体、枚举、typedef

目录

一、联合体共用体概念引入

1.1 定义一个联合体:

1.2 定义一个联合体变量:

1.3 联合体和结构体很像,但是有区别:

二、共用体注意数据覆盖问题

三、共用体开发案例

四、枚举类型介绍

4.1 什么是枚举类型:

4.2 怎么定义一个枚举类型:

4.3 定义一个枚举类型变量:

        4.3.1 枚举类型变量定义方法一:

        4.3.2 枚举类型变量定义方法二:

4.4 枚举变量保存枚举常量的值:

        4.4.1 只限于枚举列表的几种情况:

        4.4.2 枚举列表的值默认从0开始:

        4.4.3 可以指定枚举列表中数的值:

        4.4.4 可以直接忽略enum后面的名字,定义枚举变量:

五、typedef关键字

5.1 typedef关键字介绍:

5.2 typedef关键字和结构体配合应用:

        5.2.1 typedef和结构体配合一:

        5.2.2 typedef和结构体配合二:

5.3 typedef和结构体案例:


一、联合体共用体概念引入

  • 有时候同一个内存空间存放类型不同,不同类型的变量共享一块空间

  • 结构体元素有各自单独空间

  • 共用体元素共享空间,空间大小有最大类型确定

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,名字:小露,性别:女,地址:永州
*/

猜你喜欢

转载自blog.csdn.net/weixin_54859557/article/details/129353238