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

浅析 C 语言的共用体、枚举和位域

前言

最近在尝试阅读一些系统库的源码,但是其中存在很多让我感到既熟悉又陌生的语法。经过资料查阅,发现是 C 语言中的共用体和位域。于是,趁着课本还没有扔掉,将一些相关的知识点记录在本文。

文章目录

  • 前言
  • 共用体 (union)
  • 枚举 (enum)
  • 位域
  • 参考资料

共用体 (union)

公用体和结构体相似,也是一种数据构造机制。但是结构体中的各成员变量顺序排列存储,每个成员变量都有自己独立存储空间,而共用体中所有成员变量共享同一片内存区域,一个共用体变量在每个时刻里只能保存它的某个成员变量的值

定义格式如下:

union 共用体名 {成员列表
};

下面是共用体和结构体占用内存的情况:

#include <stdio.h>union UnionData {int a;float b;double c;char d;
};struct StructData {int a;float b;double c;char d;
};int main() {printf("%lu %lu\n", sizeof(UnionData), sizeof(StructData));return 0;
}

控制台输出结果:

8 24

在这里插入图片描述
共用体能支持在同一块内存区域对不同的数据类型进交替使用,增加了灵活性,节省了内存,通常在系统库中会有所应用。

枚举 (enum)

枚举 (enumeration) 是一系列命名的整型常量,它是一种基本数据类型,而不是一种构造类型。在“枚举”类型的定义中,我们需要列举出所有可能值,就像列举一周七天、一年四季等。

定义格式如下:

enum 枚举名 {枚举列表};

枚举的使用例子如下:

#include <stdio.h>// 枚举定义
enum Season {SeasonSpring = 1,SeasonSummer,SeasonAutumn, SeasonWinter
};int main () {Season a = SeasonSpring;switch (a) {case SeasonSpring:printf("SeasonSpring\n");break;case SeasonSummer:printf("SeasonSummer\n");break;case SeasonAutumn:printf("SeasonAutumn\n");break;case SeasonWinter:printf("SeasonWinter\n");break;}return 0;
}

控制台输出结果:

1 2 3

位域

有些数据在存储时并不需要占用一个完整的字节,只需要占用一个或几个二进制位即可。例如开关只有通电和断电两种状态,用 0 和 1 表示足以,也就是用一个二进位。

出于节省内存的角度考虑,就有了位域这种设计。位域是 C 语音中一种特殊的结构体成员,它允许我们指定它所占的内存位数

定义格式如下:

struct 位域结构名 {类型说明符 位域名 : 位域长度;
};

说明:

  • 一个位域必须存储在同 1 个字节中,不能跨两个字节。如果一个字节所剩的空间不足以存储下一个位域时,应该从下一个字节开始存储。
  • 位域长度不能大于 1 个字节长度,也就是说不能超过 8 位。
  • 位域的数据类型只能是 int、unsigned int、char、枚举等类型。
  • 位域可以没有位域名,因为无名的位域是不能使用的,所以只是用作填充或调整位置的作用。例如:
    struct BitStruct {int a : 4;int   : 2;  // 空域,不能使用int b : 4;int c : 4;
    }
    

参考资料

  • https://www.runoob.com/cprogramming/c-bit-fields.html
  • https://book.douban.com/subject/26792521/

本文主要对 C 语言中,共用体、枚举和位域等三块内容做简单介绍,涉及到他们在工程中应用的方面很少,如果后面阅读系统源码的过程遇到了,会再做进一步补充。

http://www.lryc.cn/news/116392.html

相关文章:

  • TartanVO: A Generalizable Learning-based VO 论文阅读
  • 单例模式-java实现
  • 篇八:装饰器模式:动态增加功能
  • 算法通关村第五关——n数之和问题解析
  • 小白到运维工程师自学之路 第七十集 (Kubernetes集群部署)
  • docker 部署mysql 5.6集群
  • mysql基本信息查询
  • C语言初学者必读:使用for循环将数字从大到小排序并输出
  • 【Vue+Element-plus】记录后台首页多echart图静态页面
  • BM5 合并k个已排序的链表 javascript
  • 1.利用matlab建立符号表达式(matlab程序)
  • LVS工作环境配置
  • 金蝶,「起舞」在大模型时代
  • 解决Vs Code工具开发时 保存React文件时出现乱码情况
  • Fastjson 使用指南
  • 阿里云内容审核服务使用(图片审核)
  • git撤回最近一次push操作
  • 2000-2022年上市公司环境不确定性(原始数据+测算代码+测算结果)
  • 网络基本概念
  • 2.安装Docker-ce
  • Redis-2
  • 一分钟了解下Java追随和适应云原生的手段之Java Native Build(JNB)
  • Flutter iOS 与 flutter 相互通信
  • OpenCV和PIL图像对象转换
  • IDEA的实用快捷键大全
  • 04-6_Qt 5.9 C++开发指南_QListWidget和QToolButton
  • 笔试错题不熟悉 积累
  • Adb发送特定广播给App和App获取权限的命令
  • 字节C++后端面试总结
  • el-select 分页加载