C结构体中位域的一点小知识,最近在看资料时遇到结构体中的一种特殊操作——位域,在下面的程序中我将根据自己的理解进行简单介绍。程序只是为了了解位域的一些性质,运行时有些编译器可能会报错。

  程序代码如下(C++编写),编译器使用的是C-Free,整型变量占4个字节。(由于刚接触,如有错误,还请大家指正。)

 #include<iostream>
 using namespace std; 

 struct bit {
     ;
     ;
     ;
 };

 int main () {
     struct bit s;
     char *c = (char*)&s;
     cout<<sizeof(s)<<endl;
     *c = 0x99;
     *(c+) = 0x97;
     cout<<s.a<<endl<<s.b<<endl<<s.c<<endl;
     ;
 }

  程序第5-7行使用到了位域,成员a、b、c虽为整型,但是却明确限制了实际的长度,其中a为3个二进制位,b为2个二进制位,c为3个二进制位。程序的执行结果如下:

  第一个表示结构体的长度,由于3个成员实际都没有占用4个字节,所以实际的长度不是12。下面搞清了a、b、c实际的存储关系后就更加清楚了,位域变量在实际存储中是逆序存储的(不知道为什么),则实际的存储情况如图:3个变量一起正好组成一个字节的长度,程序第14行,*c=0x99,则:a = 001B,b = 11B,c = 100B。由于3个数都是整型,默认是带符号的,故a为1,b为-1,c为-4。

  如果是这样,那如果3个变量的长度多于8个二进制位呢,将结构体修改为如下(将b的二进制位改为3):

 struct bit {
     ;
     ;
     ;
 };

  这种情况下又该如何存储呢?由于一个字节不足以存放3个变量,那么c是分两个字节存储,还是直接存储在下一个字节的低位呢?运行上述程序,得到结果如下:

  c的结果是-2,如果是存储在下一个字节的话,c = 111B,对应的整型数应该为-1,但实际为-2,说明不是这种方式。在看分两个字节存储的方式,在这种方式下c = 110B,正好是-2。为了进一步确认,将程序第14行的赋值操作改为:*c = 0x59;

  执行后结果如下:

  这说明是分两个字节存储的,存储位置如下:

  由于编译器不同,处理的方式也有可能不同。

C结构体中位域的更多相关文章

  1. C结构体之位域(位段)

    C结构体之位域(位段) 有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位.例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可.为了节省存储空间,并使处理简便,C ...

  2. c语言结构体中的冒号的用法

    结构体中常见的冒号的用法是表示位域. 有些信息在存储时,并不需要占用一个完整的字节,   而只需占几个或一个二进制位.例如在存放一个开关量时,只有0和1   两种状态,   用一位二进位即可.为了节省 ...

  3. C++结构体中sizeof(1)

    sizeof sizeof操作符的作用是返回一个对象或类型名的长度,长度的单位是字节. 返回值的类型是标准库命名为size_t的类型,size_t类型定义在cstddef头文件中,该头文件是C标准库的 ...

  4. [转]C结构体之位域(位段)

    有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位.例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可.为了节省存储空间,并使处理简便,C语言又提供了一种数据结构 ...

  5. C结构体之位域(位段)(转)

    有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位.例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可.为了节省存储空间,并使处理简便,C语言又提供了一种数据结构 ...

  6. C结构体中数据的内存对齐问题

    转自:http://www.cnblogs.com/qwcbeyond/archive/2012/05/08/2490897.html 32位机一般默认4字节对齐(32位机机器字长4字节),64位机一 ...

  7. 问题解决——在结构体中使用set保存结构体数据

    =====================声明========================== 本文原创,转载请明确的注明出处和作者,并保持文章的完整性(包括本声明部分). 本文链接:http:/ ...

  8. C语言 结构体中属性的偏移量计算

    //计算结构体偏移量 #include<stdio.h> #include<stdlib.h> #include<string.h> //详解:对于offscfof ...

  9. C语言 结构体中的成员域偏移量

    //C语言中结构体中的成员域偏移量 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> # ...

随机推荐

  1. Web.config中rewite 节点引起的500.19错误

    刚刚接手一个外包的小项目,客户给了发布后的网站文件和数据库,想在本地搭建一套环境先运行下看看网站原有的效果.数据库还原什么都弄好了,数据库字符串也配置好,部署在本地IIS里面,访问了下,结果看到的是5 ...

  2. UIView添加事件

    UIView *loadView = [[UIControl alloc]initWithFrame:CGRectMake(0,0,320,480)]; loadView.backgroundColo ...

  3. linux中的strings命令简介2

    摘自:http://blog.csdn.net/stpeace/article/details/46641069 linux中的strings命令简介 之前我们聊过linux strings的用法和用 ...

  4. 24点游戏&&速算24点(dfs)

    24点游戏 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Sta ...

  5. swift Dictionary 字典

    // //  main.swift //  字典 // //  Created by zhangbiao on 14-6-15. //  Copyright (c) 2014年 理想. All rig ...

  6. 国内外DNS服务器地址列表

    DNS(Domain Name System)是域名解析服务器的意思,它在互联网的作用是把域名转换成为网络可以识别的IP地址.目前国内电信运营商通过使用DNS劫持的方法,干扰用户正常上网,使得用户无法 ...

  7. 第一个关于ajax的代码

    昨天由于需要,写了第一个需要ajax的程序,之前只是看过相关介绍,没想到这么有用,记录一下,如有错误,还希望大家提出$(document).ready(function () {//获取url中名字为 ...

  8. 使用 Struts2 校验器校验用户注册信息

    基于验证框架的输入校验 一.创建一个struts2项目testValidators.Struts2 初体验:http://www.cnblogs.com/likailan/p/3280820.html ...

  9. ASP.NET 生命周期(原文翻译)

    在网上看到这篇文章,老外写的,里面很多图片挺精致,顺带翻译过来给大家分享下,英语太次好多地方都翻不过来 ASP.NET application and page life cycle Download ...

  10. Java多线程相关知识

    1)wait()  notify()  sleep() sleep是Thread类的函数,wait和notify是Object的函数. sleep的时候keep对象锁,wait的时候release 对 ...