从一个例子说起:

    int main(void){
union{
int i;
struct{
char a : ;
char b : ;
char c : ;
}bits;
}num; printf("Input an integer for i(0~15): ");
scanf("%d", &num.i);
printf("i = %d, cba = %d %d %d\n", num.i, num.bits.c, num.bits.b, num.bits.a);
return ;
} 输入i值为11,则输出为i = , cba = - - -。 为什么? ,位域的定义 在结构体的定义中,指定元素所占用的bit数, 并指定类型。 按照结构体的成员调用方式进行调用。 ,位域的内存对应规则 一个字节按照从高位到低位 bit7 ~ bit0,对于位域的定义,是从低位bit0 开始算起的(注意不是从高位开始对应)。也就是说,上面例子中的位域,在一个字节中对应的存储是 ccba, a在最低位,然后是b,和占两个bit的c。 c成员中按照bit3高位、bit2低位存储。 ,大小端问题 对于小端来说,低字节存放在低地址中,int的存储从0x00地址到0x03地址,依次是 。 联合体从头开始,是对内存中数据的截断和强转, 根据刚才位域的存储结构,cc的截断是10, b和a的截断都是1。 ,为什么打印出来是负数? ---》补码的规则 在计算机的内存中,所有的数据存储都是按照补码存储的。 对于有符号数来说,正数的补码是正数自身,负数的补码是反码+。这都没问题。 问题的核心还是符号位。计算机里从低精度数向高精度数转换时,比如从char到short, 又比如这里从10两个bit填充为一个char的8个bit, 肯定会在前面扩展一些bit位,从而达到高精度数的长度。那么扩展时,是补0还是补1呢?这里有个原则就是,有符号数扩展符号位,无符号数扩展0。对应到这里也就是1。注意,这里说的是有符号数和无符号数,对于有符号的正数,因为符号位是0,所以也是补零。然而我们在位域的定义中,定义了abc都是有符号的char型。所以在向8位扩展时,因为第一位都是1,所以往前都扩展1,a和b在内存中为11111111, c为11111110,都是补码。按照%d打印出来以后, 就是- 和 -。 如果这里定义成 unsigned char,按照定义前面补0,打印结果就会是正数了。

最新文章

  1. 玩儿转物联网IoT - 在Beagle Bone Black上运行node.js 程序
  2. BZOJ3564 : [SHOI2014]信号增幅仪
  3. 实现loading动画效果
  4. Android源码是这样搞到的(图解)
  5. Android - 折线图
  6. Android摄像头抓取图像的格式
  7. C#中操作WMI的类库-实现远程登录共享
  8. (数字IC)低功耗设计入门(一)
  9. AMD && CMD
  10. ELK学习总结(2-2)单模式CRUD操作
  11. 元组tuple插入字符串的方式
  12. 9.Git分支-分支的创建与合并-02
  13. JS拖拽div(移动)
  14. chrome离线包出现的小问题
  15. Nginx使用教程(四):提高Nginx网络吞吐量之buffers优化
  16. 淘淘商城之spring web mvc架构
  17. day 27 异常处理
  18. python for
  19. 从您的帐户中删除 App 及 iTunes Connect 开发人员帮助
  20. CCF CSP 201509-2 日期计算

热门文章

  1. react native 示例代码
  2. RVDS编译器
  3. CATiledLayer
  4. redis安装及注意事项
  5. 左连接LEFT JOIN 连接自己时的查询结果测试
  6. 有趣的js匿名函数写法(function嵌套)
  7. 远程获得的有趣的linux命令
  8. margin显示怪异,外边距合并问题
  9. maven parent工程.pom修改后未自动更新
  10. keepalived+nginx实现HA高可用的web负载均衡