工程建设招标中心网站/网站建设哪家好

工程建设招标中心网站,网站建设哪家好,优秀建筑模型案例作品,支付网站备案位域位域是指信息在保存时,并不需要占用一个完整的字节,而只需要占几个或一个二进制位。为了节省空间,C语言提供了一种数据结构,叫“位域”或“位段”。“位域“是把一个字节中的二进位划分为几个不同的区域,并说明每个…

位域

位域是指信息在保存时,并不需要占用一个完整的字节,而只需要占几个或一个二进制位。为了节省空间,C语言提供了一种数据结构,叫“位域”或“位段”。

“位域“是把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数,每个域有一个域名,允许在程序中按位域名进行操作。这样就可以把几个不同的对象用一个字节的二进制位域来表示。

位域的使用和结构成员的使用相同,其一般形式为:位域 变量名.位域名 位域允许用各种格式输出。

1. 在C中,位域可以写成这样(注:位域的数据类型一律用无符号的,纪律性)。

struct bitmap
{unsigned a : 1;unsigned b : 3;unsigned c : 4;
}bit;

  sizeof(bitmap) == 4;(整个struct的大小为4,因为位域本质上是从一个数据类型分出来的,在我们的例子中数据类型就是unsigned,大小为4,并且位域也是满足C 的结构体内存对齐原则的,等下我们会说到)。

2. 当然了位域也可以有空域。

struct bitmap{unsigned a:4;unsigned :0; /*空域*/unsigned b:4; /*从下一单元开始存放*/unsigned c:4;}sizeof(bitmap) == 8;

3. 在这个位域定义中,a占第一字节的4位,后4位填0表示不使用,b从第二字节开始,占用4位,c占用4位。这里我们可以看到空域的作用是填充数据类型的剩下的位置,有时候我们只是想调整一下内存分配,则我们可以使用无名位域:

 struct bitmap {unsigned a:1;unsigned :2;unsigned b:3;unsigned c:2;};sizeof(bitmap) == 4;
4. 如果一个位域的位的分配超过了该类型的位的总数,则从下一个单元开始继续分配,
这个很好理解:
 struct bitmap{unsigned a : 8;unsigned b : 30;unsigned c : 4;};sizeof(bitmap) == 12;

  注意这个位域的大小是12而不是8,说明如果超了大小是立马从下一个单元开始分配。

位域的使用主要出现在如下两种情况:
 (1)当机器可用内存空间较少而使用位域可以大量节省内存时。如,当把结构作为大数组的元素时。
 (2)当需要把一结构或联合映射成某预定的组织结构时。例如,当需要访问字节内的特定位时。
当要把某个成员说明成位域时,其类型只能是int,unsigned int与signed int三者之一(说明:int类型通常代表特定机器中整数的自然长度。short类型通常为16位,long类型通常为32位,int类型可以为16位或32位.各编译器可以根据硬件特性自主选择合适的类型长度.

关于位域还需要提醒读者注意如下几点:
其一,位域的长度不能大于int对象所占用的字位数.例如,若int对象占用16位,则如下位域说明是错误的:
     unsigned int x:17;
其二,由于位域的实现会因编译程序的不同而不同,在此使用位域会影响程序的可移植性,在不是非要使用位域不可时最好不要使用位域.
其三,尽管使用位域可以节省内存空间,但却增加了处理时间,在为当访问各个位域成员时需要把位域从它所在的字中分解出来或反过来把一值压缩存到位域所在的字位中.
其四,位域的位置不能访问,因些不能对位域使用地址运算符号&(而对非位域成员则可以使用该运算符).从而,即不能使用指向位域的旨针也不能使用位域的数组(因为数组实际上就是一种特殊的指针).另外,位域也不能作为函数返回的结果.
最后还要强调一遍:位域又叫位段(位字段),是一种特殊的结构成员或联合成员(即只能用在结构或联合中).

内存对齐:


1. 说到位域就不得说下内存对齐的东西,其实内存对齐也很简单,只是不同的编译器实现不一样,至于为什么要内存对齐,这个要从CPU的基本工作原理说起,但是首先要明白,无论我们是否内存对齐,CPU大多数情况都是能正常工作的(前提:对于大多数IA32指令都可以这么说,但是部分指令,如SSE多媒体指令这些就不行,这些指令有特殊内存对齐要求,比如16字节对齐,任何不满足内存对齐的地址访问储存器都是会导致异常,对于这些指令,编译器必须在编译的时候采取强制内存对齐)。

  实现内存对齐可以提高CPU的性能,比如处理器能一次取出8个字节,这个时候必须要求数据地址要8字节对齐,这个是和CPU和储存器的外围电路决定的,在内存对齐的情况下,CPU从储存器取出这8个字节只需要一个时钟周期,但是如果这个地址不是8字节对齐,那么CPU可能就需要两个时钟周期才能取出这8个字节。

  对于IA32,每个栈帧都惯例16字节对齐,编译器一般也会那么做,但是对于数据类型不同的编译器表现可能不一样,对于Windows(VC编译器),任何K字节的基本对象的地址都必须是K的倍数(比如对于int,必须4字节对齐,对于double,必须8字节对齐),这很大程度上提高了储存器和CPU的工作性能,但是对存储空间的浪费比较严重;对于Linux,惯例是8字节数对齐4字节边界(比如double可以4字节对齐)。对于Windows好Linux,数据类型long double都有4字节对其的要求,对于GCC,long double分配12字节(虽然它只占10字节大小)。

  所以我们有一般规则:

struct X
{char a;  float b;  int c;  double d;  unsigned e;
};
sizeof(X) == 32;

  内存对齐状况应该是下面这个样子:

struct X
{char a; // 1 bytes  char padding1[3]; // 3 bytes  float b; // 4 bytes  int c; // 4 bytes  char padding2[4]; // 4 bytes  double d; // 8 bytes  unsigned e; // 4 bytes  char padding3[4]; // 4 bytes};
sizeof(X) == 32;

  (其中最后的4个字节的填充是因为规则4,看下面)。

2. 如果自定义数据类型含有位域,则内存对齐满足以下原则:

  1. 如果相邻的位域的数据类型相同,则按照分配位的大小来,详情看我上面写的位域的第5个情况。

  2. 如果相邻的位域的数据类型不相同,则不同编译器实现不一样,有些编译器选择不压缩。

  3. 如果位域不连续,中间含非位域,则按标准数据类型大小划分,比如:

struct bitmap
{unsigned a : 2;  int b;  unsigned c : 3;
};
sizeof(bitmap) == 12;

3. 另外可以通过添加#pragma pack(n)来强制改变内存分配情况,比如在VC编译器中:


struct bitmap{unsigned a;double c;};sizeof(bitmap) == 16;

  加了#pragma pack(4),则强制内存对齐4字节,再测试下其大小:

#pragma pack(4)
struct bitmap
{unsigned a;  double c;
};
sizeof(bitmap) == 12;

  当然,如果#pragma pack(n)的n大于本身数据类型的宽度,则按数据类型的宽度来分配:

struct bitmap
{double c;  int k;  int m;
};
sizeof(bitmap) == 16 != 32

4. 自定义类型(C结构体,C++聚合类)的最后的内存对齐,是按照自定义类型内的最大类型的宽度来的,比如上面那个例子去掉int m:


struct bitmap{double c;int k;};
sizeof(bitmap) == 16

  必须以double进行8字节对齐(VC编译器)。

声明:

本文于网络整理,版权归原作者所有,如来源信息有误或侵犯权益,请联系我们删除或授权事宜。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/338719.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言实现数据字节序交换的四种方式

1关于数据字节序的说明1)关于字节序的说明字节序有两种大端和小端。大端:数据高位存放在低地址,地位放在高地址。如0x12345678在内存中存放为地址从左到右为低到高12345678。 小端:数据地位存放在低地址,高位存放在高地…

C语言如何实现动态数组?

提出问题请问在c语言里如何实现动态大小的数组啊,比如说int a[N];,这里N的值可以在程序中定,或者有什么方法可以实现类似的功能?总之只要在编译时不用制定数组大小就行。分析问题嵌入式系统的内存是宝贵的,内存是否高效…

Oracle为什么装在XP系统,重装xp系统后oracle恢复方法

重装系统后oracle如何恢复呢?下面就给大家介绍一下重装系统后oracle的恢复方法1、我们安装数据库软件只需安装同版本的数据库软件,不需要创建数据库。最好安装在和原来数据库同样的%ORACLE_HOME%下,省得还要修改参数文件路径等。(直接覆盖原来的oracle即…

vba 当前文件名_VBA代码解决方案第77讲内容:如何导出文件

大家好,我们今日继续讲解VBA代码解决方案的第77讲内容:如何导出文件,形成一个文本文件,如果需要将工作表中的数据保存为文本文件,可以创建一个文本文件用于保存数据。应用于FileSystemObject对象的CreateTextFile方法创…

常见的C语言字符串操作

#字符串倒序输出实现逻辑,通过strlen获取字符串长度,然后通过 len/2 进行交叉赋值,这里需要注意,不需要考虑len是奇数还是偶数的问题。如果len是奇数,最后一个字符就不需要倒序,如果是偶数,最后…

mui 时间样式错乱_微信公众号素材样式中心在哪?公众号动态分割线怎么添加?...

相比于静态分割线,动态分割线更有特色,能给文章增加趣味性。今天壹姐就来给公众号运营的小伙伴们介绍,怎么添加动态的分割线样式到文章里吧~1怎么使用公众号样式中心公众号后台的编辑功能比较基础,想要使用好看的公众号素材&#…

php获取访问量文本形式,php利用用文本统计访问量的方法图文详解

这篇文章主要介绍了php使用文本统计访问量的方法,涉及php文本文件读写与数值运算的相关技巧,需要的朋友可以参考下方法1:$fp fopen("counter.txt", "r");while(!flock($fp, LOCK_EX)) { // acquire an exclusive lock// waiting to lock the f…

yolov4论文_Alexey 大神接棒,YOLOv4 重磅来袭!快来一睹论文真容吧!| 原力计划...

作者 | Mr.Jk.Zhang责编 | 夕颜出品 | CSDN(ID:CSDNnews)前言千呼万唤始出来系列,继YOLOv3两年后,YOLOv4终于在上周出来了,让我们来一睹论文真容吧!由于YOLO之父Jeseph Redmon在今年2月已宣布退出CV学术界,大家都以为Y…

【C/C 】浅谈C/C 中函数指针与回调函数

01、函数指针1.1、函数指针定义一个函数总是占用一段连续的内存区域,函数名在表达式中有时也会被转换为该函数所在内存区域的首地址,这和数组名非常类似。我们可以把函数的这个首地址(或称入口地址)赋予一个指针变量,使…

jvm 错误_JVM因“ OutOfMemory”错误而关闭-我该怎么办?

jvm 错误看起来似乎很神奇,但是在有关JVM设置的搜索请求结果中经常显示“来自深度”的特定呼声。 您可能会遇到“我记得那个选项,但如何启用它”的问题,而有时(主要是半年一次)管理服务器或调整虚拟设备,而…

天线3db波束宽度_浅谈 Wi-Fi 天线(2)

在上一期内容中,我们为大家解读了增益(gain)、天线方向图(Antennae Directional Pattern)两个天线技术参数,本期我们来谈谈波束宽度(lobe width)。另一个常见的天线参数是“波束宽度”(又名:波瓣宽度),英文是 lobe width 或 beam …

C语言实例:3个数从小到大排序

需求任意输入3个整数,对这3个整数由小到大进行排序,并将排序后的结果输出。源码// // author: 冲哥 // date: 2021/5/7 13:37 // description: 实现对这3个整数由小到大进行排序 #include int main() {int num1, num2, num3, temp;printf("请输入3个…

oracle u01清理,Oracleの/u01/11g/diag/rdbms/orcl/orcl/incident 的清理

https://docs.oracle.com/cd/E11882_01/server.112/e25494/diag.htm#ADMIN11007每当一个错误发生的时候,oracle会创建一个incident,并且分配一个INCIDENT_ID号,同时在ADR HOME的INCIDENT目录中创建相应的INCIDENT 目录,每个错误号…

jar 、war、ear_在命令行上操作JAR,WAR和EAR

jar 、war、ear尽管Java IDE和许多图形工具使查看和操作Java归档文件(JAR,WAR和EAR)文件的内容比以往更加容易,但有时我还是更喜欢使用命令行jar命令来完成这些任务。 当我必须重复做某事或作为脚本的一部分来做时,尤其…

C语言 | 读写文件

C语言怎样向文件读写字符fgetc函数调用形式:fgetc(fp) 功能:从fp指向的文件读入一个字符。 返回值:读成功,带回所读的字符,失败则返回文件结束标志EOF(即-1)。fputc函数调…

哨兵系列卫星_空客“哥白尼哨兵-1C”卫星雷达天线首次展开双翼

【民航事儿】2020年8月11日,腓特烈港:通过模拟零重力环境并固定在特殊装置上,哥白尼哨兵-1C卫星的12.3米宽、860公斤重的合成孔径雷达(SAR)的雷达天线,首次成功的在位于德国腓特烈港的空中客车综合技术中心展开双翼。作为哨兵-1系…

oracle vm 环境支持,使用 Oracle VM 模板快速部署 Oracle RAC 环境

6. 实时监控部署状态日志[rootracnode1 racovm]# cat /tmp/progress-racovm.out2014-04-16 03:02:27:[buildcluster:Start:racnode1] Building 11gR2 RAC Cluster2014-04-16 03:02:27:[setsshroot:Start:racnode1] SSH Setup for the root user…2014-04-16 03:02:39:[setsshro…

C语言中return、break用法和区别

1returnreturn:跳出当前正在执行函数。使用方法:return (表达式);其中,(表达式)是可以省略的。 1.有返回类型return通常都是带有返回类型的,比如返回int型变量:int Fun(v…

兴趣点推荐代码_如何解读霍兰德职业兴趣测评结果?

霍兰德职业兴趣测评不难,难的是如何解读测评结果,这才是生涯规划测评中最重要的部分。今天我们就来说说霍兰德职业兴趣测评的结果应该如何解读。兴趣测评的结果是六种类型得分最高的三个代码依次排列组合而成,所以基本上就是R-实用型、I-研究…

linux mint 18支持安卓编译,Linux mint 18版本开启SSH服务

linux mint 18版本默认是没有安装ssh server的需要手动安装安装ssh server:此命令需要联网,会自动下载安装安装之后看是否开始了ssh,看到ssh-agent 和sshd 说明ssh server 已经启动了如果没看到ssh server 需要手动启动需要/etc/init.d/ssh s…