位域

#include <stdio.h>
#include <stdlib.h>
//位字段:嵌入式的物联网设备开发,需要节约内存,可以使用位字段,用来限定某个结构如变量的二进制位
struct dateE{
    unsigned int day;  // day只有1-31的取值,无需用到4个字节,浪费了内存  2^5=32  5个二进制位就足够了
    unsigned int month; // month只有1-12的取值,无需用到4个字节,浪费了内存  2^4=32  4个二进制位就足够了
    unsigned int year;  // 只有0000-9999 的取值,无需用到4个字节,浪费了内存  2^14=16384  14个二进制位就足够了
};

struct date{   //相比上面的定义,date结构体只有4个字节,大大节约了内存空间
    unsigned int day : 5;  // day只有1-31的取值,无需用到4个字节,浪费了内存  2^5=32  5个二进制位就足够了
    unsigned int month : 4; // month只有1-12的取值,无需用到4个字节,浪费了内存  2^4=32  4个二进制位就足够了
    unsigned int year :14;  // 只有0000-9999 的取值,无需用到4个字节,浪费了内存  2^14=16384  14个二进制位就足够了
};
//为什么是4个字节呢?因为考虑到内存字节对齐的问题
// 占用5位  1111 1 000     1个字节,不足补0
// 占用4位  1111 0000      1个字节,不足补0
// 占用14位 1111 1111 | 1111 11 00 |  两个字节合并到一起,2个字节,不足补0
// 在结构体中:CPU是按照字节寻址的,字节是CPU访问的最小单位,总共4个字节
//在限定位数的结构体——位域中,CPU是按位运算寻址的,不是按字节
void main1(){
    printf("%d\n", sizeof(struct dateE));  //12
    printf("%d\n", sizeof(struct date));  //4  结构体对齐
};

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//位字段的注意事项
//如果两个字符之和小于8位,会自动填充一个字节,通位操作操作位字段
//1(1位) 11111(5位) 00 1代表其占用的位,一个字节存储两个位域变量ch1,ch2
//int占用4个字节,虽然只有一位使用,后面的会默认为0,且无法使用这些0
//结构体前面的char类型为了和int字节对齐,后面补0,也对应四个字节,总共8个字节
//1 11111 00     00000000    00000000    00000000   4个字节
//1 00000000    00000000    00000000    00000000    4个字节
struct data{
    unsigned char ch1 : 1;  //结构体限定了位数,越界会溢出
    unsigned char ch2 : 2;
   // unsigned char ch3 : 10; 位字段不能超过类型的大小8个位
   // unsigned char ch4 : 0; 位字段不能为0
    int num : 1;

};
void main(){
    printf("%d\n", sizeof(struct data)); //8个字节
    struct data data1;
    data1.ch1 =2;
    data1.num =2;
    printf("%d\n",data1.ch1);  //0  2的二进制位10,而ch1只能处理以为,溢出,输出0
    printf("%d\n",data1.num);  //0 虽然num占用4个字节,但是后面的0无法利用, 2的二进制位10,而ch1只能处理以为,溢出,输出0


    //取地址
    printf("%p\n",data1); //可以去结构体的地址
    printf("%p\n",data1.ch1); //错误,不可以取位域的地址
    //位域是通过位运算来实现,无法取出位域的地址(一个字节存储两个位域变量ch1,ch2)

}

 

posted @ 2019-08-13 17:50  Coding_Changes_LIfe  阅读(625)  评论(0编辑  收藏  举报