【C语言】共用体

1、共用体占用的空间大小

共用体中各个字段都会利用同一片存储空间。共用体占用的总内存大小为各个字段中占用字节数最多的字段所占用的空间。

#include <stdio.h>

union my_register {
    struct {
        unsigned char byte1;
        unsigned char byte2;
        unsigned char byte3;
        unsigned char byte4;
    } bytes; //匿名结构体声明了一个结构体变量bytes
    unsigned int num;
};

int main() {
    union my_register un;
    printf("sizeof(un)= %ld\n", sizeof(un));//4
    return 0;
}

之所以 sizeof(un) 占4个字节,是因为在共用体中,bytes字段占4个字节,num字段占4个字节,所以共用体也就占用4个字节。

共用体内存占用结构图:

如下共用体 node 的内存占用结构图:

union node {  //共用体占据的空间大小为8个字节
	double a; //8个字节
	char b; //1个字节
	int c; //4个字节
};

2、使用共用体,实现IP转整数的功能

分析

        IP的样式为"xxx.xxx.xxx.xxx",其中每个“xxx"范围都是0~255,而255的表示就是8个1。而8位为1字节,所以IP的每个”xxx“都可以用1个字节表示,且要求为无符号类型。4个部分一共就是4个字节,所以一个IP可以对应一个无符号整型的值(都是4字节)。

代码

#include <stdio.h>

//使用共用体实现IP转整数的功能
union IP {
    struct {
        unsigned char byte1;
        unsigned char byte2;
        unsigned char byte3;
        unsigned char byte4;
    } bytes;
    unsigned int num; //当取得4个字节时,就获取到了一个无符号整数
};

int main() {
    union IP p;
    char str[100];//保存读入的IP地址
    int arr[4];
    while (~(scanf("%s", str))) {
        sscanf(str, "%d.%d.%d.%d", arr, arr + 1, arr + 2, arr + 3); //获取IP中每个部分的值
        p.bytes.byte1 = arr[0];
        p.bytes.byte2 = arr[1];
        p.bytes.byte3 = arr[2];
        p.bytes.byte4 = arr[3];
        printf("IP to int = %u\n", p. num);
    }
    return 0;
}

运行结果

192.168.0.1 //输入值
IP to int = 16820416
192.168.0.2 //输入值
IP to int = 33597632

存在的问题】192.168.0.1与192.168.0.2之间相差了1,但是它们映射得到的整型结果并不是相差1,这是为什么呢?

解答】这涉及到大端机和小端机,大端机:数据的低位存储在高地址位;小端机:数据的低位存储在低地址位。

内存占用图:(大端机:如果以整数来看待,1就是最低位,192就是最高位)

而当前机器是小端机,所以内存占用图应该如下:(0号字节放低位,3号字节放高位)

所以,当将其转为整数的时候,和192.168.0.2的差距就很大了。

修改】根据小端机的特点,修改程序:

#include <stdio.h>

//使用共用体实现IP转整数的功能
union IP {
    struct {
        unsigned char byte1;
        unsigned char byte2;
        unsigned char byte3;
        unsigned char byte4;
    } bytes;
    unsigned int num;
};

int main() {
    union IP p;
    char str[100];//保存读入的IP地址
    int arr[4];
    while (~(scanf("%s", str))) {
        sscanf(str, "%d.%d.%d.%d", arr, arr + 1, arr + 2, arr + 3);
        p.bytes.byte1 = arr[3];
        p.bytes.byte2 = arr[2];
        p.bytes.byte3 = arr[1];
        p.bytes.byte4 = arr[0];
        printf("IP to int = %u\n", p. num);
    }
    return 0;
}

运行结果

192.168.0.1
IP to int = 3232235521
192.168.0.2
IP to int = 3232235522

3、判断机器是大端机还是小端机

#include <stdio.h>
//判断机器是大端机还是小端机

int is_little() {
    int num = 1;
    //通过判断0号位字节的值是否为1来确定是否为小端机
    //将当前4字节当做4字节大小的字符数组
    return ((char *)(&num))[0]; 
}

int main() {
    printf("is_little = %d\n", is_little()); //1
    return 0;
}

为什么能通过判断0号字节位的值就能确定机器是大端机还是小端机呢?

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言中的共用体(Union)和位域(Bit-Field)是用来优化内存使用和灵活操作数据的工具。 共用体是一种特殊的数据类型,它允许不同的变量共享同一块内存空间。共用体中的成员变量共享同一内存占用内存大小等于最大成员的大小。通过修改共用体的一个成员变量的值,可以影响到其他成员变量的值。共用体适用于在不同的数据类型之间进行转换或者存储占用内存大小不定的数据。 位域是一种特殊的结构体成员变量,可以指定成员变量占用的位数,从而实现对内存空间的灵活利用。位域的成员变量必须是整型数据类型,并且位域的大小不能超过该整型类型的大小。位域可以用于减小数据结构占用内存大小,以及进行数据的位操作。 共用体和位域结构体可以一起使用。通过在位域结构体中定义共用体成员变量,可以实现对内存的灵活使用和数据的高效操作。共用体可以用于存储不同类型的数据,而位域可以用于压缩数据的存储空间。这种结合使用的方式可以为我们的程序带来更加高效和节省内存的特点。 总结起来,C语言中的共用体和位域结构体提供了一种优化内存使用和操作数据的方式。它们可以灵活地对内存空间进行利用,并且能够高效地操作数据。通过合理的使用共用体和位域结构体,我们可以达到节省内存和提高程序执行效率的目的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值