天天看点

【C语言位段】C语言位段的特点和应用

将几个 位段变量拼接放入一个16位中,为简便,我让每个字段的值等于它的位段长度。

struct PUD

{

  unsigned int version :4;       //协议版本,version 占用4bit

  unsigned int Vendor_Code :4;   //厂商代码,占用4bit

  unsigned int frame_type:5;     //帧类型, 占用5bit

  unsigned int data_len:11;      //信息段长度, 占用11bit

  unsigned int crane_type:4;     //塔吊类型, 占用4bit

  unsigned int multi_pw:4;       //倍率, 占用4bit

  unsigned int Prot_Type :1;     //保护类型, 占用1bit

  unsigned int Prot_reserved :3; //保留字段,占用3bit

  unsigned int Prot_e_num:4;     //保护区元素个数, 占用4bit

  unsigned int op_mark:1;        //操作标志, 占用1bit

  unsigned int op_reserved :2;   //保留字段, 占用2bit

  unsigned int  incident :3;     //本次事件, 占用3bit

};

struct PUD packet_data;

  int test2;

  packet_data.crane_type=4;   

  packet_data.multi_pw=4;      

  packet_data.Prot_Type=1;    

  packet_data.Prot_reserved=3;

  packet_data.Prot_e_num=4;

  test2=0x00;     //清零

  //从低位填充

  test2=test2|packet_data.Prot_e_num;

  test2=test2|packet_data.Prot_reserved<<4;

  test2=test2|packet_data.Prot_Type<<7;

  test2=test2|packet_data.multi_pw<<8;

  test2=test2|packet_data.Prot_num<<12;

 test2=test2;//test2赋值后没有调用,为了在IAR编译器给test2分配空间,能看到test2的值,加了这一句。

结果:

​​

【C语言位段】C语言位段的特点和应用

#include <stdio.h>

typedef struct _A

{

       unsigned a:4;//位段成员的类型仅能够为unsigned或者int

       unsigned b:4;

       unsigned c:2;

       unsigned d:6;

       unsigned E:1;

       unsigned D:2;

       unsigned T:3;

       unsigned A:9;

       unsigned h:4; //前面已经为31,故4+31>32已超过一个存储单元,所以4在一个新的存储单元存放

       unsigned y:29;//由于前面的4在一个新的存储单元的开头存放,且29+4>32, 故在另一个新的存储单元存放

}A;              //所以最后求出的A的大小是4 + 4 + 4 =12

typedef struct _S

       unsigned a:4;

       unsigned c:22;

       unsigned q:1;

       unsigned h:1;

       //unsigned i:33;  // 错误:‘i’ 的宽度超过它自身的类型

       //unsigned i:1;当多出此行时,该结构体大小由4变为8,因为此行之前正好为32位

} S;

typedef struct _T

{      //当没有占满一个存储单元时,结构体的大小对齐为一个存储单元的大小

       unsigned a:2;

       unsigned b:2;

       unsigned j:1;

       unsigned : 1;//可以定义无名位段,此例中该无名位段占用1位的空间,该空间将不被使用

} T;

typedef struct _V

       unsigned a:1;

       unsigned :0;   //定义长度为0的位段时不能指定名字,否则编译不过

       unsigned d:1;  //定义了0字段后,紧接着的下一个成员从下一个存储单元开始存放;

}V;                                    //此例子中,d前面那个存储单元中的余下的27位中被0填充了

int main()