位域
问题1:
- C/C++ code
//环境是VC 6.0#include<stdio.h>struct myStruct{ unsigned char a :8; unsigned char b :1; unsigned char c :1; unsigned char d :1; unsigned short e :13; unsigned char f :2; unsigned char g :2; unsigned char h :4;}var_t;int main(){ printf("The size = %d\n",sizeof(struct myStruct)); return 0;}
结果是6
为什么是6??我觉得应该是5
问题2:
- C/C++ code
struct myStruct{ int a :8; int b :1; int c :1; int d :1; int e :13; int f :2; int g :2; int h :4;}var_t;int main(){ printf("The size = %d\n",sizeof(struct myStruct)); return 0;}
结果为4
为什么是4呢?而换成下面却是6!!我觉得应该是5
- C/C++ code
struct myStruct{ unsigned short a :8; unsigned short b :1; unsigned short c :1; unsigned short d :1; unsigned short e :13; unsigned short f :2; unsigned short g :2; unsigned short h :4;}var_t;int main(){ printf("The size = %d\n",sizeof(struct myStruct)); return 0;}
[解决办法]
一个位域必须存储在同一个字节中,不能跨两个字节。如一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域。也可以有意使某位域从下一单元开始
[解决办法]
位域成员不能单独被取sizeof值,我们这里要讨论的是含有位域的结构
体的sizeof,只是考虑到其特殊性而将其专门列了出来。
C99规定int、unsigned int和bool可以作为位域类型,但编译器几乎都对此作了扩展,
允许其它类型类型的存在。
使用位域的主要目的是压缩存储,其大致规则为:
1) 如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字
段将紧邻前一个字段存储,直到不能容纳为止;
2) 如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字
段将从新的存储单元开始,其偏移量为其类型大小的整数倍;
3) 如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6采取不压缩方
式,Dev-C++采取压缩方式;
4) 如果位域字段之间穿插着非位域字段,则不进行压缩;
5) 整个结构体的总大小为最宽基本类型成员大小的整数倍。
[解决办法]
同时 位域类型 要考虑字节对齐
[解决办法]
举例
struct myStruct
{
unsigned short a :8;
unsigned short b :1;
unsigned short c :1;
unsigned short d :1;
unsigned short e :13;
unsigned short f :2;
unsigned short g :2;
unsigned short h :4;
}var_t;
a b c d两个字节 e f 两个字节 h本身两个字节(字节对齐) 所以 为6个字节
[解决办法]
VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)”
提醒:
“学习用汇编语言写程序”
和
“VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)”
不是一回事!
不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。
并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。
任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实!
不要写连自己也预测不了结果的代码!
[解决办法]
你理解对了 因为short是两字节 整个结构体的总大小为最宽基本类型成员大小的整数倍。
------解决方案--------------------
bit实际上就是把字节分开显示而已,其他和结构一样
struct myStruct
{
unsigned char a :8;
unsigned char b :1;
unsigned char c :1;
unsigned char d :1;
unsigned short e :13;
unsigned char f :2;
unsigned char g :2;
unsigned char h :4;
}var_t;
相当于
{
unsigned char a; //
unsigned char un1; //bcd
short e;
unsigned char un2; //fgh
}
一共5个字节,但最长的是short,按2字节对齐,是6
struct myStruct
{
int a :8;
int b :1;
int c :1;
int d :1;
int e :13;
int f :2;
int g :2;
int h :4;
}var_t;
一共32位,因此一个int就够了,所以是4
struct myStruct
{
unsigned short a :8;
unsigned short b :1;
unsigned short c :1;
unsigned short d :1;
unsigned short e :13;
unsigned short f :2;
unsigned short g :2;
unsigned short h :4;
}var_t;
相当于
{
short un1;//abcd
short un2; //ef
short un3; //gh
}
显然是6
[解决办法]
了解下结构体对齐吧http://blog.sina.com.cn/s/blog_5f0d72800100sy0v.html