不常见的小知识-联合体

举报
芒果_Mango 发表于 2022/03/28 10:23:20 2022/03/28
【摘要】 联合体(共用体) 联合类型的定义联合也是一种特殊的自定义类型,这种类型定义的变量也包含一系列的成员,特征是这些成员 共用一块内存空间(因此联合也叫共用体)//联合类型的声明union Un{ char c; int i ;};int main(){ union Un un; // 联合变量的定义 printf("%d\n",sizeeof(un)); //4}定义时的...

联合体(共用体)

联合类型的定义

联合也是一种特殊的自定义类型,这种类型定义的变量也包含一系列的成员,特征是这些成员 共用一块内存空间(因此联合也叫共用体)


//联合类型的声明
union Un
{
  	char c;
    int i ;
};
int main()
{
    union Un un;	// 联合变量的定义
    printf("%d\n",sizeeof(un));	//4
}

定义时的注意事项:成员后面记得跟分号,{}后面也要有分号,union Un这一整个是联合体类型,不能直接使用Un定义变量,或者计算联合体大小

sizeof(Un) //err

sizeof(union Un) //正解


联合的特点

联合的成员共用一块内存空间,且都从起始位置开始存放,这样一个联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)


union Un
{
    int i;
    char c;
};
int main()
{
     union Un un = {0};
    printf("%p\n",&(un.i));
    printf("%p\n",&(un.c));
    printf("%p\n",&un);
}

打印结果相同地址相同。


image-20220310223038632

成员都从第一个位置开始向后存放


结构体和联合体的区别

共同点:二者的访问方式,声明方式一样且二者都有内存对齐

不同点:联合体的成员共用同一块空间 ,改变某一个成员,其他的都会发生改变,

而结构体的每个成员都有独立空间互不影响


使用联合体判断大小端

大小端:二进制的字节序在内存中存放的顺序

int a = 1;	//0x 00 00 00 01
//     低地址----->高地址
//小端存放:01 00 00 00 低字节内容放在低地址处
//大端存放:00 00 00 01 
所以只要拿出第一个字节,判断是0还是1即可知道是小端还是大端

//法1:使用char*强转,只取第一个字节
int main()
{
    int a = 1;
    char* p =(char*)&a;
    if(*p == 1)
    {
        printf("小端\n");
    }
    else
    {
        printf("大端\n");
    }
    return 0;
}

优化:
int Check_DX()
{
    int a = 1;
    return *(char*)&a;
}
int main()
{
    int ret = Check_DX();
    if(ret == 1)
    {
        printf("小端\n");
    }
    else
    {
        printf("大端\n");
    }
}

方法2:使用联合体

image-20220310223123280

因为共用一块内存空间,所以可以给i赋值为1,只拿c中的内容即可


union U
{
    char c;
    int i ;  
}u;	//u为全局变量
int main()
{
    u.i  = 1;
    if(u.c == 1)
    {
        printf("小端\n");
    }
    else
    {
        printf("大端\n");
    }
    return 0;
}

写成函数形式:

int check_sys()
{
    union
    {
        char c;
        int i;
    }u;
    u.i = 1;
    //返回1->小端
    //返回0->大端
    return u.c;
}

联合体大小的计算

  • 联合体的大小至少是最大成员的大小

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

    (对齐数:成员类型的大小与编译器的对齐数(VS为8)比较,取较小值)

    (最大对齐数:联合体中所有成员的对齐数的最大值)

联合体也存在内存对齐!!!


//例子1
union Un1
{
    char c[5];
    int i;
};
int main()
{
    printf("%d\n",sizeof(union Un1));	//8
    return 0;
}

c为5个元素的char类型数组,相当于存放了5个char类型的变量,c的大小为5字节, 但是char类型大小为1byte,所以对齐数为1

i为整形变量,大小为4bit,对齐数为4

Un1成员的最大对齐数为4,最大成员大小为5

但是5不是4的倍数,浪费3个字节->联合体Un1大小为8


//例子2
union Un2
{
    short c[7];
    int i;
};
int main()
{
    printf("%d\n",sizeof(union Un2));	//16
    return 0;
}

c为7个元素的short类型数组,相当于存放了7个short类型的变量,c的大小为2*7=14字节, 但是short类型大小为为2byte 对齐数为2

i为整形变量,大小为4bit,对齐数为4

Un2成员的最大对齐数为4,最大成员大小为14,14不是4的倍数,所以浪费2个字节

->结构体Un2的大小为16byte


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。