共用体与位域 --20240310

共用体
共用体(Union)是一种特殊的数据类型,它允许在同一个内存位置存储不同的数据类型。
共用体的所有成员共享同一块内存空间,因此同一时间只能存储其中一个成员的值。
共用体的定义和结构体类似,使用关键字union,后面跟着成员列表。每个成员可以是不同的数据类型,但共用体的所有成员都共享同一块内存空间,大小取决于最大的成员
 
共用体使用举例demo:
#include <string.h>

union Data {
        int i;
        float f;
        char str[20];
};

int main()
{
        union Data data;

        data.i = 10;
        printf("data.i = %d \n", data.i);
        printf("sizeof(data) = %ld \n", sizeof(data));

        data.f = 20;
        printf("data.f = %f \n", data.f);
        printf("sizeof(data) = %ld \n", sizeof(data));

        strcpy(data.str, "Hello");
        printf("data.str: %s\n", data.str);
        printf("sizeof(data) = %ld \n", sizeof(data));

        return 0;
}

// 执行结果
data.i = 10
sizeof(data) = 20
data.f = 20.000000
sizeof(data) = 20
data.str: Hello
sizeof(data) = 20

 

位域
寄存器的一个bit位在存储时并不需要占用一个完整的字节,只需要一个bit,用0和1表示足以,也就是用一个二进位。正是基于这种考虑,C语言又提供了一种数据结构,叫做“位域”或“位段”。
位域的存储:
位域的存储遵循结构体内存对齐的原则,举个例子:
#include <stdio.h>

struct pack
{
        int a:2;
        int b:4;
        int c:6;
} a;

int main(void)
{
        printf("sizeof(a) = %d \n", sizeof(a));
        return 0;
}

// 执行结果
sizeof(a) = 4
a、b、c成员所占的位长之和在一个存储单元(此处为int类型所占的字节数)内,即4个字节内,所以struct pack类型的变量所占的字节长度为4个字节(实际a、b、c一共占用12bit,还有20bit空间为保留的空白)。此处要将内存对齐到 4 个字节(int类型所占的字节数),以便提高存取效率。
 
共用体和位域结合使用
寄存器操作时,共用体和位域结合使用十分方便,如下
#include <stdio.h>

union GPA_REG0 {
        int resval;
        struct {                                                                                                                                                                                                                 int bit0: 1;
                int bit1: 1;
                int bit2: 1;
                int bit3: 1;
                int bit4: 1;
                int bit5: 1;
                int bit6: 1;
                int bit7: 1;
                int bit8: 1;
                int bit9: 1;
                int bit10: 1;
                int bit11: 1;
                int bit12: 1;
                int bit13: 1;
                int bit14: 1;
                int bit15: 1;
        } fields;
};

union GPA_REG0 gpa_reg0;

void gpa_reg0_modify(union GPA_REG0 *addr)
                addr->fields.bit0 = 1;
                addr->fields.bit1 = 1;
                addr->fields.bit2 = 1;
                addr->fields.bit3 = 1;
                addr->fields.bit4 = 1;
                addr->fields.bit5 = 1;
                addr->fields.bit6 = 1;
                addr->fields.bit7 = 1;
                addr->fields.bit8 = 1;
                addr->fields.bit9 = 1;
                addr->fields.bit10 = 1;
                addr->fields.bit11 = 1;
                addr->fields.bit12 = 1;
                addr->fields.bit13 = 1;
                addr->fields.bit14 = 1;
                addr->fields.bit15 = 0;
}

int main()
{
        printf("gpa_reg0.resval = 0x%lx, sizeof(gpa_reg0) = %d \n", gpa_reg0.resval, sizeof(gpa_reg0));
        gpa_reg0_modify(&gpa_reg0);
        printf("gpa_reg0.resval = 0x%lx, sizeof(gpa_reg0) = %d \n", gpa_reg0.resval, sizeof(gpa_reg0));
}

// 执行结果
gpa_reg0.resval = 0x0, sizeof(gpa_reg0) = 4
gpa_reg0.resval = 0x7fff, sizeof(gpa_reg0) = 4

 

 
posted @ 2024-03-10 16:14  lethe1203  阅读(31)  评论(0编辑  收藏  举报