笔记21-2 (C语言进阶 自定义类型)

目录

注:

联合体类型的定义

联合的特点

联合体类型的初始化

例子:判断当前计算机的大小端存储

联合体大小的计算

分析

练习


注:

 本笔记参考B站up鹏哥C语言的视频


联合体类型的定义

联合也是一种特殊的自定义类型。

这种类型定义的变量也包含一系列的成员,特征是这些成员共用同一块空间(所以联合也叫做共用体)。

比如:

//联合类型的声明
union Un
{
	char c;
	int i;
};

int main()
{
	//联合变量的定义
	union Un un_1;
	//计算这个变量的大小
	printf("%d\n", sizeof(un_1));
        
        return 0;
}

打印结果:

为什么这里是4个字节呢?这就是联合体的特点。

联合的特点

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

现在回来看之前的例子。

首先观察地址,打印:

printf("%p\n", &un_1);
printf("%p\n", &(un_1.c));
printf("%p\n", (&un_1.i));

打印结果:

发现三个地址是一模一样的。

会发现,ic 共用一块空间。

这就是共用体的一个特点:它的成员完全有可能共用了同一块空间

联合体类型的初始化

union Un
{
	char c;
	int i;
};

int main()
{
	//联合变量的定义
	union Un un_1 = { 10 };

	return 0;
}

此时如果进行调试,看见:

此时 c 和 i 内存储的都是 10 。

那如果想要分别给 c 和 i 赋值要怎么办?

union Un un_1 = { 10 };
un_1.i = 1000;
un_1.c = 100;

在 i 内存储数字1000,实际上是在内存的4个字节内存储1000。而想在 c 内存储数字100,实际上是在内存的第一个字节内存储了100。

发现:既然 i 和 c 共用一个空间,所以在改动 i 的时候实际上也改动了 c 。同理,在改动 c 的时候也改动了 i 。这就是共用体的另一个特点:同一时间,只能使用共用体中的一个成员

联合体的作用:让多个成员共同享有某一块空间。

例子:判断当前计算机的大小端存储

复习存储模式

大端存储模式、小端存储模式在存储到内存后,可以发现存在差异。

只需要拿出第一个字节的内容就可以找出不同,进而判断出计算机的大小端存储。

int main()
{
    int a = 1;
    if ((*(char*)&a) == 1)
    {
	printf("小端\n");
    }
    else
    {
        printf("大端\n");
    }

    return 0;
}

函数实现

int check_sys()
{
    int a = 1;
    if ((*(char*)&a) == 1)
    {
	return 1;//小端
    }
    else
    {
	return 0;//大端
    }
}

int main()
{
    int ret = check_sys();
    if (ret == 1)
	printf("小端\n");
    else
       	printf("大端\n");
    return 0;
}

这里会发现,a 占了4个字节,而我们需要的,只是这4个字节中的第一个字节,这时候就可以使用联合体了。

------

union Un
{
	char c;
	int i;
};

如果给 i 赋值为1,再取出 c ,此时 c 就占据 i 的第一个字节。

联合体的写法:

int check_sys()
{
    union U
    {
	char c;
	int i;
    }u;

    u.i = 1;
    return u.c;//此处是char类型,返回时转换成了int类型
    //返回1,就是小端
    //返回0,就是大端
}

int main()
{
    int ret = check_sys();
    if (ret == 1)
	printf("小端\n");
    else
	printf("大端\n");
    return 0;
}

联合体大小的计算

  • 联合的大小至少是最大成员的大小。
  • 当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。

分析

union Un
{
	char a[5];//占5个字节
	int i;//占4个字节
};

int main()
{
	union Un u;
	printf("%d\n", sizeof(u));
	return 0;
}

这里的打印结果是:

发现这里的打印结果并不是联合体最大成员的大小 5 ,而是 8

这是因为联合体也是存在对齐的当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。

  • char a[5] 每个元素都是char类型,所以认为 a[5] 的对齐数就是 1 。
  • int i 的对齐数就是 4 。

所以这些成员的最大对齐数就应该是 4

但是 a[5] 所占空间大小是 5 ,5 不是 4 的倍数,所以继续开辟空间,一直到开辟出第8个字节,此时 84 的倍数。

练习

union Un
{
	char a[5];
	char b;
};

可以猜测,这个联合体的大小是 5 。


union Un
{
	short s[5];//10
	int a;//4
};

一个short类型是2个字节,4 > 2,最大对齐数应该是4。

s[5] 所占空间大小是10,不是4的倍数,开辟到12个字节的大小。故联合体大小为:12 。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值