天天看点

C语言 位段的相关知识

位段的相关知识:

1. 位段被当作是有符号数,还是无符号数;

2. 位段中位的最大数目;

3. 位段中成员在内存中的分配方式(从左到右,还是从右到左);

直接贴代码:

#include <stdio.h>

#include <string.h>

#include <malloc.h>

typedef struct pid_tag

{

unsigned refcount : 6;

unsigned inactive : 1;

unsigned reactive : 2;

} radish;

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

/*

对上面的具体解释: 一个位段必须存储在同一个存储单元中,不能跨两个单元.

如果某存储单元空间中不能容纳下一个位段,则改空间不用,而从下一个存储单元起存放该位段.

结构体A中的h和y就是这种情况.在gcc环境下,测试后,一个存储单元为4个字节.

*/

typedef struct _S

{

unsigned a:4;

unsigned b: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 b:4;

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

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

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

void bit_test()

{

A a;

S s;

T t;

V v;

char ch = 0x00;

printf("Bit Struct Test:/n");

printf("sizeof(a)=%d/n", sizeof(a));

printf("sizeof(s)=%u/nsizeof(t)=%u/n", sizeof(s), sizeof(t));

printf("sizeof(v)=%d/n", sizeof(v));

((radish*)(&ch))->refcount = 0x3f;

((radish*)(&ch))->inactive = 0x1;

((radish*)(&ch))->reactive = 0x1;

// 赋值以后:ch = 0xff

}