结构体和联合体的区别

结构体(struct)和联合体(union)在C/C++语言中都是用于组合不同数据类型成员的复合数据类型,但它们在内存使用和数据访问上有着本质的区别:

1. **内存分配**:
   - **结构体**:结构体中的每个成员都有自己独立的存储空间,成员间互不影响。结构体的总大小是其所有成员所需空间之和,还需考虑内存对齐。
   - **联合体**:联合体中的所有成员共享同一块内存空间。在任何给定时间,联合体内只存储一个成员的值。联合体的大小通常等于其最大成员的大小。

2. **数据访问**:
   - **结构体**:对结构体的不同成员进行赋值或访问是互不影响的,每个成员都保持各自的值。
   - **联合体**:对联合体的一个成员赋值会覆盖其他成员的值,因为它们共享内存。访问联合体的某个成员时,实际上是查看这块共享内存以该成员类型解释的值。

3. **用途**:
   - **结构体**:适用于需要同时存储不同类型数据,并且这些数据在程序运行期间都需要保留其独立值的情况。
   - **联合体**:适用于需要在同一内存位置存储不同类型的值,但在任意时刻只使用其中一种情况。它可以帮助节省内存空间,或者用于表示同一资源的不同视图。

4. **内存对齐**:
   - 结构体成员之间可能存在填充字节以满足对齐要求,导致结构体的实际大小可能大于成员大小之和。
   - 联合体虽然共享内存,但也需要对齐到其最大成员的对齐要求,但这不会导致额外的内存开销,因为其大小就是最大成员的大小。

总的来说,结构体提供了数据的封装和组织,而联合体则提供了内存的复用和类型转换的能力。在现代编程实践中,结构体的应用更为广泛,而联合体多用于特定场景下的优化或特殊处理。


### 结构体示例

```c
#include <stdio.h>

// 定义一个结构体类型 Student
struct Student {
    char name[20];
    int age;
    float score;
};

int main() {
    struct Student stu1;
    
    // 分别给结构体成员赋值
    strcpy(stu1.name, "Alice");
    stu1.age = 20;
    stu1.score = 90.5;
    
    // 打印结构体成员的值
    printf("Name: %s, Age: %d, Score: %.1f\n", stu1.name, stu1.age, stu1.score);

    return 0;
}
```
在这个例子中,`Student`结构体包含了姓名(字符串)、年龄(整数)和分数(浮点数)三个成员,它们各自独立存储,可以同时保持各自的值。

### 联合体示例

```c
#include <stdio.h>

// 定义一个联合体类型 Data
union Data {
    int i;
    char c;
    float f;
};

int main() {
    union Data data;
    
    // 给联合体的一个成员赋值
    data.i = 10;
    printf("Integer value: %d\n", data.i);
    
    // 赋予另一个成员值,这会覆盖之前i的值
    data.c = 'A';
    printf("Char value: %c, ASCII: %d\n", data.c, data.c);
    
    // 注意:现在data.i的值不再是10,而是字符'A'的ASCII值
    // 因为它们共享同一块内存
    printf("Now integer value (due to char assignment): %d\n", data.i);
    
    return 0;
}
```
在这个例子中,`Data`联合体可以存储整数、字符或浮点数,但一次只能存储其中一个值。当给`data.c`赋值后,原先`data.i`的值就被`'A'`的ASCII码值覆盖了,展示了联合体成员共享内存的特点。
全部评论

相关推荐

04-06 16:59
已编辑
河南工业大学 Java
牛牛牛的牛子:最好扔了,实在没有选择的选择
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
1
2
分享

创作者周榜

更多
牛客网
牛客企业服务