免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 7230 | 回复: 4
打印 上一主题 下一主题

【结帖】与联合体,结构体相关的位域问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-05-09 08:07 |只看该作者 |倒序浏览
#include<stdio.h>
#include<stdlib.h>

int  main(void)
{
        union A{
             char a;
             char y:3;
             char z:3;
             char x:2;
        }a;

        a.a = 0x67;
        printf("a.a =%0x a.x=%0x \t a.y=%0x\t a.z=%0x\n",a.a, a.x, a.y, a.z );
        return 0;
}
结果
a.a =67 a.x=ffffffff     a.y=ffffffff    a.z=ffffffff
a.a =64 a.x=0    a.y=fffffffc    a.z=fffffffc
a.a =65 a.x=1    a.y=fffffffd    a.z=fffffffd

很久没动c语言了,很多基础性的东西都没有深入学习。今天看到关于联合体位域面试题,想了半天才知道程序答案的来由~~汗颜~~
如果单从位域来理解这个还是简单,问题的关键是理解其在计算机内的存取规则。
对a.a=64, 单从取位(二进制)上可知a.x=00, a.y=101, a.z=101.目前通用计算机x86大都是32位机,我的机器也是32位,在存取上默认是存取32位。对每个数而言第一位是符号位,补码存储。那么可以理解a.x的补码就是00000000, a.y的补码就是11111100, a.z的补码就是11111100.这样看比较自然,但如果输出结果是10进制,就会觉得难以理解。当然关键还是对数据的存取规则和编码的熟悉。
a.a=0x64的10进制结果是a.x=0, a.y=-4 ,a.z=-4
补充一点,union内的变量顺序对结果不影响(每次只可能有一种解释是合理的,这个跟struct显然不同)

关于位域在结构体的应用主要要注意内存对齐规则的理解和空域的理解
http://blog.csdn.net/jiyucn/archive/2006/07/01/862085.aspx
使用位域的主要目的是压缩存储,其大致规则为:
1)  如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止;  
2)  如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍;  
3)  如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6采取不压缩方式,Dev-C++采取压缩方式;  
4)  如果位域字段之间穿插着非位域字段,则不进行压缩;  
5)  整个结构体的总大小为最宽基本类型成员大小的整数倍。

#include <stdio.h>
int main()
{
    union
    {
               struct
               {
                         unsigned short s1:3;
                         unsigned short s2:3;
                         unsigned short s3:3;
               }x;
               char c;
    }v;
    v.c=100;

    printf("%d\n",sizeof(v));
    printf("s1=%d\n",v.x.s1);
    printf("s2=%d\n",v.x.s2);
    printf("s3=%d\n",v.x.s3);
    return 0;
}
fc6--linux下gcc-4.1.1
2
s1=4
s2=4
s3=5
windows xp2下vc6.0
2
s1=4
s2=4
s3=1

可见s3的结果并不一样vc6.0的结果如果只是按位取,就很好理解,这样跟之前的union的存取规则又不一样了~~而对于gcc-4.1.1,s3=5还没想出该结果的原因。同时考虑
        struct
               {
                         unsigned short s1:3;
                         unsigned short s2:3;
                         unsigned short s3:3;
                         unsigned short s4:7;
               }x;
       最后s4的结果更加扑朔迷离~~请大家多指点~·

[ 本帖最后由 fertiland 于 2007-5-17 10:51 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2007-05-09 17:19 |只看该作者
你这里v.c=100;只赋值了1byte,对于另外一byte没有赋值。
没有赋值的数据,它的值有随机性,没什么可奇怪的。

论坛徽章:
0
3 [报告]
发表于 2007-05-09 20:10 |只看该作者
恩,谢谢2楼提醒~~(脸丢大了,我运行了很多次显示同一个结果,就把这个基础给忽略了,重起系统结果就不同了).
有关位域的联合和结构体的存储规则,大家有相关的资料吗~~

[ 本帖最后由 fertiland 于 2007-5-9 20:14 编辑 ]

论坛徽章:
0
4 [报告]
发表于 2007-05-09 20:16 |只看该作者
任何一本讲C语言的书应该都有,但是位域几乎没有任何规则,只是说可以节省空间,时间换空间。

论坛徽章:
0
5 [报告]
发表于 2007-05-11 23:32 |只看该作者
如果你可以不用,尽量不要在自己的程序中使用它,这跟对齐方式有很大的关系。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP