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. GetModuleHandle,AfxGetInstanceHandle使用区别

    当一个文件被映射到调用进程的地址空间时,GetModuleHandle函数得到其中某一模块的句柄. 使用GetModuleHandle函数格式:HMODULE GetModuleHandle( LPC ...

  2. (译)"usermod"命令使用完全指导---15个练习例程截图

    "usermod"命令使用完全指导---15个练习例程截图 By Babin Lonston Under: Linux Commands On: November 11, 2014 ...

  3. 关于清晰讲解linux正则表达式的博文分享

    http://www.cnblogs.com/chengmo/archive/2010/10/10/1847287.html  linux shell 正则表达式(BREs,EREs,PREs)差异比 ...

  4. MindManager_9.1.157使用模板时显示“参数错误”

    每次使用标准模板时都出现这个问题,上网搜索,原来是模板中存在的 “注释”导致的问题.具体原因不详,解决起来也简单,就是繁琐一点.转抄如下: 先找到模板文件夹,共四个文件夹Communcation.Pe ...

  5. cURL.1 手册页

    摘自http://blog.csdn.net/huangxy10/article/details/45717793 cURL.1 手册页 名称 cURL - transfer a URL 摘要 cUR ...

  6. linux shell自定义函数(定义、返回值、变量作用域)介绍

    http://www.jb51.net/article/33899.htm linux shell自定义函数(定义.返回值.变量作用域)介绍 linux shell 可以用户定义函数,然后在shell ...

  7. MySQL --概述--

    Mysql是最流行的关系型数据库管理,在Web应用方面MySQL是最好的RDBMS:关系数据库管理系统 什么是数据库? 数据库(Database)是按照数据结构来组织,存储和管理数据的仓库. 每个数据 ...

  8. OC中如何把字典中的数据拼接成url字符串

    在使用objective-c语言开发iOS应用中,会向服务器通过URL请求一些数据,因此对URL的拼接肯定少不了.而在iOS中,我们一般是通过将字典中的数据拼接成我们要请求的URL字符串,那这个是怎么 ...

  9. Search gold(dp)

    Search gold Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Subm ...

  10. 变形课(dfs)

    变形课 Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 131072/65536K (Java/Other) Total Submissi ...