IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C语言中不常见类型:位段的详解 -> 正文阅读

[C++知识库]C语言中不常见类型:位段的详解

目录

位段

? ? ? ? 我们都知道结构体,那您是否了解位段呢?

? ? ? ? 一、位段的定义?

? ? ? ? 二、位段的内存分配

????????三、段位赋值问题

????????四、位段跨平台问题

????????五、位段的运用?


位段

? ? ? ? 我们都知道结构体,那您是否了解位段呢?

????????仔细观察一下两个不一样的“结构体”,他们有什么区别呢?

? ? ? ? 一、位段的定义?

? ? ? ? ? ? ? ? 位段的声明和结构体是类似的,但是有两点不同:

? ? ? ? ? ? ? ? ? ? ? ? 1.位段的成员必须是int、unsigned int、signed int或char(char属于整型家族)类型。(一般情况下位段的成员类型都全部为int或者char类型)

? ? ? ? ? ? ? ? ? ? ? ? 2.位段成员的后面有一个:(冒号)和一个数字(数字表示这个成员所需内存大小,以bit为单位)。

? ? ? ? ? ? ? ? 如上面的H就是一个位段。

? ? ? ? 二、位段的内存分配

????????????????位段的空间是以4个字节(位段成员是int类型)或者1个字节(位段成员是char类型)开辟的。(所以冒号后面的bit大小不会超过32bit(int类型)或8bit(char类型),具体还是要看机器(如16位机器int是2字节,32位机器int是4字节)

????????????????如下面G这个位段:

struct G
{
	int i : 2;
	int o : 5;
	int p : 10;
	int u : 30;
};

? ? ? ? ? ? ? ? i占2bit,o占5bit,p占10bit,u占30bit,加起来应该是47bit,按道理6字节的空间就够存储他们了。

? ? ? ? ? ? ? ? 可事实并非如此:

? ? ? ? ? ? ? ? 经实践认证此位段所占空间为8字节,为什么呢?

下面我们来对此位段空间的分配进行详解:

由于此位段成员类型都是int,所以每次以4个字节(也就是32bit)为单位开辟空间:

? ? ? ? 以小段存储为例,我们先开辟32bit的空间:

?????????再将只占2bit的i成员先存入:?

? ? ? ? 接着紧按着i成员,将5bit的哦成员存入(段位没有像结构体一样的内存对齐):

?

? ? ? ? 之后再将10bit空间的p成员存入:

????????最后我们在存30bit的u成员时,发现内存只剩15bit不够用,此时我们再向空间申请4字节(int类型)的空间:

? ? ? ? ?存入30bit的p成员:

?????????在我们存完所有成员之后,我们发现实际存p时系统并不会再使用上面并未用完的15bit的空间,而是直接在可以存下p的新空间地方存p。

? ? ? ? 这就最终造成了段位G所占用的空间为64bit(8字节)。

????????三、段位赋值问题

????????????????现在我们将位段赋值:

int main()
{
  unsigned char puc[4];
  struct tagPIM
  {
    unsigned char ucPim1;
    unsigned char ucData0 : 1;
    unsigned char ucData1 : 2;
    unsigned char ucData2 : 3;
  }*pstPimData;
  pstPimData = (struct tagPIM*)puc;
  memset(puc,0,4);//将数组puc的4个字节全部赋值为0
  pstPimData->ucPim1 = 2; 
  pstPimData->ucData0 = 3;
  pstPimData->ucData1 = 4;
  pstPimData->ucData2 = 5;
  printf("%02x %02x %02x %02x\n",puc[0], puc[1], puc[2], puc[3]);
  return 0;
}

?我们先来模拟展示一下位段tagPIM的存储结构:

?????????如图位段tagPIM的总存储大小为16bit,其中ucPim1占8bit、ucData2占3bit、ucData占2bit、ucData0占1bit。

而字符数组puc的存储结构为:

? ? ? ? ?如图char元素0、1、2、3分别占8bit,一共32bit。

????????所以将puc强转为段位tagPIM指针类型时(pstPimData = (struct tagPIM*)puc),pstPimData最多可以指向puc字符数组中0和1元素大小的空间。

? ? ? ? 当puc中所以元素都被赋值为0时:

?????????当pstPimData->ucPim1 = 2时,即ucPim1指针大小的空间被赋值为2时,2的二进制表示是10,puc中的元素发生如下变化:

????????

????????当pstPimData->ucData0 = 3时,即ucData0指针大小的空间被赋值为3时,3的二进制表示是11,可是ucData0大小只有1bit,所以舍弃前一位,puc中的元素发生如下变化:

?

????????当?pstPimData->ucData1 = 4时,即ucData1指针大小的空间被赋值为4时,4的二进制表示是100,可是ucData1大小只有2bit,所以舍弃前一位,puc中的元素发生如下变化:

????????当pstPimData->ucData2 = 5时,即ucData2指针大小的空间被赋值为5时,5的二进制表示是101,可是ucData2的大小正好是3bit,所以不用舍弃,puc中的元素发生如下变化:

?

?????????最终进行printf打印时puc【0】的值为10换为十六进制为2,puc【1】的值为101001转换为十六进制为29,puc【2】和puc【3】的值还为0。

????????四、位段跨平台问题

????????????????1.int位段被当成有符号数还是无符号数是不确定的。
????????????????2.位段中最大位的数目不能确定。(16位机器最大16,32位机器最大32,写成27,在16位机器会出问题)。
????????????????3.位段中的成员在内存中从左向右分配,还是从右向左分配标准尚未定义。
????????????????4.当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的位时,是舍弃剩余的位还是利用,这是不确定的。

所以说跟结构体相比位段可以达到相同的效果而且比较节省空间,但是有跨平台的问题存在。

????????五、位段的运用?

????????位段通常会运用在网络数据的封装(浅浅提一下~):

好了,今天的博客又要和大家说再见了,谢谢各位看官嘞!

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-09-24 20:38:18  更:2022-09-24 20:42:04 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 10:20:06-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码