实验验证C语言中结构体与共用体的差异

简介: 实验验证C语言中结构体与共用体的差异


一、引言


在C语言编程中,结构体(struct)和共用体(union)是两种重要的复合数据类型,它们允许程序员将多个不同类型的数据组合成一个单一的数据类型。然而,尽管两者在形式上有些相似,但它们在内存中的表示和用途上却有着显著的区别。本文将通过实验的方式,深入探究结构体和共用体在C语言中的差异,并通过代码示例进行验证。


二、结构体(struct)


结构体是一种复合数据类型,它允许我们在一个变量中存储不同的数据类型。结构体中的每个元素(也称为成员)可以是不同类型的数据,它们通过结构体名来访问。结构体在内存中占据的是所有成员变量大小的总和,并且每个成员在内存中是连续存储的。

下面是一个简单的结构体示例代码:

#include <stdio.h>
// 定义一个结构体
typedef struct {
    int id;
    char name[50];
    float score;
} Student;
int main() {
    // 声明一个结构体变量
    Student stu = {1, "Tom", 90.5};
    // 访问结构体成员
    printf("ID: %d, Name: %s, Score: %.1f\n", stu.id, stu.name, stu.score);
    return 0;
}

在这个示例中,我们定义了一个名为Student的结构体,它包含了三个成员:id(整型)、name(字符数组)和score(浮点型)。然后,我们声明了一个Student类型的变量stu,并初始化了它的成员。最后,我们通过结构体变量名加上点操作符(.)来访问结构体的成员。


三、共用体(union)


共用体也是一种复合数据类型,它允许我们在一个变量中存储不同的数据类型。然而,与结构体不同的是,共用体中的所有成员共享同一块内存空间。这意味着,当我们在共用体中存储一个值时,它将覆盖该内存块中之前的值。共用体在内存中的大小是其成员中最大数据类型的大小。

下面是一个简单的共用体示例代码:

#include <stdio.h>
// 定义一个共用体
typedef union {
    int i;
    float f;
    char str[20];
} Data;
int main() {
    // 声明一个共用体变量
    Data data;
 
    // 存储整数
    data.i = 10;
    printf("Integer: %d\n", data.i);
    // 存储浮点数(覆盖之前的整数)
    data.f = 220.5;
    printf("Float: %.1f\n", data.f);
    // 存储字符串(覆盖之前的浮点数)
    strcpy(data.str, "Hello");
    printf("String: %s\n", data.str);
    // 注意:此时尝试访问 data.i 或 data.f 将得到未定义的结果
    return 0;
}

在这个示例中,我们定义了一个名为Data的共用体,它包含了三个成员:i(整型)、f(浮点型)和str(字符数组)。然后,我们声明了一个Data类型的变量data,并依次存储了整数、浮点数和字符串。由于共用体的特性,当我们存储一个新的值时,它将覆盖该内存块中之前的值。因此,在存储字符串之后,我们不能再通过data.i或data.f来访问之前的整数或浮点数了。


四、实验验证


为了更直观地展示结构体和共用体在内存中的差异,我们可以使用C语言中的指针和内存操作函数来进行实验验证。

首先,我们定义一个结构体和一个共用体,并声明相应的变量。然后,我们打印出这些变量在内存中的地址和大小。接下来,我们使用指针和内存操作函数来查看这些变量在内存中的具体内容。

以下是实验验证的代码示例:

#include <stdio.h>
#include <string.h>
// 定义结构体和共用体
typedef struct {
    int id;
    char name[50];
    float score;
} Student;
typedef union {
    int i;
    float f;
    char str[20];
} Data;
int main() {
    // 声明变量
    Student stu = {1, "Tom", 90.5};
    Data data;
    // 打印变量地址和大小
    printf("Student stu address: %p, size: %zu\n", &stu, sizeof(stu));
    printf("Data data address: %p, size: %zu\n", &data, sizeof(data));
    // 验证结构体内存布局
    printf("stu.id address: %p, value: %d\n", &(stu.id), stu.id);
    printf("stu.name address: %p, value: %s\n", stu.name, stu.name);
    printf("stu.score address: %p, value: %.1f\n", &(stu.score), stu.score);
    // 验证共用体内存布局(仅展示一种成员)
    data.i = 10;
    printf("data.i address: %p, value: %d\n", &(data.i), data.i);
    // 注意:由于共用体的特性,我们不能同时查看多个成员的内容
    return 0;
}

通过运行这段代码,我们可以清晰地看到结构体和共用体在内存中的地址和大小差异。同时,通过打印结构体和共用体成员的地址和内容,我们可以验证它们在内存中的存储方式。实验结果将直观地展示结构体成员在内存中是连续存储的,而共用体成员则共享同一块内存空间。

相关文章
|
20天前
|
存储 网络协议 编译器
【C语言】深入解析C语言结构体:定义、声明与高级应用实践
通过根据需求合理选择结构体定义和声明的放置位置,并灵活结合动态内存分配、内存优化和数据结构设计,可以显著提高代码的可维护性和运行效率。在实际开发中,建议遵循以下原则: - **模块化设计**:尽可能封装实现细节,减少模块间的耦合。 - **内存管理**:明确动态分配与释放的责任,防止资源泄漏。 - **优化顺序**:合理排列结构体成员以减少内存占用。
105 14
|
25天前
|
存储 编译器 C语言
【C语言】结构体详解 -《探索C语言的 “小宇宙” 》
结构体通过`struct`关键字定义。定义结构体时,需要指定结构体的名称以及结构体内部的成员变量。
112 10
|
29天前
|
存储 数据建模 程序员
C 语言结构体 —— 数据封装的利器
C语言结构体是一种用户自定义的数据类型,用于将不同类型的数据组合在一起,形成一个整体。它支持数据封装,便于管理和传递复杂数据,是程序设计中的重要工具。
|
1月前
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
122 13
|
1月前
|
存储 编译器 数据处理
C 语言结构体与位域:高效数据组织与内存优化
C语言中的结构体与位域是实现高效数据组织和内存优化的重要工具。结构体允许将不同类型的数据组合成一个整体,而位域则进一步允许对结构体成员的位进行精细控制,以节省内存空间。两者结合使用,可在嵌入式系统等资源受限环境中发挥巨大作用。
62 11
|
1月前
|
存储 人工智能 算法
数据结构实验之C 语言的函数数组指针结构体知识
本实验旨在复习C语言中的函数、数组、指针、结构体与共用体等核心概念,并通过具体编程任务加深理解。任务包括输出100以内所有素数、逆序排列一维数组、查找二维数组中的鞍点、利用指针输出二维数组元素,以及使用结构体和共用体处理教师与学生信息。每个任务不仅强化了基本语法的应用,还涉及到了算法逻辑的设计与优化。实验结果显示,学生能够有效掌握并运用这些知识完成指定任务。
57 4
|
存储 C语言
【C语言】 条件操作符 -- 逗号表达式 -- []下标访问操作符,()函数调用操作符 -- 常见关键字 -- 指针 -- 结构体
【C语言】 条件操作符 -- 逗号表达式 -- []下标访问操作符,()函数调用操作符 -- 常见关键字 -- 指针 -- 结构体
【C语言】——define和指针与结构体初识
【C语言】——define和指针与结构体初识
|
存储 C语言
C语言初识-关键字-操作符-指针-结构体
C语言初识-关键字-操作符-指针-结构体
66 0
【C语言】指针,结构体,链表
【C语言】指针,结构体,链表