首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

位域,该怎么处理

2012-04-19 
位域问题1:C/C++ code//环境是VC 6.0#includestdio.hstruct myStruct{unsigned char a :8unsigned char

位域
问题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是两字节 整个结构体的总大小为最宽基本类型成员大小的整数倍。
探讨

引用:

举例
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……

那……

------解决方案--------------------


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

热点排行