• 【C语言基础】结构体中内嵌联合体|联合体中内嵌结构体


    📢:如果你也对机器人、人工智能感兴趣,看来我们志同道合✨
    📢:不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852
    📢:文章若有幸对你有帮助,可点赞 👍 收藏 ⭐不迷路🙉
    📢:内容若有错误,敬请留言 📝指正!原创文,转载请注明出处


    一、结构体中内嵌联合体

    1.1 意义

    使用结构体中内嵌联合体的好处是可以在一个数据结构中灵活地存储和处理不同类型的数据。下面列出了一些具体的好处:

    1. 节省内存:联合体的所有成员共享同一块内存,只有其中一个成员可以被有效地使用。这意味着内嵌联合体可以节省内存空间,尤其是当需要存储不同类型的数据时。

    2. 简化数据访问:通过使用内嵌联合体,可以在一个结构体中直接包含不同类型的成员,并根据需要访问相应的成员。这样可以简化数据的访问和操作过程,而不需要额外的指针或条件语句来切换不同的数据类型。

    3. 提高代码可读性:通过将相关的数据组织在结构体中,特别是在需要处理多种类型数据的情况下,可以提高代码的可读性和可维护性。逻辑上相关的数据可以打包在一个结构体中,使得代码更加清晰和易于理解。

    4. 便于扩展:使用内嵌联合体可以轻松地扩展数据结构,以支持新的数据类型。只需在联合体中添加新的成员,并相应地修改结构体定义,即可支持新的数据类型,而不会对现有的代码产生太大的影响。

    1.2 案例

    结构体中内嵌联合体,通过如下三步实现:
    1、先定义一个结构体,要求结构体内嵌共用体
    2、宏定义一个结构体指针,宏的名称为Reg1
    3、通过宏来更改结构体内的元素

    #include 
    
    int main()
    {	
    	//Case1:结构体中内嵌联合体
       //1、先定义一个结构体,要求结构体内嵌共用体
    	typedef struct 
    	{
    		unsigned int Value0 : 8;//设置位域为8bit
    		unsigned int Value1 : 8;
    		unsigned int Value2 : 8;
    		
    		//内嵌共用体
    		union MyUnion//无需typedef,也可以自定义
    		{
    			unsigned int All;
    
    		}bits;
    	}My_Reg;
    
    	//2、宏定义一个结构体指针,宏的名称为Reg1
    #define Add_BASE		(0x30000000)
    #define Reg1			((My_Reg *)Add_BASE)//强制转化为结构体指针
    
    	//3、通过宏来更改结构体内的元素
    	printf("YS_Struct占用的内存空间=%d", sizeof(My_Reg));
    	Reg1->Value0 =	1;
    	Reg1->bits.All = 2;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    二、联合体中内嵌结构体

    2.1 意义

    在联合体(Union)内嵌结构体(Struct)可以提供一些好处:

    1. 节省内存空间:共用体内部的成员共享同一块内存空间。当结构体成员中的字段不会同时使用时,可以共享内存以减少内存占用。这对于具有大量可能性但只能选择其中一个的情况非常有用。

    2. 数据组织和访问方便:使用结构体可以将多个相关字段组织在一起,使得数据的表示更为清晰和高效。通过共用体,可以将不同类型的结构体成员组合在一起,方便对它们进行访问和操作。

    3. 多样化的数据表示:共用体内的结构体成员可以具有不同的数据类型和字段,这使得可以根据需要灵活地选择合适的数据类型和结构布局。这种灵活性可用于处理多样化的数据表示需求。

    4. 代码简洁性:通过使用共用体内嵌结构体,可以减少冗余的代码,使代码更加简洁和易于理解。通过使用共用体和结构体,可以将复杂的数据类型和数据结构组织得更加紧凑和清晰。

    2.2 案例

    //Case2:联合体中内嵌结构体

    #include 
    
    int main()
    {	
    	//1、定义一个联合体
    	typedef union 
    	{
    		unsigned int Val0;
    		struct 
    		{
    			unsigned int Val1:5;
    			unsigned int Val2:8;
    
    		}bits;
    
    	}My_Union;
    
    	//2、宏定义这个联合体,为联合体指针
    #define Add_Base1	(0x40000000)
    #define Reg2	((My_Union*)Add_Base1)
    
    	//3、通过宏来更改结构体内的元素
    	Reg2->bits.Val1 = 3;
    	printf("Reg2->My_Struct.Val1=%d", Reg2->bits.Val1);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    位域的使用

    位域(Bit fields)是一种在结构体或联合体中进行位级操作的机制。它允许程序员将结构体的成员字段按照指定的位数进行定义,以节省内存空间。

    位域的定义使用冒号(:)和数字来表示字段的位数。例如,以下代码定义了一个使用位域的结构体:

    struct Flags {
        unsigned int flag1 : 1;
        unsigned int flag2 : 3;
        unsigned int flag3 : 4;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在上面的例子中,flag1占用1个位,flag2占用3个位,flag3占用4个位。

    通过使用位域,可以有效地利用内存空间并减少结构体的大小。然而,需要注意的是,位域的使用也有一些限制和注意事项:

    • 位域只能是无符号整数类型(如unsigned intunsigned char等)或者有符号整数类型(如intchar等),不能是浮点型、结构体或联合体。
    • 不同编译器对于位域的实现可能存在差异,因此在使用位域时要注意可移植性问题。
    • 对位域的访问速度可能比正常的整数访问慢,因为需要进行位操作。

    总之,位域是一种可以有效利用内存空间的机制,适用于某些特定的应用场景,但在使用时需要注意其限制和可移植性问题。
    在这里插入图片描述

  • 相关阅读:
    Android Studio的debug和release模式及签名配置
    程序员天天 CURD,怎么才能成长,职业发展的思考 ?
    【Vite】development、mock和production不同环境下的配置
    xatlas源码解析(七)
    jQuery表单选择器:快速选择<input>标签
    Linux_用户管理
    安装anaconda时控制台conda-version报错
    智能AI系统源码ChatGPT系统源码+详细搭建部署教程+AI绘画系统+已支持OpenAI GPT全模型+国内AI全模型
    做自媒体一个重要的问题就是:自己的定位是什么?
    细胞膜包裹精氨酸脱亚胺酶脂质纳米粒/融合细胞膜包裹尿酸酶/过氧化氢酶脂质纳米粒的研究
  • 原文地址:https://blog.csdn.net/weixin_51244852/article/details/133934377