- C 编程教程
- C - 首页
- C 语言基础
- C - 概述
- C - 特性
- C - 历史
- C - 环境搭建
- C - 程序结构
- C - Hello World
- C - 编译过程
- C - 注释
- C - 词法单元
- C - 关键字
- C - 标识符
- C - 用户输入
- C - 基本语法
- C - 数据类型
- C - 变量
- C - 整数提升
- C - 类型转换
- C - 类型强制转换
- C - 布尔值
- C 语言中的常量和字面量
- C - 常量
- C - 字面量
- C - 转义序列
- C - 格式说明符
- C 语言中的运算符
- C - 运算符
- C - 算术运算符
- C - 关系运算符
- C - 逻辑运算符
- C - 位运算符
- C - 赋值运算符
- C - 一元运算符
- C - 自增和自减运算符
- C - 三元运算符
- C - sizeof 运算符
- C - 运算符优先级
- C - 其他运算符
- C 语言中的决策
- C - 决策
- C - if 语句
- C - if...else 语句
- C - 嵌套 if 语句
- C - switch 语句
- C - 嵌套 switch 语句
- C 语言中的循环
- C - 循环
- C - while 循环
- C - for 循环
- C - do...while 循环
- C - 嵌套循环
- C - 无限循环
- C - break 语句
- C - continue 语句
- C - goto 语句
- C 语言中的函数
- C - 函数
- C - 主函数
- C - 按值调用函数
- C - 按引用调用函数
- C - 嵌套函数
- C - 可变参数函数
- C - 用户定义函数
- C - 回调函数
- C - 返回语句
- C - 递归
- C 语言中的作用域规则
- C - 作用域规则
- C - 静态变量
- C - 全局变量
- C 语言中的数组
- C - 数组
- C - 数组的特性
- C - 多维数组
- C - 将数组传递给函数
- C - 从函数返回数组
- C - 可变长数组
- C 语言中的指针
- C - 指针
- C - 指针和数组
- C - 指针的应用
- C - 指针运算
- C - 指针数组
- C - 指针到指针
- C - 将指针传递给函数
- C - 从函数返回指针
- C - 函数指针
- C - 指向数组的指针
- C - 指向结构体的指针
- C - 指针链
- C - 指针与数组
- C - 字符指针和函数
- C - 空指针
- C - void 指针
- C - 悬空指针
- C - 解引用指针
- C - 近、远和巨型指针
- C - 指针数组的初始化
- C - 指针与多维数组
- C 语言中的字符串
- C - 字符串
- C - 字符串数组
- C - 特殊字符
- C 语言中的结构体和联合体
- C - 结构体
- C - 结构体和函数
- C - 结构体数组
- C - 自引用结构体
- C - 查找表
- C - 点 (.) 运算符
- C - 枚举 (或 enum)
- C - 结构体填充和打包
- C - 嵌套结构体
- C - 匿名结构体和联合体
- C - 联合体
- C - 位域
- C - Typedef
- C 语言中的文件处理
- C - 输入 & 输出
- C - 文件 I/O (文件处理)
- C 预处理器
- C - 预处理器
- C - 指令
- C - 预处理器运算符
- C - 宏
- C - 头文件
- C 语言中的内存管理
- C - 内存管理
- C - 内存地址
- C - 存储类
- 其他主题
- C - 错误处理
- C - 可变参数
- C - 命令执行
- C - 数学函数
- C - static 关键字
- C - 随机数生成
- C - 命令行参数
- C 编程资源
- C - 问答
- C - 快速指南
- C - 速查表
- C - 有用资源
- C - 讨论
C 语言中的联合体
C 语言中的联合体
在 C 语言中,联合体是一种特殊的数据类型,它允许在同一个内存位置存储不同的数据类型。您可以定义一个包含多个成员的联合体,但在任何给定时间,只有一个成员可以包含值。联合体提供了一种有效的方式,可以使用同一个内存位置来实现多种用途。
联合体的所有成员共享同一个内存位置。因此,如果我们需要对两个或多个成员使用同一个内存位置,那么联合体就是最适合的数据类型。最大的联合体成员决定了联合体的大小。
定义联合体
联合体变量的创建方式与结构体变量相同。关键字union用于在 C 语言中定义联合体。
语法
以下是 C 语言中定义联合体的语法:
union [union tag]{ member definition; member definition; ... member definition; } [one or more union variables];
“联合体标签”是可选的,每个成员定义都是一个正常的变量定义,例如“int i;”、“float f;”或任何其他有效的变量定义。
在联合体定义的末尾,在最后一个分号之前,您可以指定一个或多个联合体变量。
访问联合体成员
要访问联合体的任何成员,我们使用成员访问运算符(.)。成员访问运算符被编码为联合体变量名和我们想要访问的联合体成员之间的句点。您将使用关键字 union 来定义联合体类型的变量。
语法
以下是 C 语言中访问联合体成员的语法:
union_name.member_name;
联合体成员的初始化
您可以通过使用赋值 (=) 运算符为其赋值来初始化联合体的成员。
语法
以下是初始化联合体成员的语法:
union_variable.member_name = value;
示例
以下代码语句显示了如何初始化联合体“data”的成员“i”:
data.i = 10;
联合体的示例
示例 1
以下示例演示了如何在程序中使用联合体:
#include <stdio.h> #include <string.h> union Data{ int i; float f; char str[20]; }; int main(){ union Data data; data.i = 10; data.f = 220.5; strcpy(data.str, "C Programming"); printf("data.i: %d \n", data.i); printf("data.f: %f \n", data.f); printf("data.str: %s \n", data.str); return 0; }
输出
当编译并执行上述代码时,会产生以下结果:
data.i: 1917853763 data.f: 4122360580327794860452759994368.000000 data.str: C Programming
在这里,我们可以看到i和f(联合体的成员)的值显示为垃圾值,因为分配给变量的最终值已占据了内存位置,这就是str成员的值能够正确打印的原因。
示例 2
现在让我们再次看看同一个示例,在其中我们将一次使用一个变量,这是使用联合体的主要目的:
#include <stdio.h> #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); data.f = 220.5; printf("data.f: %f \n", data.f); strcpy(data.str, "C Programming"); printf("data.str: %s \n", data.str); return 0; }
输出
当编译并执行上述代码时,会产生以下结果:
data.i: 10 data.f: 220.500000 data.str: C Programming
在这里,所有联合体成员的值都能够正确打印,因为每次只使用了一个成员。
联合体的大小
联合体的大小是其最大成员的大小。例如,如果一个联合体包含两个char和int类型的成员。在这种情况下,联合体的大小将是int的大小,因为int是最大的成员。
您可以使用sizeof() 运算符来获取联合体的大小。
示例
在下面的示例中,我们打印了一个联合体的大小:
#include <stdio.h> // Define a union union Data { int a; float b; char c[20]; }; int main() { union Data data; // Printing the size of the each member of union printf("Size of a: %lu bytes\n", sizeof(data.a)); printf("Size of b: %lu bytes\n", sizeof(data.b)); printf("Size of c: %lu bytes\n", sizeof(data.c)); // Printing the size of the union printf("Size of union: %lu bytes\n", sizeof(data)); return 0; }
输出
当您编译并执行代码时,它将产生以下输出:
Size of a: 4 bytes Size of b: 4 bytes Size of c: 20 bytes Size of union: 20 bytes
结构体和联合体的区别
在 C 编程中,结构体和联合体都是复合数据类型。结构体和联合体之间最显著的区别在于它们存储数据的方式。结构体将每个成员存储在单独的内存位置,而联合体将所有成员存储在同一个内存位置。
以下是一个名为myunion的联合体类型的定义:
union myunion{ int a; double b; char c; };
联合体的定义类似于结构体的定义。具有相同元素的“struct type mystruct”的定义如下所示:
struct mystruct{ int a; double b; char c; };
结构体和联合体之间的主要区别在于变量的大小。编译器为结构体变量分配内存,以便能够存储所有元素的值。在mystruct中,有三个元素:一个 int、一个 double 和一个 char,需要 13 个字节 (4 + 8 + 1)。因此,sizeof(struct mystruct)返回 13。
另一方面,对于联合体类型变量,编译器分配一块内存,其大小足以容纳字节大小最大的元素。myunion类型具有 int、double 和 char 元素。在这三个元素中,double 变量的大小最大,即 8。因此,sizeof(union myunion)返回 8。
另一个需要考虑的要点是,联合体变量只能保存其一个元素的值。当您为一个元素赋值时,其他元素未定义。如果您尝试使用其他元素,则会导致一些垃圾数据。
示例 1:联合体占用的内存
在下面的代码中,我们定义了一个名为Data的联合体类型,它具有三个成员i、f和str。Data类型的变量可以存储一个整数、一个浮点数或一个字符字符串。这意味着单个变量(即同一个内存位置)可以用来存储多种类型的数据。您可以根据需要在联合体中使用任何内置或用户定义的数据类型。
联合体占用的内存将足够大,以容纳联合体中最大的成员。例如,在上面的示例中,Data将占用 20 个字节的内存空间,因为这是字符字符串可以占用的最大空间。
以下示例显示了上述联合体占用的总内存大小:
#include <stdio.h> #include <string.h> union Data{ int i; float f; char str[20]; }; int main(){ union Data data; printf("Memory occupied by Union Data: %d \n", sizeof(data)); return 0; }
输出
当您编译并执行代码时,它将产生以下输出:
Memory occupied by Union Data: 20
示例 2:结构体占用的内存
现在,让我们创建一个具有相同元素的结构体,并检查它在内存中占用了多少空间。
#include <stdio.h> #include <string.h> struct Data{ int i; float f; char str[20]; }; int main(){ struct Data data; printf("Memory occupied by Struct Data: %d \n", sizeof(data)); return 0; }
输出
此结构体将占用 28 个字节 (4 + 4 + 20)。运行代码并检查其输出:
Memory occupied by Struct Data: 28