《C语言笔记:位操作相关》

一,位操作一般用法

  1,特定位清零用“&”。

    要想把一个数的特定位清零,就需要构造另一个数,这个数的对应特定位为0,其他位为1。2

  2,特定位置1用“|”。

    要想把一个数的特定位置1(设置特定位),就需要构造另一个数,这个数的对应特定位为1,其他位为0。

  3,特定位取反用“^”。

    要想把一个数的特定位取反,就需要构造另一个数,这个数的对应特定位为1,其他位为0。

二,如何构造“另一个数”。

  1,如果这个数比较少位为“1”,大部分为“0”,则可以通过连续多“1”左移n位得到。

  2,如果这个数比较少位为“0”,大部分为“1”,则可以先通过构建其位反数,然后再位取反来得到。

  3,如果想要构造的数中连续1(连续0)的部分不止一个,那么可以通过多段分别构造,然后再彼此位或即可。

三,位运算实战。

  1,给定一个整数型a,设置a的bit3,同时保证其他位不变。

    a |= (0x1<<3);

  2,给定一个整数型a,设置a的bit3~bit7,同时保证其他位不变。

    a |= (0x1f<<3);

  3,给定一个整数型a,清除a的bit15,同时保证其他位不变。

    a &= (~(0x1<<15));

  4,给定一个整数型a,清除a的bit15~bit23,同时保证其他位不变。

    a &= (~(0x1ff<<15));

  5,给出一个整数型a,取出bit3~bit8。

    第一步:先把bit3~bit8保持不变,其他位清零。

        a &= ((0x3f<<3)) ;

    第二步:再将其右移3位得到结果。

        a>>3;

  6,给一个寄存器的bit7~bit17赋值937(其他位不受影响)。

    关键点:第一,不能影响其他位,第二,并不知道bit7-bit17中原来的值。

    第一步:对于关键点二,得先把bit7~bit17清零。

      a &= (~(0x7ff<<7));

    第二步:将937写到对应位。

      a |= (937<<7);

  7,将一个寄存器的bit7~bit17的值加17(其他位不受影响)。

    第一步:先读出对应位的数。

      data = (a & (0x7ff<<7))>>7;

    第二步:data  += 17;

    第三步:对应位清零。

      a &= (~(0x7ff<<7));

    第四步: a |= (data<<7);

  8,给一个寄存器的bit7~bit17赋值937,给一个寄存器的bit21~bit25赋值17(其他位不受影响)。

    两次第6题。

    a &= (~(0x7ff<<7) | ~(0x1f<<21));

    a |= ((937<<7) | (17<<21))

  9,宏实现置位,复位。(一般笔试题中规定的是最右边为第一位)

    #define SET_BIT(x,n)  (x|((1U)<<(n-1)))

    #define CLEAR_BIT(x,n) ((x & ~((1U)<<(n-1))))

  10,截取变量的部分连续位。比如变量0x88,即0x10001000b,若截取第2~4位,则值为100b = 4。

    #define GETBITS(x,n,m) ((x & ~(~(0U)<<(m-n+1))<<(n-1))>>(n-1))

    分析:

      #define GETBITS(x,n,m)   ((x    &    ~(~(0U)<<(m-n+1))   <<(n-1))   >>(n-1))

      第一次分解:

        (x & ~(~(0U)<<(m-n+1)) <<(n-1))                    >>         (n-1))

      第二次分解:

        x                              &                                        ~(~(0U)<<(m-n+1)) <<(n-1)

      第三次分解:

         ~(~(0U)<<(m-n+1))                                        <<         (n-1)

       ~(~(0U)<<(m-n+1)):得到连续(m-n+1)个1的数 。

      ~(~(0U)<<(m-n+1)) << (n-1):将连续(m-n+1)个1的数 移动到对应连续位处。

      (x & ~(~(0U)<<(m-n+1)) <<(n-1)):取出对应位处的位值。

      (x & ~(~(0U)<<(m-n+1)) <<(n-1)) >> (n-1)):得到所求连续位的值。

#include <stdio.h>

#define GETBITS(x,n,m)    ((x&(~(~(0u)<<(m-n+1))<<(n-1)))>>(n-1))
#define CLEARBITS(x,n,m)   (x&(~((~(~(0u)<<(m-n+1)))<<(n-1))))
#define SETBITS(x,n,m)    (x|(~(~(0u)<<(m-n+1)))<<(n-1))

int main()
{
    int a = 0x88;

    printf("  %d  \n",GETBITS(a,2,4));    //4

    a = 0xff;
    
    printf(" 0x%x  \n ",CLEARBITS(a,2,4));  // 0xf1

    a = 0xf1;
    
    printf(" 0x%x  \n",SETBITS(a,2,4));     //0xff
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程界的小学生、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值