• Sword 位域知识点


    有些数据在存储时并不需要占用一个完整的字节,只需要占用一个或几个二进制位即可。
    例如开关只有通电和断电两种状态,用 01 表示足以,也就是用一个二进位。
    正是基于这种考虑,C语言又提供了一种叫做位域的数据结构。
    在结构体定义时,我们可以指定某个成员变量所占用的二进制位数(Bit),这就是位域。请看下面的例子:
    struct bs{
        unsigned m;
        unsigned n: 4;
        unsigned char ch: 6;
    };
    :后面的数字用来限定成员变量占用的位数。成员 m 没有限制,根据数据类型即可推算出它占用 4 个字节(Byte)的内存。
    成员 n、ch 被:后面的数字限制,不能再根据数据类型计算长度,它们分别占用 46 位(Bit)的内存。
    C语言标准还规定,只有有限的几种数据类型可以用于位域。
    在 ANSI C 中,这几种数据类型是 int、signed int 和 unsigned intint 默认就是 signed int);到了 C99,_Bool 也被支持了。 但编译器在具体实现时都进行了扩展,额外支持了 char、signed char、unsigned char 以及 enum 类型,
    所以上面的代码虽然不符合C语言标准,但它依然能够被编译器支持。
    位域的存储
    C语言标准并没有规定位域的具体存储方式,不同的编译器有不同的实现,但它们都尽量压缩存储空间。
    
    位域的具体存储规则如下:
    1) 当相邻成员的类型相同时,如果它们的位宽之和小于类型的 sizeof 大小,那么后面的成员紧邻前一个成员存储,
    直到不能容纳为止;如果它们的位宽之和大于类型的 sizeof 大小,那么后面的成员将从新的存储单元开始,其偏移量为类型大小的整数倍。 2) 当相邻成员的类型不同时,不同的编译器有不同的实现方案,GCC 会压缩存储,而 VC/VS 不会。
    /* 位域与结构体内存对齐 */
    #include <stdio.h>
    #include <stdlib.h>
    
    struct Student
    {
        char c;
        unsigned int      no;
        unsigned char     i : 1;
        unsigned char     j : 1;
        unsigned char     k : 6;
        unsigned char     m : 2;
    };
    
    /*
    说明: i,j,k三个属性占用一个 unsigned char 大小
    m占用一个 unsigned char 大小
     
    */
    
    void test()
    {
        printf("----size[%d]-------
    ", sizeof(Student));    //占用12字节大小
    }
    
    int main()
    {
        test();
        getchar();
        return 0;
    }
  • 相关阅读:
    git 一般的使用操作
    php 导出excel,csv
    安装sublime_text_3
    安装mongodb记录,mongo基本命令记录
    redis 安装记录
    YII2 activeform样式修改
    go 安装下载
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.hbsjz/com.hbsjz.BaseMapActivity}:
    SQLServer创建触发器,更新表
    SQL Server触发器创建、删除、修改、查看示例步骤
  • 原文地址:https://www.cnblogs.com/zhanggaofeng/p/12722848.html
Copyright © 2020-2023  润新知