实验验证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;
}

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

相关文章
|
11天前
|
存储 C语言
C语言程序设计核心详解 第九章 结构体与链表概要详解
本文档详细介绍了C语言中的结构体与链表。首先,讲解了结构体的定义、初始化及使用方法,并演示了如何通过不同方式定义结构体变量。接着,介绍了指向结构体的指针及其应用,包括结构体变量和结构体数组的指针操作。随后,概述了链表的概念与定义,解释了链表的基本操作如动态分配、插入和删除。最后,简述了共用体类型及其变量定义与引用方法。通过本文档,读者可以全面了解结构体与链表的基础知识及实际应用技巧。
|
16天前
|
C语言
c语言中的结构体
本文档详细介绍了C语言中结构体的使用方法,包括结构体的基本定义、变量声明与赋值、数组与指针的应用,以及结构体嵌套、与`typedef`结合使用等内容。通过示例代码展示了如何操作结构体成员,并解释了内存对齐的概念。
|
22天前
|
C语言
C语言结构体赋值的四种方式
本文总结了C语言结构体的四种赋值方式,并通过示例代码和编译运行结果展示了每种方式的特点和效果。
35 6
|
1月前
|
编译器 程序员 Linux
【C语言篇】结构体和位段详细介绍
跟结构相⽐,位段可以达到同样的效果,并且可以很好的节省空间,但是有跨平台的问题存在。
|
1月前
|
存储 C语言
C语言------结构体和共用体
这篇文章是关于C语言中结构体和共用体的实训,通过示例代码演示了结构体的定义、赋值、使用,以及如何使用结构体变量进行数据的组织和操作,包括输入、排序、求平均分和查找学生信息等功能。
C语言------结构体和共用体
|
2月前
|
人工智能 C语言
7-5 sdut -C语言实验-节约用电
7-5 sdut -C语言实验-节约用电
26 3
|
2月前
|
存储 编译器 定位技术
结构体数组在C语言中的应用与优化策略
结构体数组在C语言中的应用与优化策略
|
2月前
|
Linux C语言
【编程小实验】C语言实现:无限循环写入文本文件,支持Ctrl+C中断与数据追加(附完整源码)
在Linux中,文件I/O(输入/输出)是程序与文件进行交互的基本方式,包括读取文件内容和向文件写入数据。这通常通过标准的C库函数来实现,下面是一些基本的文件读写操作和代码示例。
112 0
|
2月前
|
存储 编译器 数据库
结构体数组在C语言中的应用与优化技巧
结构体数组在C语言中的应用与优化技巧
|
3月前
|
C语言
C语言中的结构体
C语言中的结构体