也谈C/C++中的位域

来源:互联网 发布:java用户注册界面代码 编辑:程序博客网 时间:2024/06/09 13:03

C/C++中的位域在百度百科里面介绍了一些基础知识,但遗憾的是没有和内存示意相结合,初学者容易理解偏差。
以下内容是假设读者已初步理解掌握了百度百科“位域”的基础上,再加以补充说明:《Soloe@csdn,转载请说明》
1、位域中的变量字段,最小占用是其变量说明的类型在“正常占用”下的大小。
什么意思呢,看下面这个例子:

struct A{    int a:5;    int b:3;};

这里a和b总共占用了8bit,那么这个结构体的大小是否为1字节?
答案是no,笔者电脑上 sizeof(A) 结果为4,这是因为在x86下int占4个字节。

2、继续前面的案例,a和b在这四个字节中处于哪个位置?
高位 低位

高位 低位 00000100 00000011 00000001 00000000 bbbaaaaaa

答案如上图所示,a占了最低位的5个bit,b占了a左边的3个比特

3、从结构体位域转换成正常变量,需要注意哪些事项:
看下面的例子:

#include <iostream>#include <memory.h>using namespace std;struct A{    int a:5;    int b:3;};int main(void){    char str[100] = "0134324324afsadfsdlfjlsdjfl";    struct A d;    memcpy(&d, str, sizeof(A));    cout << d.a << endl;    cout << d.b << endl;    return 0;}

输出是多少?
答案是:

-161

原因是int a和int b是有符号数,要注意符号位的扩展。

高位 低位 00000100 00000011 00000001 00000000 ‘4’ ‘3’ ‘2’ ‘1’

其中d.a和d.b占用d低位一个字节(00110000),d.a : 10000, d.b : 001
d.a内存中二进制表示为10000,由于d.a为有符号的整型变量,输出时要对符号位进行扩展,所以结果为-16(二进制为11111111111111111111111111110000)

d.b内存中二进制表示为001,由于d.b为有符号的整型变量,输出时要对符号位进行扩展,所以结果为1(二进制为00000000000000000000000000000001)

《Soloe@csdn,转载请说明》
最后给出一个面试的案例:

struct mybitfields{    unsigned short a : 4;    unsigned short b : 5;    unsigned short c : 7;} testvoid main(void){    int i;    test.a=2;    test.b=3;    test.c=0;    i=*((short *)&test);    printf("%d\n",i);}

聪明的你,能直接在评论中给出答案吗?

0 0
原创粉丝点击