位段与字节对齐

来源:互联网 发布:复杂网络路由是算法 编辑:程序博客网 时间:2024/06/05 09:14

所谓位段就是以位为单位定义长度的结构体类型的成员。

例如:

  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)  */

 

以上是我对位段和对齐的理解,希望大家多多纠错,共同进步!

 

 

原创粉丝点击