C语言位操作复习

一.对c语言位操作的复习 2017/11/19 16:50
a&b :相同为1则为1,否则为0 // 特定位清零用&
比如:
举例:假设原来32位寄存器中的值为:0xAAAAAAAA,我们希望将bit8~bit15清零而其他位不变,
可以将这个数与0xFFFF00FF进行位与即可。a=0xAAAAAAAA, b=0xFFFF00FF, c=a&b;
a|b :有1则为1,否则为0 //特定位置1用 |
a^b : 有1则为1,否则为0 //特定位取反用^
常用位运算:与、或、非、移位
位与(&) 位或(|) 位非(取反 ~) 移位(左移<< 右移>>)
使用位运算实现功能
1<<3 等于 0b1000, 即bit3为1
1<<5 等于 0b100000, 即bit5为1
(1<<3)|(1<<5) 等于 0b101000
扩展一下:如何只熄灭中间1颗而点亮旁边2颗
ldr r0, =((0<<3) | (1<<4) | (0<<5))
总结:要置1用|,清零用&,要取反用^,~和<< >>用来构建特定二进制数
(1)如果你要的这个数比较少位为1,大部分位为0,则可通过连续很多个1左移n位得到。
(2)如果你想要的数是比较少位为0,大部分位为1,则可通过先构建其位反数,然后再位取反来得到。举例说明:
1.给定一个整型数a,设置a的bit3,保证其他位不变。 设置即为1,清除即为0
a=a|(1<<3)
2.给定一个整形数a,设置a的bit3~bit7,保持其他位不变。
a=a|(0b11111<<3) == a |= (0x1f<<3) //左移3位说明从bit3开始, 0x1f 表示有连续5位置1
3.保证bit15这个数不变,其余位全部清零。
a=a&((1<<15))
4.给定一个整型数a,清除a的bit15,保证其他位不变。
a=a&(~(1<<15))// 左移15位说明从bit15开始, 0x1 表示有连续1位置0.
5.给定一个整形数a,清除a的bit15~bit23,保持其他位不变。
a=a&(~(0b111111111<<15)) == a=a&(~(0x1ff<<15))
// 左移15位说明从bit15开始, 0x1ff 示有这部分有9位

如下实例:
6、给定一个整形数a,取出a的bit3~bit8。
思路:
第一步:先将这个数bit3~bit8不变,其余位全部清零。
a &= (0x3f<<3);
第二步,再将其右移3位得到结果。
a >>= 3;

7、用C语言给一个寄存器的bit7~bit17赋值937(其余位不受影响)。
关键点:第一,不能影响其他位;第二,你并不知道原来bit7~bit17中装的值。
思路: 第一步,先将bit7~bit17全部清零,当然不能影响其他位
a &= ~(0x7ff<<7);
第二步,再将937写入bit7~bit17即可,当然不能影响其他位。
a |= (937<<7);
8、用C语言将一个寄存器的bit7~bit17中的值加17(其余位不受影响)。
关键点:不知道原来的值是多少
思路:第一步,先读出原来bit7~bit17的值
第二步,给这个值加17
第三步,将bit7~bit17清零
第四步,将第二步算出来的值写入bit7~bit17
/*
unsigned int a = 0xc30288f8; // 0xc34648f8
//第一步,先读出原来bit7~bit17的值,
即bit7~bit17不变,将其他位全部清零,然后右移对应的起始bit位
unsigned int tmp = 0;
tmp = a & (0x7ff<<7);
//printf("befor shift, tmp = 0x%x.\n", tmp);
tmp >>= 7;
//printf("after shift, tmp = 0x%x.\n", tmp);
//第二步,给这个值加17,
tmp += 17;
//第三步,将a的bit7~bit17清零
a &= ~(0x7ff<<7);
//第四步,将第二步算出来的值写入bit7~bit17
a |= tmp<<7;
printf("a = 0x%x.\n", a);
*/
9、用C语言给一个寄存器的bit7~bit17赋值937,同时给bit21~bit25赋值17.
思路:4.2.4.6的升级版,两倍的4.2.4.6中的代码即可解决。
/*// 直接double第7题
unsigned int a = 0xc30288f8;
a &= ~((0x3ff<<7) | (0x1f<<21)); // bit7~bit17和bit21~bit25全清零
a |= ((937<<7) | (17<<21)); // 937和17全部赋值

printf("a = 0x%x.\n", a); // 0xc223d4f8
*/
位操作复习main.c:
#include <stdio.h>

int main(int argc,char *argv[])//位操作复习
{
    
    //6.给定一个整形数a,取出a的bit3~bit8。
    unsigned int a =  0xc30288f8;
    //第一步,先将a的bit3~bit8不变,其他位全部清零
    a&=(0b111111<<3);
    //第二步,再将其右移3位得到结果
    a>>=3;

    printf("after shift, a = 0x%x.\n", a);

    /*
    //7.用C语言给一个寄存器的bit7~bit17赋值937(其余位不受影响)。
      unsigned int a =  0xc30288f8;
    a&=~(0b11111111111<<7);//第一步,先将bit7~bit17全部清零,其他位不变
    a|=(937<<7);//第二步,再将937写入bit7~bit17即可,当然不能影响其他位。

    printf("after shift, a = 0x%x.\n", a);
*/

   /*
    //8.用C语言将一个寄存器的bit7~bit17中的值加17(其余位不受影响)。
    unsigned int a =0xc30288f8;
    unsigned int b=0;
    //第一步,先读出原来bit7~bit17的值,即bit7~bit17不变,将其他位全部清零
    b=a&(0b11111111111<<7);
    b>>=7;
    //第二步,给这个值加17
    b+=17;
    //第三步,将a的bit7~bit17的值清零,当然不能影响其他位
    a&=~(0b11111111111<<7);
    //第四步,将第二步算出的值写入bit7~bit17中
    a|=b<<7;

    printf("after shift, a = 0x%x.\n", a);
*/

 /*   
  //9.用C语言给一个寄存器的bit7~bit17赋值937,同时给bit21~bit25赋值17.
    unsigned int a =  0xc30288f8;
    a&=~(0b11111111111<<7);//第一步,先将bit7~bit17全部清零,其他位不变
    a|=(937<<7);//第二步,再将937写入bit7~bit17即可,当然不能影响其他位。

    a&=~(0b11111<<21);//第一步,先将bit21~bit25全部清零,其他位不变
    a|=(17<<21);//第二步,再将17写入bit21~bit25即可,当然不能影响其他位。

    printf("after shift, a = 0x%x.\n", a);

    //也可以将上面的步骤合一
    a&=~((0b11111111111<<7)|(0b11111<<21));//第一步,先将bit7~bit17全部清零,其他位不变
    a|=((937<<7)|(17<<21));//第二步,再将937写入bit7~bit17即可,当然不能影响其他位。

    printf("after shift, a = 0x%x.\n", a);
*/



}

二、位操作的宏定义

//用宏定义将32位数x的第n(bit0为第1)置位

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

//用宏定义将32位数x的第n(bit0为第1)清零

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

//用宏定义将32位数x的第n位到第m(bit0为第1)置位

#define SET_BITS_N_M(x,n,m) (x | (((~0U)>>(32-(m-n+1)))<<(n-1)))

//用宏定义将32位数x的第n位到第m(bit0为第1)清零

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

//用宏定义获取32位数x的第n位到第m(bit0为第1)的部分

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


猜你喜欢

转载自blog.csdn.net/wangweijundeqq/article/details/78632615
今日推荐