C语言联合体详解

目录

联合体的简介

联合的定义

普通使用联合

不普通使用联合

位域介绍

结构体+联合体的使用

内存分析​编辑


联合体的简介

  • 联合体又叫共用体,联合体也是一种 户可自定义数据类型。
  • 不同于结构体成员一一它们在结构中都具有单独的内存位置。
  • 联合成员则共享同一个内存位置。 也就是说,联合中的所有成员都是从相同的内存地址开始。 因此,可以定义一个拥有许多成员的联合,但是同一时刻只能有一个成员允许含有一个值
  • 联合的内存大小:是最大的成员所占的内存大小。
  • 联合让程序员可以方便地通过不同方式使用同一个内存位置。

联合的定义

普通使用联合

联合的定义方式与结构是一样的,只是把关键字 struct 改成 union:

union tag
{
	member;
	...
};

下面的例子定义了一个名为Data的联合类型,它有3个成员: i、x和 str:

union Data
{
	int i;
	double x;
	char str[16];
}

union Data u = {.str = “LiuZhenJie”};

这段代码是创建了一个union Data类型的联合体, 名字叫 u ,然后给联合体中的str变量赋值为”LiuZhenJie”

不普通使用联合

位域介绍

结构体后方用冒号,是表示位域。

其表示形式为:

struct 位域结构名
{
	类型 位域名:位域长度
}

例如

struct  bit_struct
{
    int  bit1:3;
    int  bit2:5;
    int  bit3:7;
}data;
  • 其中bit_struct表示位域结构体 bit1、bit2、bit3表示对应的位域 data表示位域结构体定义的变量。
  • 整个位域结构体占用2个字节,bit1占3位,bit2占5位,bit1和bit2共用一个字节,bit3占7位,独占一个字节。

结构体+联合体的使用

如下代码,我们创建了一个 类型, 用来创建一个联合体,

  • 有一个长度为 11 的字符数组 info
  • 还有一个嵌套的结构体,结构体中包含一个长度为 10 的字符数组 name,以及两个位域成员age 占 7 位,gender 占 1 位。
  • 结构体有10字节用来存放名字,7bit用来存放 age , 1bit 用来定义 男 或女。 (这里的结构体没有声明名字,叫做匿名结构体
  • 结构体和 info共用11个字节的空间
typedef union 
{
	char info[11];
	struct 
	{
		char name[10];
		unsigned char age    :7;
		unsigned char gender :1;
	}
}union_PersonType;
  1. 定义un_Person 的 联合体:PersonType person;

  2. 我们可以直接对person联合体中的值进行赋值操作:

    person = {
    	.name   = "zhangsan",
    	.age    = 20,
    	.gender = 1;
    };
    

    验证: printf("name:%s age:%d gender:%d\\n",person.name, person.age, person.gender);

  3. 也可以通过别的方式过来(例如串口)

    • 定义一个11个成员的,char类型的数组,对char数组赋值:

    • char new_info[11] = {'z','h','a','n','g','s','a','n','0','0', (20<<1|1)}; //腾出一个bit放男女信息

    • 也能这么写:

      char new_info[11];
      strcpy(new_info, "zhangsan");
      new_info[10] = (20 << 1) | 1;
      //腾出一个bit放男女信息
      
    • 反正最终目的是先把变量存到new_info这个char类型的数组中。

    • 然后就可以把我们新的信息new_info,拷贝到联合体变量person中.

      memcpy(person.info, new_info, sizeof(new_info));

      • 这样前十个字节就相当于放到了结构体name的变量中。
      • 最后一个字节的最后一个bit位是用来记录 男(1)或女(0)的;
        • 前七个bit则是用来存放年龄的(7个bit若全为1,十进制为为254,不会又人能活这么久的!)。

    验证: printf("name:%s age:%d gender:%d\\n",person.name, person.age, person.gender);

内存分析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

L_Z_J_I

让孩子吃一顿免费的午餐吧!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值