:x的问题

来源:互联网 发布:淘宝上的费列罗真假 编辑:程序博客网 时间:2024/06/05 11:43

现象

struct Test{UINT32 test1:4;UINT32 test2:2;UINT32 test3:4;UINT32 test4:3;UINT32 test5:4;UINT32 test6:3;UINT32 test7:4;UINT32 test8:2;};


  今日于底层发现如上代码,头一次见到这种“:x”代码,不知何意,写了些代码测试出该如何使用。

过程

  1.首先将其结构增加构造函数如下

struct Test{UINT32 test1:4;UINT32 test2:2;UINT32 test3:4;UINT32 test4:3;UINT32 test5:4;UINT32 test6:3;UINT32 test7:4;UINT32 test8:2;Test(){test1= 0;test2= 0;test3= 0;test4= 0;test5= 0;test6= 0;test7= 0;test8= 0;}};


  2.sizeof(Test)的值为4;

  3.声明一个Test变量,查看内存显示为 00 00 00 cc,说明只初始化了4字节中的头三个字节,依据这个现象,猜测:x中的x是比字节更小的单位,即比特。可以先按照比特来猜测某些操作的结果,如果不成立的话再想另外的可能性。

  4.给变量赋值

Test test;test.test1 = 1;// 01 00 00 cctest.test2 = 2;// 21 00 00 cctest.test3 = 3;// e1 00 00 cc


    来分析下每一步操作都干了什么事情:

    1)声明变量;          内存为00 00 00 cc 二进制为:0000 0000 0000 0000 0000 0000 1100 1100

    2)test.test1 = 1;二进制:1      内存为01 00 00 cc 二进制为:0000 0001 0000 0000 0000 0000 1100 1100

    3)test.test2 = 2;二进制:10   内存为21 00 00 cc 二进制为:0010 0001 0000 0000 0000 0000 1100 1100

    4)test.test3 = 3;二进制:11   内存为e1 00 00 cc 二进制为:1110 0001 0000 0000 0000 0000 1100 1100

    现在很明显:x的x就是这个变量占据的比特位数

    5)test.test4 = 4;二进制:100  内存为e1 10 00 cc 二进制为:1110 0001 00010000 0000 0000 1100 1100

    6)test.test8 = 8;二进制:1000  内存为e1 10 00 cc 二进制为:1110 0001 0001 0000 0000 0000 1100 1100

      test8只能占2bit,高位被截断,所以相当于将00赋值给test8

  5.内存对齐问题:

struct Test1{__int64 test1:30;UINT32 test2:2;};//sizeof(Test1)为16

    1)内存对齐的规则和一般对象的变量相同,只不过:x强制制定了该变量多少位有效,高位的数据统统截断;

    2)是否可以使用该方法使某些类型占的大小变大呢?

struct Test1{__int64 test1:30;UINT32 test2:2;char test3:64;};

      以上代码在编译时就报错:error C2034: “Test1::test3”: 位域类型对位数太小。看来是不可以了。

疑问?

  1.为什么会出现这种用法?

   在使用上,由于某种原因,在业务范围内,Test对象的各个变量都有最大值,这种写法一个对象占4个字节,而按照普通写法一个对象占用8×sizeof(int)=32字节;

   由于不了解汇编,不清楚在使用一个对象时是如何读取内存的。也就不能确定在Windows上这种做法是否效率更高。

   猜测,公司有做硬件,也许对于专门优化过的(有这种优化么?)硬件来说,尽量小的存储空间和传输通道会效率更高?

  2.从上学到现在各种语言也略微看过些,从来就没有发现这种语法,网上也没有查到什么资料,这到底是从哪个石头缝里蹦出来的语法?