C言语中位域和结构体得区别是什么 (c语言位域的高低位)

C言语中位域和结构体得区别是什么 (c语言位域的高低位)

本文目录导航:

C言语中位域和结构体得区别是什么?

C言语结构体对齐也是老生常谈的话题了。

基本上是面试题的必考题。

内容只管很基础,但一不小心就会弄错。

写出一个struct,而后sizeof,你会不会经常对结果感到奇异?sizeof的结果往往都比你申明的变量总长度要大,这是怎样回事呢?开局学的时刻,也被此类疑问困扰很久。

其实关系的文章很多,觉得说分明的不多。

结构体究竟怎样对齐? 有人给对齐准则做过总结,详细在哪里看到如今已记不起来,这里援用一下先人的阅历(在没有#pragma pack宏的状况下): 准则1、数据成员对齐规则:结构(struct或联结union)的数据成员,第一个数据成员放在offset为0的中央,以后每个数据成员存储的起始位置要从该成员大小的整数倍开局(比如int在32位机为4字节,则要从4的整数倍地址开局存储)。

准则2、结构体作为成员:假设一个结构里有某些结构体成员,则结构体成员要从其外部最大元素大小的整数倍地址开局存储。

(struct a里存有struct b,b里有char,int,double等元素,那b应该从8的整数倍开局存储。

) 准则3、收尾上班:结构体的总大小,也就是sizeof的结果,必定是其外部最大成员的整数倍,无余的要补齐。

这三个准则详细怎样了解呢?咱们看上方几个例子,经过实例来加深了解。

例1:struct { short a1; short a2; short a3;}A;struct{ long a1; short a2;}B; sizeof(A) = 6; 这个很好了解,三个short都为2。

sizeof(B) = 8; 这个比是不是比预想的大2个字节?long为4,short为2,整个为8,由于准则3。

例2:struct A{int a;char b;short c;};struct B{ char b; int a; short c;}; sizeof(A) = 8; int为4,char为1,short为2,这里用到了准则1和准则3。

sizeof(B) = 12; 能否超出预想范畴?char为1,int为4,short为2,怎样会是12?还是准则1和准则3。

深究一下,为什么是这样,咱们可以看看内存里的规划状况。

a b c A的内存规划:1111, 1*, 11 bac B的内存规划:1***, 1111, 11** 其中星号*示意填充的字节。

A中,b前面为何要补充一个字节?由于c为short,其起始位置要为2的倍数,就是准则1。

c的前面没有补充,由于b和c正好占用4个字节,整个A占用空间为4的倍数,也就是最大成员int类型的倍数,所以不用补充。

B中,b是char为1,b前面补充了3个字节,由于a是int为4,依据准则1,起始位置要为4的倍数,所以b前面要补充3个字节。

c前面补充两个字节,依据准则3,整个B占用空间要为4的倍数,c前面不补充,整个B的空间为10,不符,所以要补充2个字节。

再看一个结构中含有结导致员的例子: 例3:struct A{ int a; double b; float c;};struct B{ char e[2]; int f; double g; short h; struct A i;}; sizeof(A) = 24; 这个比拟好了解,int为4,double为8,float为4,总长为8的倍数,补齐,所以整个A为24。

sizeof(B) = 48; 看看B的内存规划。

e f ghi B的内存规划:11* *, 1111, , 11 * * * * * *,1111* * * *, , 1111 * * * * i其实就是A的内存规划。

i的起始位置要为24的倍数,所以h前面要补齐。

把B的内存规划弄分明,无关结构体的对齐模式基本就算把握了。

以上讲的都是没有#pragma pack宏的状况,假设有#pragma pack宏,对齐模式依照宏的定义来。

比如上方的结构体前加#pragma pack(1),内存的规划就会齐全扭转。

sizeof(A) = 16; sizeof(B) = 32; 有了#pragma pack(1),内存不会再遵照准则1和准则3了,按1字节对齐。

没错,这不是现实中的没有内存对齐的环球吗。

ab c A的内存规划:1111, , 1111 ef gh i B的内存规划:11, 1111, , 11 ,1111, , 1111 那#pragma pack(2)的结果又是多少呢?#pragma pack(4)呢?留给大家自己思索吧,置信没有疑问。

还有一种经常出现的状况,结构体中含位域字段。

位域成员不能独自被取sizeof值。

C99规则int、unsigned int和bool可以作为位域类型,但编译器简直都对此作了裁减,准许其它类型类型的存在。

经常使用位域的关键目标是紧缩存储,其大抵规则为: 1) 假设相邻位域字段的类型相反,且其位宽之和小于类型的sizeof大小,则前面的字段将紧邻前一个字段存储,直到不能容纳为止; 2) 假设相邻位域字段的类型相反,但其位宽之和大于类型的sizeof大小,则前面的字段将重新的存储单元开局,其偏移量为其类型大小的整数倍; 3) 假设相邻的位域字段的类型不同,则各编译器的详细成功有差异,VC6采取不紧缩模式,Dev-C++采取紧缩模式; 4) 假设位域字段之间交叉着非位域字段,则不启动紧缩; 5) 整个结构体的总大小为最宽基本类型成员大小的整数倍。

还是让咱们来看看例子。

例4:struct A{ char f1 : 3; char f2 : 4; char f3 : 5; }; a b c A的内存规划:111,1111 *, * * * 位域类型为char,第1个字节仅能容纳下f1和f2,所以f2被紧缩到第1个字节中,而f3只能从下一个字节开局。

因此sizeof(A)的结果为2。

例5:struct B{ char f1 : 3; short f2 : 4; char f3 : 5; }; 由于相邻位域类型不同,在VC6中其sizeof为6,在Dev-C++中为2。

例6:struct C{ char f1 : 3; char f2; char f3 : 5; }; 非位域字段交叉在其中,不会发生紧缩,在VC6和Dev-C++中失掉的大小均为3。

思索一个疑问,为什么要设计内存对齐的解决模式呢?假设体系结构是不对齐的,成员将会一个挨一个存储,显然对齐更糜费了空间。

那么为什么要经常使用对齐呢?体系结构的对齐和不对齐,是在期间和空间上的一个掂量。

对齐节俭了期间。

假定一集体系结构的字长为w,那么它同时就假定了在这种体系结构上对宽度为w的数据的解决最频繁也是最关键的。

它的设计也是从优先提高对w位数据操作的效率来思索的。

有兴味的可以google一下,人家就可以跟你解释的,一大堆的情理。

最后顺便提一点,在设计结构体的时刻,普通会尊照一个习气,就是把占用空间小的类型排在前面,占用空间大的类型排在前面,这样可以相对浪费一些对齐空间。

本篇文章起源于:开发学院原文链接:

C言语什么是位段,位段的定义求答案

位段(bit-field)是以位为单位来定义结构体(或联结体)中的成员变量所占的空间。

含有位段的结构体(联结体)称为位段结构。

驳回位段结构既能够节俭空间,又繁难于操作。

位段的定义格局为:

type [var]:digits

其中type只能为int,unsigned int,signed int三种类型(int型能不能示意正数视编译器而定)。

位段称号var是可选参数,即可以省略。

digits示意该位段所占的二进制位数。

那么定义一个位段结构可以像上方这段代码去定义:

C言语结构体位域的繁难引见

结构体在C言语中是一种复合数据类型,准许蕴含多种数据类型,似乎在校生消息表。

例如:申明结构体模式为:在32位操作系统中,经常使用sizeof函数失掉结构体占用的字节大小。

例如:了解结构体占用字节大小时,需思索数据类型所占字节数。

例如:结构体的内存对齐是指CPU以32位(4字节)为单位启动数据访问。

若数据类型大小超出32位,CPU将分屡次访问。

例如:以字符型变量为例,若紧随其后为整型变量,结构体总大小及各变量地址偏移将受影响。

例如:结构体位域准许自定义每个成员的位宽,以字节为单位,成功内存应用最大化。

例如:在位域中重新定义成员位宽,结构体总大小等于一切成员位宽之和。

例如:结构体位域在实践编程中用于提升内存经常使用,实用于对内存资源敏感的运行场景。

例如:

你可能想看:
« 上一篇
下一篇 »

相关推荐

FreeBasic:强大免费开源的64位basic编译器及应用优势

2025年05月10日

82阅读

脊柱侧弯矫正方法大盘点:运动康复、支具矫正等多种方式

2025年05月09日

87阅读

如何在winForm标题栏去掉标题文字且任务栏图标正常显示

2025年05月09日

86阅读

十一黄金周促销广告词大全,国庆购物狂欢等你来

2025年05月09日

78阅读

关闭快速编辑模式及插入模式,设置控制台指定文字颜色举例

2025年05月09日

63阅读

黄金搭档低糖高钙饮品包装及成分功效全解析,适合人群要知晓

2025年05月09日

91阅读