您的位置:首页 > 其它

位段与字节对齐

2011-05-10 23:46 183 查看
所谓位段就是以位为单位定义长度的结构体类型的成员。

例如:

struct Demo

{

unsigned int a:2;

signed int b:2;

unsigned int c:4;

}demo;

Demo一共占用了8位,即一个字节长度。如果对其进行赋值,如:

demo.a = 4;

demo.b = 3;

demo.c = 2;

则打印结果会是 a 0(a两位最大为3,即11);b -1(含符号位);c 2;

定义字段,可以节省许多很多空间,试想,如果有一棋盘坐标需要进行定义,那么应该有坐标是否为空,棋盘棋子类别,棋盘各个方向的权值记录。。。由此,我们可定义以下数据结构:

struct ZuoBao

{

char qizi; //'0' 空, '1' 类型一','2' 类型2...

int rr0;

int rr1;

int rr2;

int rr3;

};

这样累计一下应该是20字节(其中char有三个字节用于对齐);

如果定义位段:

struct ZuoBao

{

unsigned qizi:5; //'0' 空, '1' 类型一','2' 类型2...

unsigned rr:10; //前两位为权值方向,后8位为权值(0----2^8-1)

};

此时这用了15位,4个字节(其实这个unsigned还有好多余地);

其实还有很多用例,比如说TCP协议头部结构,简单聊天程序信息等。。。

前面提到对齐,我对此了解不多。之所以出现这种情况是因为在读数时通常都是读取偶数地址,对于奇数的尽量跳过,一方面一些平台却是从偶数读起,另一方面就是从奇数读起,可能要跨度两次。如果存储单位有int,有short时,为了读取的快速,通常都是以最大(4字节)为一个存储。如以下例子:

struct Demo

{

short c;

int a;

char b;

}demo;

最大的单位为4字节,那么就有c用两个,空两个;a 用四个; b 用一个,空三个

共计12个字节。

当然,如果是

struct Demo

{

int a;

short c;

char b;

}demo;

a 用四个;c和b联合用四个;

共计8个字节。

struct Demo

{

int a;

short c;

char b;

char d;

}demo;

如果多个char(1个字节),这是d和c,d正好用4个,

共计8个。

struct Demo

{

int a;

short c;

short b;

char d;

}demo;

如果b变为short,这是就多出1个字节,没办法,它要在后面空出三个地址来;

此时共计12个字节。

位段对齐也可以自己设置,

#pragama pack(n) 就是定义了位段对齐的方式,编译器默认情况是4,如果定义n的话,编译器就会以n进行对齐,知道遇到#pragama pack()结束,恢复默认。

eg:

#pragma pack (2)

/* 2个字节的对齐方式 */

#pragma pack () /* 恢复编译器默认的对齐方式,即#pragma pack (4) */

以上是我对位段和对齐的理解,希望大家多多纠错,共同进步!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: