一. 基础语法
1. 位运算符
运算符 | 术语 | 示例 | 结果 |
---|---|---|---|
& | 按位与 | 011 & 101 | 2个都为1才为1,结果为001 |
| | 按位或 | 011 & 101 | 有1个为1就为1,结果为111 |
^ | 按位异或 | 011 ^ 101 | 不同的为1,结果为110 |
~ | 取反 | 011 | 100 |
<< | 左移 | 1010 << 1 | 10100 |
>> | 右移 | 1010 >> 1 | 0101 |
& 按位于运算: 都为1才为1
| 按位或运算: 只要有一个1, 结果为1
^ 按位异或运算: 相同为0, 不同为1
~ 取反运算: 1变0, 0变1
<< 左移运算: 所有位向左移动,在后面补0
>> 右移运算: 所有位向右移动(去掉最后一位)
1.1 将变量a的第二位设置为1, 其他保持不变
#include <stdio.h>
#include <inttypes.h>
int main()
{
uint8_t a = 0xb3;
// 0xb3 -> 二进制: 0b 1011 0011
// 按位或运算 0b 0000 0100 (转成十六位: 0x04)
// 第二位设置为1: 0b 1011 0111 (转成十六位: 0xb7)
printf("置位结果: %0x\n", 0x4); // 4
// 将1左移2位
printf("结果为:%0x\n", a | (1 << 2)); // b7
}
1.2 将变量b的第二位和第六位设置为1, 其他位保持不变
#include <stdio.h>
#include <inttypes.h>
int main()
{
uint8_t b = 0xb3;
// 0xb3 -> 二进制: 0b 1011 0011
// 按位或运算: 0b 0100 0100 (转成十六位: 0x44)
// 第二位和第六位设置1: 0b 1011 0111 (转成十六位: 0xb7)
printf("%#x\n", b | 0x44); // 0xf7
// 将1左移2位和六位
printf("%#x\n", b | (1 << 2 | 1 << 6)); // 0xf7
}
1.3 将变量c的第五位设置为0, 其他位置保持不变
#include <stdio.h>
#include <inttypes.h>
int main()
{
uint8_t c = 0xb3;
// 0xb3 --> 二进制: 0b 1011 0011
// 按位与运算: 0b 1101 1111 (0xdf)
// 第五位设置为0: 0b 1001 0011 (0x93)
printf("%#x\n", c & 0xdf);
// 将1向左移动5位,并取反
printf("%#x\n", c & ~(1 << 5));
}
1.4 将变量d的0-3位置于0,其他位置保持不变
#include <stdio.h>
#include <inttypes.h>
int main()
{
uint8_t d = 0xff;
// 0xff -> 0b 1111 1111;
// 0b 1111 0000; (0xf0)
// 0b 1111 0000; (0xf0)
printf("%#x\n", d & 0xf0);
// (1 << 0 | 1 << 1 | 1 << 2 | 1 << 3): 0000 1111;
// ~(1 << 0 | 1 << 1 | 1 << 2 | 1 << 3): 1111 0000;
printf("%#x~~~~~~~~~~~~\n", d & ~(1 << 0 | 1 << 1 | 1 << 2 | 1 << 3));
}
1.5 将变量e的第二位取反, 其他位置保持不变
#include <stdio.h>
#include <inttypes.h>
int main()
{
uint8_t e = 0b10110011; //(0xb3)
// 0b 1011 0011; (0xb3)
// 0b 0000 0100; (0x04) (按位异或运算(将第二位变成1,其他为0))
// 0b 1011 0111; (0xb7)
printf("%#x\n", e ^ 0x04);
// 5.2.将变量e的第二位取反, 其他位置保持不变
uint8_t e2 = 0b10111111; // (0xbf)
// 0b 1011 1111 (0xbf)
// 0b 0000 0100 (0x04) //(按位异或运算(将第二位变成1,其他为0))
// 0b 1011 1011 (0xbb)
printf("%#x\n", e2 ^ 0x04); // 0xbb
}
1.6 将变量f取出8-15位
#include <stdio.h>
#include <inttypes.h>
int main()
{
uint32_t f = 0x12345678; // 十六进制
// f 十六进制 对应32位二进制
// 十六进制一个数对应二进制四位数
// 与运算 0x0000ff00, 在&运算中,只有f是四个一样的1111,在&运算中,一个为1则为1
// 0000 0000 0000 0000 0000 0000 0000 0000 0000
printf("%#x\n", (f & 0x0000ff00) >> 8); // 0x56
}
//检查变量e的第7位是否为1,如果是则输出"Bit is set",否则输出"Bit is not set"。
uint8_t e = 0b10110011;
printf("s===%d\n", e & (1 << 7));
if (e & (1 << 7))
{
printf("Bit is set\n");
}
else
{
printf("Bit is not set\n");
}
总结
1. 想把某一位置为1时, 使用 | 换位运算符或者左移<< 例如:(a | 0b 0000 0100)或者(a | (1<< 2) )
2. 想把某一位设置为0时, 使用 & 换位运算符,或者左移<<并进行~取反运算符
例如: (a & 0b 0000 1100) 或者(a & (1<<2 | 1<< 3))
3. 想把某一位取反时, 使用换位异或运算符 ^, 例如: (a ^ 0b 0000 0100)
4. 想取出某一位时, 使用&运算符和右移>>, 这里注意: 数据位数32时,十六进制对应二进制的四位, 例如: 取出32位的8-15位时((a & 0x0000ff00) >> 8), 取出8位的第七位时, (e & (1 << 7))
1 ---- | 或者 >>
0 ---- & 或者 >>
取反 ---- ^
取出 ---- & >>