位域实践
有如下代码:
1: #include <stdio.h> 2: 3: #include <string.h>
4: 5: #include <malloc.h> 6: 7: #include <stdlib.h> 8: 9: typedef struct AA
10: 11: { 12: 13: int b1:5;
14: 15: int b2:2;
16: 17: }AA; 18: 19: int main(){
20: 21: AA aa; 22: 23: char cc[100];
24: 25: strcpy_s(cc,"0123456789abcdefghijklmnopqrstuvwxyz\0");
26: 27: printf("%d\n",sizeof(cc));
28: 29: printf(" %d \n",sizeof(AA));
30: 31: memcpy(&aa,cc,sizeof(AA));
32: 33: printf("aa.b1 = %d\n",aa.b1);
34: 35: printf("aa.b2 = %d\n",aa.b2);
36: 37: system("pause");
38: 39: }运行结果:
当时对这个结果非常的费解,memcpy(&aa,cc,sizeof(AA)); 将会从数组cc中拷贝4个字节到结构体aa中,拷贝过后的结果如下图所示,其中的0x30、0x31、0x32、0x33分别是"0123"的
码(注意:字符在内存中是按照ASCII值存放的)。
由于intel是Little endian(小高高),小端格式+高位存放在高地址,所以b1和b2一起占据了第一个字节的前七位,由于第一字节0x30=0011 0000,所以b1=1 0000,b2=01,由于在输出的时候要进行符号位的扩展,所以b1=0xffff fff0=-16,b2=0x0000 0001=1,这就是上面的输出结果。
下面的截图来自:C: in a nutshell
其实我们可能不希望由于符号位的扩展而导致正数变成负数,这就需要将位域的类型定义为unsigned int,如下所示:
这样输出结果就是16和1了,如下图所示:
位域的大小
上面结构的大小是4.
上面结构的大小是1.
以上结果都是在VS2008中得到的。
空位域:
定义为unsigned int :0,表示从下一个边界开始存放。
Sizeof(AA)为:16
如果不用空位域,着sizeof(AA)为12,如下图所示:
注意:每一个位域的大小不能够超过了其自身类型的大小,如下面的定义是错误的:
参考资料:






![clip_image004[1] clip_image004[1]](https://images.cnblogs.com/cnblogs_com/justinzhang/201107/201107182030081182.png)





浙公网安备 33010602011771号