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;
};


答案:

目录
相关文章
|
18天前
|
测试技术 C语言
数据结构学习记录——树习题—Tree Traversals Again(题目描述、输入输出示例、解题思路、解题方法C语言、解析)
数据结构学习记录——树习题—Tree Traversals Again(题目描述、输入输出示例、解题思路、解题方法C语言、解析)
14 1
|
2天前
|
C语言
C语言-----计算两个int(32位)整数m和n的二进制表达中,有多少个位(bit)不同?
C语言-----计算两个int(32位)整数m和n的二进制表达中,有多少个位(bit)不同?
|
2天前
|
Serverless C语言
C语言----递归函数,计算一个非负整数的数字之和
C语言----递归函数,计算一个非负整数的数字之和
11 0
|
2天前
|
C语言
C语言---试计算在区间1 到n 的所有整数中,数字x(0 ≤ x ≤ 9)共出现了多少次?
C语言---试计算在区间1 到n 的所有整数中,数字x(0 ≤ x ≤ 9)共出现了多少次?
|
2天前
|
C语言
C语言---计算三角形的周长和面积--海伦公式
C语言---计算三角形的周长和面积--海伦公式
|
3天前
|
C语言
C语言-----计算1 / 1 - 1 / 2 + 1 / 3 - 1 / 4 + 1 / 5 …… + 1 / 99 - 1 / 100 的值,打印出结果
C语言-----计算1 / 1 - 1 / 2 + 1 / 3 - 1 / 4 + 1 / 5 …… + 1 / 99 - 1 / 100 的值,打印出结果
|
4天前
|
程序员 C语言
C语言memcpy()函数用法
C语言memcpy()函数用法
6 0
|
4天前
|
C语言
C语言strcpy函数用法
C语言strcpy函数用法
16 0
|
18天前
|
存储 算法 安全
数据结构学习记录——图应用实例-拯救007(问题描述、解题思路、伪代码解读、C语言算法实现)
数据结构学习记录——图应用实例-拯救007(问题描述、解题思路、伪代码解读、C语言算法实现)
16 0
|
18天前
|
程序员 C语言 C++
C语言学习记录——动态内存习题(经典的笔试题)、C/C++中程序内存区域划分
C语言学习记录——动态内存习题(经典的笔试题)、C/C++中程序内存区域划分
29 0