朱有鹏:位运算实战演练
约定: 题目中出现"设置"字符就是要把寄存器设置为1;出现”清除“ 就是把寄存器值设置为0
位操作口诀: 要置1用|;
要清零用&;
要取反用^;
~和 << >> 用来构建特定二进制数.
4.2.4.1 给定一个整型a, 设置a的bit3,保证其他位不变。
答: a = a | (1<<3) 或 a |= (1<<3)
4.2.4.2 给定一个整型a, 设置a的 bit3 ~ bit7 (3~7位为1),保证其他位不变。
答: a = a | (0b11111<<3)
#include <stdio.h>
int main(void)
{
unsigned int a;
a = 0;
printf("a = 0x%x\n", a);
a |= (0b11111<<3);
printf("a = 0x%x\n", a);
}
结果:

4.2.4.3 给定一个整型数a, 清除a的 bit15,保持其他位不变。
答: a = a & (~(1<<15)); 或者 a &= (~(1<<15))
#include <stdio.h>
int main(void)
{
unsigned int a;
a = 0xFFFFFFFF;
printf("a = 0x%x\n", a);
a &= (~(1<<15));
printf("a = 0x%x\n", a);
}
结果:

4.2.4.4 给定一个整型数a,清除a的 bit15 ~ bit23,其他位保持不变
答: a = a & (~(0x1ff<<15)); 或者 a &= (~(0x1ff<<15))
#include <stdio.h>
int main(void)
{
unsigned int a;
a = 0xFFFFFFFF;
printf("a = 0x%x\n", a);
a &= (~(0x1ff<<15));
printf("a = 0x%x\n", a);
}
结果:

4.2.4.5 给定一个整型数a,取出a的 bit3 ~ bit8 的值。
分析思路:
第一步:现将这个数 bit3 ~ bit8 不变,其余位全部清零;
第二步:将其右移 3 位得到结果。
第三步:想明白上面的两部算法,再将其转换为C语言实现即可。
#include <stdio.h>
int main(void)
{
unsigned int a = 0xc30288f8;
printf("a = 0x%x\n", a); // 输出a定义原始值
a &= (0x3f<<3);
printf("a = 0x%x\n", a); // 位与后的值
a >>= 3;
printf("a = %u\n", a); // 输出十进制
}
结果:

4.2.4.6 用C语言给一个寄存器的 bit7 ~ bit17 赋值 937(其余位不受影响)
明白关键点:
第一:不能影响其他位;
第二:你并不知道原来 bit7 ~ bit17 值是什么;
思路:
第一步:先将 bit7 ~ bit17 全部清零,当然不能影响其他位;
第二步:再将937写入 bit7 ~ bit17 ,当然不能影响其他位。
#include <stdio.h>
int main(void)
{
unsigned int a = 0xc30288f8;
printf("a = 0x%x\n", a);
a &= ~(0x7ff<<7);
a |= (937<<7);
printf("a = 0x%x\n", a);
}
结果:

4.2.4.7 用C语言给一个寄存器的 bit7 ~ bit17 值加17(其余位不受影响)
明白关键点: 不知道原来的值是多少
思路:
第一步:先读出原来 bit7 ~ bit17 的值;
第二步:给这个值加17;
第三步:将 a 的 bit7~bit17 清零;
第四步:将第二步算出来的值写入 bit7 ~ bit17
#include <stdio.h>
int main(void)
{
unsigned int a = 0xc30288f8;
unsigned int tmp = 0;
printf("a = 0x%x\n", a);
tmp = a & (0x3ff<<7); //取出 7~17bit 的值
tmp >>= 7; // 将值移动到 最右边 0 位,获取到值,方便后面加法计算
tmp += 17;
a &= ~(0x3ff<<7);
a |= tmp<<7;
printf("a = 0x%x\n", a);
}
结果:

4.2.4.8 用C语言给一个寄存器的 bit7~bit17 赋值 937,同时给 bit21 ~ bit25 赋值 17
#include <stdio.h>
int main(void)
{
unsigned int a = 0xc30288f8;
printf("原始值:a = 0x%x\n", a);
// 方式一:写法比较繁琐。
a &= ~(0x3ff<<7);
a |= (937<<7);
a &= ~(0x1f<<21);
a |= (17<<21);
printf("方式一:a = 0x%x\n", a);
// 方式二: 将上面的 4 行操作,合并在 2 行,
// 网上代码大多数用此写法,推荐使用。
// 效果和"方式一"一样
a &= ~((0x3ff<<7) | (0x1f<<21));
a |= ((937<<7) | (17<<21));
printf("方式二:a = 0x%x\n", a);
}
结果:

来源:
朱有鹏-嵌入式软件工程师完全学习路线图专题\4.C语言高级专题精讲视频课程套餐\4.2.C语言位操作\
4.2.4.位运算实战演练1.mp4
4.2.5.位运算实战演练2.mp4
浙公网安备 33010602011771号