【C语言进阶篇】一篇文章让你彻底拿下 位段 枚举 联合!(上)

简介: 【C语言进阶篇】一篇文章让你彻底拿下 位段 枚举 联合!(上)

📋 前言

  🌈hello! 各位宝子们大家好啊,前面一章给大家带来了结构体的深层次 讲解,那么接下来就来到下一章的学习了,铁铁们准备好了嘛?

  ⛳️本期给大家带来的是 位段的内存分配 枚举 联合(共用体)的详细讲解让我们一起学起来把!

  📚本期文章收录在《C语言进阶篇》,大家有兴趣可以看看呐

  ⛺️ 欢迎铁汁们 ✔️ 点赞 👍 收藏 ⭐留言 📝!

💬 位段

  ⛳️一般情况下在书里,结构体的章节过来了之后就是位段(位域)叫法不同而已,说明我们的位段是靠结构体来实现的!

💬 什么是位段

位段的声明和结构是类似的,有两个不同:

  • 1.位段的成员必须是 int、unsigned int 或signed int 。
  • 2.位段的成员名后边有一个冒号和一个数字。(冒号后面的数字不得超过前面类型的大小.)

📚 代码演示:

struct A
{
 int _a:2;
 int _b:5;
 int _c:10;
 int _d:30;
};

⛳️ 这里A就是一个位段类型。那位段A的大小是多少?

  • 会是我们心里想的16个字节嘛?

📑 代码结果:

诶这时你会发现这个结构体的内存对齐计算结构体大小完全不一样啊!为什么大小是这个呢?

  • 就算是按4个整形计算也不可能是8个字节啊
  • 下面我们就来介绍一下位段的内存是如何分配的!

🔥 注:结构体如何计算大小文章链接《结构体的内存对齐》

  ⛳️ 位段位段,说明他是位的截段 那么是什么位呢?答案是 比特位 !,每个数字是占多少个 比特位

  • 大家可以验证一下,这些数字加起来刚好32位
  • 而32个 比特位4 个字节刚好能装下
  • 大家看一下下面这个猜一下是不是我们计算的4呢!
struct B
{
  int _a : 2;
  int _b : 5;
  int _c : 15;
  int _d : 10;
};

📑 代码结果:

哦!的确是这样的。下面我们就来具体看下位段到底是怎么样开辟空间的

💭 位段的内存分配

📜说明:

  • 🌱 位段的成员可以是 intunsigned intsigned int 或者是 char(属于整形家族)类型
  • 🌱 位段的空间上是按照需要以 4 个字节( int )或者1个字节( char )的方式来 开辟 的。
  • 🌱 位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。

  ⛳️ 这些是什么意思呢?就是我们位段的成员必须是整形家族的,如果我们位段时int 类型的那么就会先开辟4个字节,不够在开辟4个字节这样一直开辟下去, char类型的也是同理!

📚 举个例子:

#include <stdio.h>
struct S
{
  char a : 3;
  char b : 4;
  char c : 5;
  char d : 4;
};
int main()
{
  struct S s = { 0 };
  s.a = 10;
  s.b = 12;
  s.c = 3;
  s.d = 4;
  return 0;
}

  ⛳️那么究竟是不是我们这样描述存储的实践一下看看就明白了,假设我们在vs2019 这个平台上是从低向高访问的

  • 并且按照我们分配内存的慷慨性一旦放不下就重新开辟空间!
  • 而我们的位段 是char 类型的说明先开辟一个字节 ,不够在开辟
  • 那么我们大致画一下内存分布并运行查看一下到底是不是这样的?
    🔥 注:vs2019的情况下成员存放是先从右往左用,但是内存开辟是从地地址向高地址开辟

这里我们想象的大致内存分布是这样的,用了3个字节,程序运行看下是不是这样的?

📑 代码结果:

哦!看来在vs这个环境里就是按我们想像的这样开辟空间的我们在验证一下

  • 我们位段的每个成员都存放数据,然后到内存里面看是不是这样存储的
  • 但是每个成员只占他所对应的 比特位 存放
  • 所以一旦存放的内容超过所能存储的内容就会发生截断

位段成员a在内存中占3个字节但是 10 这个数字要存放 4 个字节,所以我们就会截断

  • 10 的二进制位是1010
  • 截断3位就是 010所以我们 a 存放的就是010

我们把存放进去的二进制位转成16进制来看一下!

  • 因为是 16进制 所以 4 个比特位 为一个 16进制

⛳️这里就可以看到按我们这存放的话,转换出来的16进制是 0x 62 03 04 00

  • 我们在vs2019里面调试看一下存放的和我们一步一样!

📑图片展示:

这时就可以看出在vs2019就是按我们想的那样存储的!

  • 即,位段中的成员在内存中(我们在vs是从低地址到高地址存储的)
  • 一旦分配的字节不过够存放下一个成员,会开辟新的字节来存放新成员

注:但是在C语言中从左向右分配,还是从右向左分配标准尚未定义!

注:当第一个位段的剩余的内容无法存储第二个位段时,要开辟新的空间,那之前剩余的空间是否被利用取决于平台,也没有规定.

💻 位段的跨平台问题

⛳️ 跟结构相比,位段可以达到同样的效果,并且可以很好的节省空间,但是有跨平台的问题存在。

  1. int 位段被当成有符号数还是无符号数是不确定的。
  2. 位段中最大位的数目不能确定。(16位机器最大16,32位机器最大32,写成27,在16位机
    器会出问题。
  3. 位段中的成员在内存中从左向右分配,还是从右向左分配标准尚未定义。
  4. 当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的位时,是
    舍弃剩余的位还是利用,这是不确定的。
目录
相关文章
|
C语言
【C语言程序设计——循环程序设计】枚举法换硬币(头歌实践教学平台习题)【合集】
本文档介绍了编程任务的详细内容,旨在运用枚举法求解硬币等额 - 循环控制语句(`for`、`while`)及跳转语句(`break`、`continue`)的使用。 - 循环嵌套语句的基本概念和应用,如双重`for`循环、`while`嵌套等。 3. **编程要求**:根据提示在指定区域内补充代码。 4. **测试说明**:平台将对编写的代码进行测试,并给出预期输出结果。 5. **通关代码**:提供完整的代码示例,帮助理解并完成任务。 6. **测试结果**:展示代码运行后的实际输出,验证正确性。 文档结构清晰,逐步引导读者掌握循环结构与嵌套的应用,最终实现硬币兑换的程序设计。
212 19
|
C语言
【C语言程序设计——枚举】得到 3 种不同颜色的球的可能取法(头歌实践教学平台习题)【合集】
本关任务要求从红、黄、蓝、白、黑五种颜色的球中,每次取出3个不同颜色的球,列举所有可能的排列情况。通过定义枚举类型和使用嵌套循环语句实现。枚举类型用于表示球的颜色,循环语句用于生成并输出所有符合条件的排列 编程要求:在指定区域内补充代码,确保输出格式正确且完整。测试说明:平台将验证代码输出是否与预期一致,包括每种排列的具体顺序和总数。 示例输出: ``` Output: 1 red yellow blue 2 red yellow white ... 60 black white blue total: 60 ```
305 4
|
机器学习/深度学习 C语言
【c语言】一篇文章搞懂函数递归
本文详细介绍了函数递归的概念、思想及其限制条件,并通过求阶乘、打印整数每一位和求斐波那契数等实例,展示了递归的应用。递归的核心在于将大问题分解为小问题,但需注意递归可能导致效率低下和栈溢出的问题。文章最后总结了递归的优缺点,提醒读者在实际编程中合理使用递归。
835 7
|
存储 编译器 C语言
c语言回顾-联合和枚举
c语言回顾-联合和枚举
|
存储 C语言 C++
深入C语言,发现多样的数据之枚举和联合体
深入C语言,发现多样的数据之枚举和联合体
175 0
深入C语言,发现多样的数据之枚举和联合体
|
存储 机器学习/深度学习 编译器
一篇文章,把你的C语言拉满绩点
一篇文章,把你的C语言拉满绩点
143 0
|
存储 安全 编译器
深入理解C语言中的枚举
深入理解C语言中的枚举
|
存储 编译器 C语言
【C语言】自定义类型:联合与枚举的简明概述
【C语言】自定义类型:联合与枚举的简明概述
189 0
|
C语言
《C语言及程序设计》实践项目——枚举应用
返回:贺老师课程教学链接 【项目1-对称点】 设计函数,可以按指定的方式,输出一个平面点的对称点 下面给出枚举类型定义和main函数(测试函数),请写出output函数的实现。 #include&lt;stdio.h&gt; enum SymmetricStyle {axisx, axisy, point};//分别表示按x轴, y轴, 原点对称三种方式 void
1177 0
|
存储 算法 C语言
【C语言程序设计——函数】素数判定(头歌实践教学平台习题)【合集】
本内容介绍了编写一个判断素数的子函数的任务,涵盖循环控制与跳转语句、算术运算符(%)、以及素数的概念。任务要求在主函数中输入整数并输出是否为素数的信息。相关知识包括 `for` 和 `while` 循环、`break` 和 `continue` 语句、取余运算符 `%` 的使用及素数定义、分布规律和应用场景。编程要求根据提示补充代码,测试说明提供了输入输出示例,最后给出通关代码和测试结果。 任务核心:编写判断素数的子函数并在主函数中调用,涉及循环结构和条件判断。
793 23