C语言学习记录——联合体(共用体、特点、用法、联合体大小计算)

简介: C语言学习记录——联合体(共用体、特点、用法、联合体大小计算)

联合体的概念

联合体与之前的结构体、位段、枚举一样,也是自定义类型的一种。这种类型定义的变量也包含一系列的成员,特征是这些成员共用同一块空间(所以联合体也叫共用体)。

联合变量的定义

#include <stdio.h>
//联合类型的建立
union U
{
    char i;
    int n;
};
int main()
{
    //联合变量的定义
    union U un;
    //联合变量大小的计算
    printf("%u\n", sizeof(un));
    return 0;
}

联合体的特点

联合体的成员是共用一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联合体至少得有能力保存最大的那个成员)。

我们打印出联合变量中成员的地址,具体看一下

#include <stdio.h>
union UN
{
    char c1;
    char c2;
    int n;
    double d;
}un;
int main()
{
    printf("c1 = %p\n", &(un.c1));
    printf("c2 = %p\n", &(un.c2));
    printf("n = %p\n", &(un.n));
    printf("d = %p\n", &(un.d));
    return 0;
}

运行结果:

其中每个成员都是共用一块内存的,一旦修改了一个成员的值,其他成员的值也会改变。

小结:在同一时间,联合体的成员只能使用一个

联合体的用法

联合体这么独特,那么我们如何使用,又要在什么情况下使用联合体呢?

之前学习过,写一个函数:判断系统是大端存储还是小端存储,接下来就通过这个函数示例一下联合体的使用。

原来的写法

#include <stdio.h>
int check_sys()
{
    int i = 1;
    if (*(char*)&i == 1)
        return 1;//小端存储
    else
        return 0;//大端存储
}
int main()
{
    int ret = check_sys();
    if (ret == 1)
        printf("小端存储\n");
    else
        printf("大端存储\n");
    return 0;
}

这个写法的思路是:

观察(int*)i和(char*)i,它们是同一个变量,但占用着不同的大小。如果给他们改一下名字

所以我们用联合体的方式来解决这个函数

#include <stdio.h>
int check_sys()
{
    union U
    {
        char c;
        int i;
    }u;
    u.i = 1;
    return u.c;
    //返回1为小端存储
    //返回0为大端存储
}
int main()
{
    if (check_sys() == 1)
        printf("小端存储\n");
    else
        printf("大端存储\n");
    return 0;
}


小结:当需要使用的成员允许使用共用一块空间,且共用一块空间时不会影响设计和使用的时候可以运用联合体来实现。



小结:当需要使用的成员允许使用共用一块空间,且共用一块空间时不会影响设计和使用的时候可以运用联合体来实现。

联合体大小的计算

当最大成员大小不是最大对齐数的整数倍时,就要对齐到最大对齐数的整数倍。

也就是说,联合体的大小也存在着对齐的情况。

学习过结构体的内存对齐,联合体大小的计算举个例子就很好理解了

#include <stdio.h>
union U
{
    char a[5];
    int i;
};
int main()
{
    printf("%u\n", sizeof(union U));
    return 0;
}

运行结果:

小练习

//计算下列联合体类型的大小
union U1
{
    short a[5];
    int i;
};
union U2
{
    char c;
    char arr[5];
};
union U3
{
    char c;
    char arr[10];
    int i;
    double d;
};


答案:

目录
相关文章
|
4月前
|
IDE 编译器 开发工具
【C语言】全面系统讲解 `#pragma` 指令:从基本用法到高级应用
在本文中,我们系统地讲解了常见的 `#pragma` 指令,包括其基本用法、编译器支持情况、示例代码以及与传统方法的对比。`#pragma` 指令是一个强大的工具,可以帮助开发者精细控制编译器的行为,优化代码性能,避免错误,并确保跨平台兼容性。然而,使用这些指令时需要特别注意编译器的支持情况,因为并非所有的 `#pragma` 指令都能在所有编译器中得到支持。
346 41
【C语言】全面系统讲解 `#pragma` 指令:从基本用法到高级应用
|
7月前
|
C语言
C语言判断逻辑的高阶用法
在C语言中,高级的判断逻辑技巧能显著提升代码的可读性、灵活性和效率。本文介绍了六种常见方法:1) 函数指针,如回调机制;2) 逻辑运算符组合,实现复杂条件判断;3) 宏定义简化逻辑;4) 结构体与联合体组织复杂数据;5) 递归与分治法处理树形结构;6) 状态机管理状态转换。通过这些方法,可以更高效地管理和实现复杂的逻辑判断,使代码更加清晰易懂。
301 88
|
4月前
|
存储 算法 安全
C 语言中的位运算:挖掘底层计算的高效力量
位运算是C语言中直接操作二进制位的一种技术,能高效处理底层数据,广泛应用于优化算法、硬件编程等领域,是掌握C语言高级特性的关键之一。
|
5月前
|
存储 算法 C语言
C语言中常见的字符串处理技巧,包括字符串的定义、初始化、输入输出、长度计算、比较、查找与替换、拼接、截取、转换、遍历及注意事项
本文深入探讨了C语言中常见的字符串处理技巧,包括字符串的定义、初始化、输入输出、长度计算、比较、查找与替换、拼接、截取、转换、遍历及注意事项,并通过案例分析展示了实际应用,旨在帮助读者提高编程效率和代码质量。
256 4
|
6月前
|
存储 C语言 C++
深入C语言,发现多样的数据之枚举和联合体
深入C语言,发现多样的数据之枚举和联合体
深入C语言,发现多样的数据之枚举和联合体
|
6月前
|
C语言
教你快速理解学习C语言的循环与分支
教你快速理解学习C语言的循环与分支
32 0
|
6月前
|
存储 编译器 Linux
深入理解 C 语言中的联合体
深入理解 C 语言中的联合体
|
8月前
|
存储 缓存 编译器
【C语言篇】scanf和printf万字超详细介绍(基本加拓展用法)(下篇)
scanf处理⽤⼾输⼊的原理是,⽤⼾的输⼊先放⼊缓存,等到按下回⻋键后,按照占位符对缓存进⾏解读。 解读⽤⼾输⼊时,会从上⼀次解读遗留的第⼀个字符开始,直到读完缓存,或者遇到第⼀个不符合条件的字符为⽌。
245 2
|
8月前
|
存储 编译器 C语言
【C语言篇】自定义类型:联合体和枚举详细介绍
像结构体⼀样,联合体也是由⼀个或者多个成员构成,这些成员可以不同的类型。
70 1
|
8月前
|
存储 C语言
【C语言篇】scanf和printf万字超详细介绍(基本加拓展用法)(上篇)
printf 的作⽤是将参数⽂本输出到屏幕。它名字⾥⾯的 f 代表 format (格式化),表⽰可以定制输出⽂本的格式。
143 1
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等