首页 > 编程笔记

C语言联合体

C语言中的联合体(union)是一种特殊的数据类型,它允许在同一段内存中存储不同类型的数据。联合体的大小等于其最大的成员大小,因为联合体中只会存储其中一个成员。

联合体的定义

联合体的定义方式与结构体类似,使用 union 关键字:
union MyUnion {
    int i;
    float f;
    char c;
};
上述代码定义了一个联合体 MyUnion,包含三个成员:整型 i、浮点型 f、字符型 c。该联合体的大小为 4 个字节,因为整型和浮点型的大小都是 4 个字节,而字符型的大小为 1 个字节,由于联合体只存储其中一个成员,因此大小等于其最大的成员大小。

联合体的使用

联合体可以像结构体一样使用点运算符来访问成员。但是,需要注意的是,只能同时访问联合体中的一个成员。例如:
union MyUnion u;
u.i = 10;
printf("%d\n", u.i);   // 输出 10
u.f = 3.14;
printf("%f\n", u.f);   // 输出 3.140000
printf("%d\n", u.i);   // 输出 1085485875
在上述代码中,首先将整型成员 i 赋值为 10,然后输出i的值。接着将浮点型成员 f 赋值为 3.14,然后输出 f 的值。最后再次输出 i 的值,可以发现其值已经发生了变化,这是因为浮点型和整型在内存中的表示方式不同,导致联合体中的值发生了变化。因此,在使用联合体时需要格外小心,确保访问的成员正确。

除了使用点运算符访问成员外,也可以使用数组下标的方式访问联合体的成员。例如:

union MyUnion u;
u.i = 10;
printf("%d\n", u.i);           // 输出 10
u.c = 'A';
printf("%c\n", u.c);           // 输出 A
printf("%d\n", u.i);           // 输出 65
printf("%d\n", u.f);           // 输出 1090519040
printf("%c\n", u.c);           // 输出 A
printf("%d\n", u.c);           // 输出 65
printf("%d\n", u.i);           // 输出 65

在上述代码中,首先将整型成员i赋值为 10,然后输出 i 的值。接着将字符型成员 c 赋值为 'A',然后依次输出 c、i、f、c、c、i 的值。可以看到,由于联合体中的成员共享同一块内存,因此在对成员进行赋值后,其他成员的值也可能发生变化。

联合体的应用

联合体的应用范围非常广泛,可以用于优化内存使用、处理二进制数据等。下面以处理二进制数据为例,介绍联合体的应用。

在处理二进制数据时,常常需要读取数据块中的不同类型的数据。例如,一个数据块中可能包含一个整数和一个浮点数。此时,可以使用联合体来读取这些数据,如下所示:
union DataBlock {
    int i;
    float f;
};

int main() {
    FILE *fp;
    union DataBlock block;
   
    fp = fopen("data.bin", "rb");
    if (fp == NULL) {
        printf("Failed to open file.\n");
        return 1;
    }
   
    fread(&block, sizeof(union DataBlock), 1, fp);
   
    if (feof(fp)) {
        printf("End of file reached.\n");
    } else if (ferror(fp)) {
        printf("Error reading file.\n");
    } else {
        printf("Integer: %d\n", block.i);
        printf("Float: %f\n", block.f);
    }
   
    fclose(fp);
    return 0;
}
上述代码首先定义了一个联合体 DataBlock,包含两个成员:整型 i 和浮点型 f。然后在主函数中打开一个名为 data.bin 的二进制文件,并使用 fread 函数读取一个数据块的大小,存储到 block 中。如果成功读取到数据,则输出整数和浮点数的值;否则输出相应的错误信息。最后关闭文件并返回 0。

可以通过以下代码生成一个包含整数和浮点数的二进制文件:
int main() {
    FILE *fp;
    union DataBlock block;
   
    fp = fopen("data.bin", "wb");
    if (fp == NULL) {
        printf("Failed to open file.\n");
        return 1;
    }
   
    block.i = 10;
    block.f = 3.14;
    fwrite(&block, sizeof(union DataBlock), 1, fp);
   
    fclose(fp);
    return 0;
}
上述代码首先打开一个名为 data.bin 的二进制文件,并将整数和浮点数分别存储到 block 的 i 和 f 成员中。然后使用 fwrite 函数将 block 写入文件。最后关闭文件并返回 0。

运行上述读取数据的代码,可以得到如下输出结果:
Integer: 10
Float: 3.140000
上述代码演示了联合体在处理二进制数据时的应用,它可以轻松地读取不同类型的数据,并将它们存储在同一个数据块中。

联合体的注意事项

使用联合体需要注意以下几点:

总结

本文介绍了 C语言中的联合体,包括联合体的定义和使用方法,以及联合体在处理二进制数据时的应用。联合体是 C语言中一个非常有用的数据类型,可以优化内存使用,提高程序性能。然而,在使用联合体时需要格外小心,确保不会出现未定义行为。

推荐阅读