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

C语言:自定义类型:联合体与枚举

文章目录

  • 前言
  • 1. 联合体
    • 1.1 联合体类型的声明
    • 1.2 联合体类型的特点
    • 1.3 联合体大小的计算
    • 1.4 用联合判断大小端
  • 2. 枚举
    • 2.1 枚举类型的声明
    • 2.2 枚举类型的优点
    • 2.3 枚举类型的使用

前言

在C语言中,除了基本数据类型(如intcharfloat)和数组,程序员还可以通过结构体联合体枚举来自定义复杂的数据类型。这些自定义类型极大地增强了C语言描述现实世界数据的能力。

本文将重点介绍联合体枚举这两种自定义类型。联合体以其独特的内存共享机制,在节省内存和灵活解释数据方面发挥着重要作用;而枚举则为程序中的整型常量提供了更具可读性和安全性的表示方式。理解并掌握它们,是迈向高级C语言编程的关键一步。

1. 联合体

联合体是C语言中一种特殊的数据类型,它允许在同一块内存空间中存储不同类型的数据成员。与结构体为每个成员分配独立内存不同,联合体的所有成员共享同一段内存。这意味着,在任意时刻,联合体中只有一个成员是有效的,对其中一个成员的赋值会覆盖其他成员的值。

1.1 联合体类型的声明

声明一个联合体类型使用关键字union,其语法与结构体(struct)非常相似:

union联合体标签{成员类型1成员名1;成员类型2成员名2;// ... 更多成员};
  • union:声明联合体类型的关键字。
  • 联合体标签:联合体类型的名称,遵循C语言标识符命名规则。
  • 成员列表:用花括号{}包裹,内部定义了联合体的各个成员,每个成员都有自己的类型和名称。

示例:声明一个简单的联合体:

#include<stdio.h>// 联合类型的声明unionUn{charc;inti;};intmain(){// 联合变量的定义unionUn un={0};// 计算联合变量的大小printf("%d\n",sizeof(un));//输出4return0;}

1.2 联合体类型的特点

联合体最核心的特点在于其内存共享机制,这带来了以下几个关键特性:

  1. 所有成员共享同一内存地址
    联合体的所有成员都从同一内存地址开始存储。这意味着,通过不同的成员名访问的是同一块内存区域。

  2. 同一时间只有一个成员有效
    由于内存共享,当你给一个成员赋值后,再访问其他成员将得到未定义的值(可能是之前值的残留,也可能是被覆盖后的新值)。程序员需要自己记录当前哪个成员是“活跃”的。

  3. 大小由最大成员决定
    联合体变量占用的内存大小,等于其所有成员中所需空间最大的那个成员的大小。编译器会确保联合体的大小至少能容纳下最大的成员,并可能进行内存对齐。

1.3 联合体大小的计算

计算联合体的大小需要遵循两个原则:

  1. 大小至少等于其最大成员的大小。
  2. 大小必须是所有成员类型对齐要求的整数倍(内存对齐原则)。

计算步骤:

  1. 找出所有成员中,占用空间最大的成员的大小(sizeof(最大成员))。
  2. 找出所有成员中,对齐要求最严格的成员的对齐值(通常等于其大小)。
  3. 最终联合体的大小是最大成员大小向上取整到最严格对齐值的整数倍。
unionExample{charc;// 大小1字节,对齐要求1字节inti;// 大小4字节,对齐要求4字节(在常见32/64位系统上)doubled;// 大小8字节,对齐要求8字节};
  • 最大成员是double d,大小为8字节。
  • 最严格的对齐要求也是double的8字节。
  • 因此,union Example的大小为8字节

可以使用sizeof运算符验证:

printf("Size of union Example: %zu bytes\n",sizeof(unionExample));// 输出 8

与结构体大小对比:

structSExample{charc;inti;doubled;};// 在考虑对齐(如按8字节对齐)后,此结构体大小可能为 1+(3填充)+4+(4填充)+8 = 24字节。

可以看到,联合体通过共享内存,在存储“互斥”数据时,能比结构体节省大量空间。

1.4 用联合判断大小端

我们可以写一个程序,判断当前机器是大端还是小端。

int check_sys() { union { int i; char c; }un; un.i = 1; return un.c;//返回1是小端,返回0是大端 }

2. 枚举

枚举是C语言中一种用于定义一组命名整型常量的自定义数据类型。

2.1 枚举类型的声明

声明一个枚举类型使用关键字enum,其基本语法如下:

enum枚举标签{枚举常量1,枚举常量2,// ... 更多常量};
  • enum:声明枚举类型的关键字。
  • 枚举标签:枚举类型的名称,遵循C语言标识符命名规则。
  • 枚举常量列表:用花括号{}包裹,内部列出所有枚举常量,常量之间用逗号分隔。

示例:声明一个表示星期的枚举类型:

enumWeekday{MONDAY,// 默认值为 0TUESDAY,// 默认值为 1WEDNESDAY,// 默认值为 2THURSDAY,// 默认值为 3FRIDAY,// 默认值为 4SATURDAY,// 默认值为 5SUNDAY// 默认值为 6};

枚举常量的值:

  • 默认情况下,第一个枚举常量的值为0,后续常量依次递增1。
  • 可以显式地为枚举常量指定整数值,未指定的常量将基于前一个值递增1。
    enum Color { RED = 1, GREEN, // 值为 2 BLUE = 5, YELLOW // 值为 6 };

2.2 枚举类型的优点

我们可以使用#define定义常量,为什么非要使用枚举?相比#define,枚举具有以下显著优点:

  1. 增加代码的可读性和可维护性,枚举常量使用有意义的名称,使代码意图一目了然。同时,枚举常量集中定义在一处,便于统一管理和修改。

  2. #define定义的标识符比较,枚举有类型检查,更加严谨

  3. 便于调试,预处理阶段会删除#define定义的符号

  4. 使用方便,一次可以定义多个常量

  5. 枚举常量是遵循作用域规则的,枚举声明在函数内,只能在函数内使用。

2.3 枚举类型的使用

enumColor//颜色{RED=1,GREEN=2,BLUE=4};enumColorclr=GREEN;//使用枚举常量给枚举变量赋值

在C语言中,可以直接用整数给枚举变量赋值,但是在C++是不行的,C++的类型检查比较严格。

http://www.jsqmd.com/news/1398212/

相关文章:

  • 石家庄翻译公司 德语专利翻译技巧
  • 2026年想找靠谱纱窗厂家?这家成都纱窗厂家不容错过!
  • 主页被清空的那个晚上:聊聊抖音视频批量下载与无水印保存
  • 4.PID调参实战:先P后I再D,手把手教你搞定参数整定
  • MZmine 3质谱数据处理从入门到实战:一篇文章吃透安装配置、特征检测与2类典型分析流程
  • Seedance 2.0 Prompt 怎么写?真人、电商、短视频 3 类可直接套用模板(技灵AI)
  • AI编程助手上下文压缩机制:原理、策略与工程实践
  • OneNote笔记迁移5步搞定:onenote-md-exporter无损导出Markdown完整教程
  • 基于OpenAI API构建自动化工作流:从信息获取到量化回测的AI数字员工实践
  • GBFR Logs 伤害统计工具新手实战教程:3步装好DPS计量器,把每场战斗的伤害数据都看明白
  • 人到中年选首饰,慈溪普通人的佩戴思路值得参考
  • DLSS Swapper完整使用教程:3步完成DLSS版本升级,画质与帧率一起提升
  • LLM应用监控盲区:Vergilant如何解决API调用失败与成本泄漏
  • Legacy-iOS-Kit 上手指南:四步让老设备降级重获流畅,顺带备份 SHSH 票据
  • 3分钟上手ParsecVDD:给Windows凭空“变出“16个虚拟显示器
  • LosslessCut 无损视频剪辑完整实战:从切割到多轨合并,全程零画质损失
  • DHCP协议详解:从DORA四步握手到实战排错与安全配置
  • EGO数采多传感器时间同步详解:具身智能数据对齐的硬件触发方案与工程实践
  • AI语音智能体开发日记(十二)GX8006 固件定制指南——从双唤醒词到 UART 音频传输
  • 04-时序数据聚合统计:按小时/天/月设备数据汇总
  • 微信聊天记录导出备份:3 步用 WeChatMsg 把对话永久留在自己手里
  • Diablo Edit2完整指南:10分钟搞定暗黑破坏神2角色存档修改(1.09到2.6全版本通用)
  • KMS_VL_ALL_AIO智能激活脚本完整教程:3分钟免费搞定Windows与Office激活
  • 免驱动标签打印怎么落地:LPrint 用 1 个进程接管全公司打印机
  • 不想越狱又想给 iPhone 换位置?iFakeLocation 跨平台虚拟定位完整上手指南
  • OneNote 迁移实战终极指南:onenote-md-exporter 5 步完成笔记无损转换
  • Figma 界面汉化完整指南:FigmaCN 安装教程与使用技巧
  • 抖音无水印下载工具douyin-downloader实战教程:如何轻松搞定单个视频与主页批量下载
  • 网易云音乐等级自动打卡工具入门:从安装到每日300首歌曲打卡
  • 基于Python的公共卫生数据分析实战:环孢子虫病监测案例