• 【技巧】通过结构体进行的位操作



    位域

    通过定义相应位域的结构体指针,来访问变量的相应位域数据:

    #include <stdio.h>
    
    struct byte {//由低至高
    	int a:4;
    	int b:4;
    	int c:4;
    	int d:4;
    }* p;
    
    void main(){
    	short int b =0xf1ff;
    	p = (struct byte*)&b;
    	printf("%d
    ",&b);	printf("%d
    ",p);//输出起始字节地址
    	printf("%x
    ",p->c);//访问 b 的第 9 到第 12 位
    }
    
    

    输出:

    1703724
    1703724
    1


    一个小错误

    将:

    	short int b =0xf1ff;
    

    改为:

    	short int b =0xf8ff;
    
    #include <stdio.h>
    
    struct byte {//由低至高
    	int a:4;
    	int b:4;
    	int c:4;
    	int d:4;
    }* p;
    
    void main(){
    	short int b =0xf8ff;
    	p = (struct byte*)&b;
    	printf("%d
    ",&b);	printf("%d
    ",p);//输出起始字节地址
    	printf("%x
    ",p->c);//访问 b 的第 9 到第 12 位
    }
    
    

    输出不符合预期:

    1703724
    1703724
    fffffff8

    为什么?


    若改为:

    	short int b =0xf7ff;
    

    输出正常:

    1703724
    1703724
    7

    为什么 7 正常,而 8 就出问题?
    实际上 8 - F 都会有问题。


    错误在结构体的定义中:

    struct byte {//由低至高
    	int a:4;
    	int b:4;
    	int c:4;
    	int d:4;
    };
    

    8 的原码为 1 0 0 0,而 int 是 signed 类型,那么首位即为符号位。
    符号位为 1 时转 int ,会在高位全部填充1,即 1111 1111 1111 1000,格式化%x输出即为 fffffff8。

    而 7 的原码为 0 1 1 1,
    符号位为 0 时转 int ,高位全部填充 0 ,也就是 0000 0000 0000 0111,格式化%x输出即为 7。

    解决方法1:定义unsigned

    struct byte {//由低至高
    	unsigned int a:4;//可以不是int ,char ,long , long long等均可
    	unsigned int b:4;//如果仅操作而不输出,float ,bool ,double等所有类型均可
    	unsigned int c:4;
    	unsigned int d:4;
    };
    

    解决方法2:输出时转类型

    	printf("%x
    ",(unsigned int)p->c);
    //其他类型也可,取决于程序员你的要求
    
  • 相关阅读:
    yum安装8.0mysql数据库
    free命令详细介绍
    linux 自定义美女欢迎界面
    shll脚本常用格式和规则使用
    liunx常用知识基本命令大全
    liunx系统二进制包安装编译mysql数据库
    CentOS7更改网卡名称
    老男孩教育100道面试题
    非关系型数据库(NoSQL)
    iptables
  • 原文地址:https://www.cnblogs.com/gaolihai/p/13149769.html
Copyright © 2020-2023  润新知