当前位置: 首页 > web >正文

【C语言】深入理解C语言中的自定义数据类型:struct、union与enum

文章目录

  • 前言
    • 1. struct —— 结构体
      • 1.1 结构体的定义与声明
      • 1.2 声明结构体变量
      • 1.3 结构体的内存布局
      • 1.4 使用typedef简化结构体定义
    • 2. union —— 共用体
      • 2.1 定义与声明共用体
      • 2.2 共用体的使用
      • 2.3 共用体的内存布局
    • 3. enum —— 枚举
      • 3.1 定义与声明枚举
      • 3.2 使用枚举
      • 3.3 自定义枚举的值
      • 3.4 枚举的内存大小
      • 3.5 枚举的优缺点
    • 4. struct、union 与 enum 的比较

前言

C语言中,结构体(struct)、共用体(union)和枚举(enum)是三种常见的自定义数据类型,可以组织多个不同类型的变量为一个单一的复合类型,提高代码的可读性和组织性。


1. struct —— 结构体

结构体(struct)是C语言中最常用的复合数据类型之一。它可以将多个不同类型的变量组织在一起,形成一个新的类型。结构体的变量可以包含不同的数据类型,这使得它非常适合描述一些复杂对象。

1.1 结构体的定义与声明

定义结构体时,我们使用struct关键字,后面跟上结构体的名称,并定义其内部包含的成员。

struct Person {char name[50];int age;float height;
};

在上面的示例中,Person是一个结构体类型,它包含三个成员:name(字符串类型)、age(整数类型)和height(浮点数类型)。

1.2 声明结构体变量

定义完结构体类型后,我们可以在程序中声明变量并对其进行操作。

struct Person person1;
person1.age = 25;
person1.height = 5.9;
strcpy(person1.name, "John");

1.3 结构体的内存布局

结构体内存是按顺序分配的,但由于不同类型的变量可能具有不同的对齐要求,编译器通常会在成员之间插入填充字节,以确保每个成员的地址按照其对齐要求正确存放。内存布局的大小也受到这些填充字节的影响。

1.4 使用typedef简化结构体定义

在C语言中,结构体类型可以通过typedef进行简化,避免在声明变量时重复写struct关键字。

typedef struct {char name[50];int age;float height;
} Person;Person person2;  // 不需要再写 struct

2. union —— 共用体

共用体(union)与结构体非常相似,但它的每个成员共享同一段内存区域。这意味着,在任何时候,union类型变量只有一个成员能够存储数据,而其他成员的数据会被覆盖。这使得union在节省内存空间时非常有用,尤其是在存储不同类型数据时,只需要考虑当前使用的数据类型大小。

2.1 定义与声明共用体

union Data {int i;float f;char str[20];
};

在这个例子中,union Data可以存储整数、浮点数或字符串,但它们共享同一内存区域,任何时候只能保存其中一个。

2.2 共用体的使用

union Data data1;
data1.i = 10;
printf("data1.i: %d\n", data1.i);data1.f = 220.5;
printf("data1.f: %f\n", data1.f);strcpy(data1.str, "Hello, World!");
printf("data1.str: %s\n", data1.str);

注意,在上述代码中,先存储的整数i会被浮点数f覆盖,浮点数f又会被字符串str覆盖。因此,共用体中的成员是互斥的。

2.3 共用体的内存布局

共用体的内存大小是其最大成员大小,也就是说,它的内存大小取决于最大成员的大小。例如,union Data的内存大小为sizeof(char[20]),即20个字节,因为str是共用体中最大的一项。


3. enum —— 枚举

枚举(enum)是一种为整型变量定义一组符号常量的方式。它允许我们为某些固定的值设置有意义的名称,使代码更加易读和维护。

3.1 定义与声明枚举

enum Weekday {Monday = 1,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday
};

在这个例子中,enum Weekday为一周的7天定义了符号常量。默认情况下,Monday的值是1,接下来的天数自动递增。

3.2 使用枚举

enum Weekday today = Wednesday;
if (today == Wednesday) {printf("Today is Wednesday\n");
}

通过枚举,我们可以使用有意义的名字代替数字,使代码更具可读性。

3.3 自定义枚举的值

我们还可以自定义枚举值的起始值和增量。

enum Color {Red = 10,Green = 20,Blue = 30
};

此时,Red的值为10,Green为20,Blue为30。

3.4 枚举的内存大小

枚举的底层实现是整数类型,通常为int,因此它的内存大小通常为sizeof(int),但是在某些编译器中,可以通过typedef或强制类型转换来改变枚举的底层类型。

3.5 枚举的优缺点

优点缺点
增强可读性:使用有意义的名字代替数字常量,使代码更易于理解。内存消耗:枚举通常使用整数类型,可能会浪费内存。
类型安全:编译器会检查枚举值是否符合定义的类型范围。缺少灵活性:枚举成员是静态的,不能动态添加或修改。
减少硬编码:通过为常量赋予名字,减少数字常量的硬编码。与其他类型的兼容性差:枚举不能与其他类型(如 charfloat)直接兼容。
自动赋值:枚举值会自动递增,简化赋值操作。调试困难:调试时,枚举值通常显示为整数,难以识别具体含义。
提高代码可维护性:常量的名字增强了代码的自解释性,易于团队协作和后期维护。无法直接进行运算:枚举值不能直接进行算术运算。

4. struct、union 与 enum 的比较

特性structunionenum
存储方式每个成员都有独立内存空间所有成员共享同一内存空间每个枚举值都映射为一个整数值
内存大小所有成员的内存大小之和最大成员的内存大小通常为整数类型的大小
使用场景适用于描述包含不同类型的复合数据适用于存储不同类型的数据,但每次只能存储一个值适用于表示有限集合的常量值
成员类型可以是任意类型只能是简单类型(通常是基本数据类型)必须是整型常量

我们对三者进行简单总结:

  • struct用于将不同类型的数据组织成一个集合,适合存储复合数据。
  • union允许多个成员共享同一块内存,可以节省空间,但每次只能保存一个成员的数据。
  • enum为一组常量值提供更具可读性的名称,用于表示有限集合的值。
http://www.xdnf.cn/news/9658.html

相关文章:

  • 大话软工笔记—基本概念
  • 三视图重建 笔记
  • python入门day02
  • 制导与导航总述、分类介绍、MATLABdemo
  • PROFIBUS转PROFINET网关:饲料行业的通信桥梁
  • LeetCode 543 二叉树的直径
  • 使用Miniconda管理Python环境
  • MS3494模拟矩阵开关
  • transformer-PositionalEncoding (对数空间计算实现)
  • 行业案例 | OPPO借助Azure AI Speech国际服务实现音频文件智能转录
  • 基于MATLAB的二维圆形随机骨料生成程序
  • APL Photonics封面成果:KAUST用五边形激光腔刷新物理随机数生成极限——800Gb/s!
  • Selenium 测试框架 - JavaScript
  • Xamarin入门笔记(Xamarin已经被MAUI取代)
  • 利益相关者意见分歧,如何决策
  • 在线临床指标分类信息表转甜甜圈矩阵图
  • 将git最后一次提交把涉及到的文件按原来目录结构提取出来
  • LLM中的Loss与Logits详解
  • 【leetcode】206. 反转链表
  • Linux Shellcode开发(Stager Reverse Shell)
  • 简述MySQL优化锁方面你有什么建议?
  • 彰显国产力量|暴雨亮相2025 C3安全峰会
  • Guava限频器RateLimiter的使用示例
  • STM32学习第一课--工程建立(云端备份与自我复盘)
  • ROS2学习(16)------ URDF 机器人建模方法
  • 操作系统 | 第一章:操作系统引论思维导图
  • 解决ssh: connect to host IP port 22: Connection timed out报错(scp传文件指定端口)
  • Java—多线程
  • 如何使用 poetry 创建虚拟环境,VSCode 如何激活使用 Poetry 虚拟环境(VSCode如何配置 Poetry 虚拟环境)
  • MVCC原理解析