可以使用C对变量中的个别位进行操作。您可能对人们想这样做的原因感到奇怪。这种能力有时确实是必须的,或者至少是有用的。C提供位的逻辑运算符和移位运算符。
-
位运算符 {#title-0} ==================
-
位运算符
- 取反 ~,对于每个位按位取反。
- 位与 &,对于每个位,只有两个操作数的对应位都是 1 时结果才为 1。
- 位或 |,对于每个位,如果其中任意操作数中对应的位为 1,那么结果位就为 1。
- 位抑或 ^,二进制运算符^对两个操作数逐位进行比较。如果都是0或者都是1,则结果位0, 两个不一样则为1。
-
移位运算符
- 左移 <<,按二进制形式把所有的数字向左移动对应的位数,高位移出(舍弃),低位的空位补 0。
- 右移 >>,按二进制形式把所有的数字向右移动对应位移位数,低位移出(舍弃),高位的空位补符号位,即正数补 0,负数补 1
// 1. 取反
void test01()
{
int num1 = 2;
//1. 按位取反
// 11111111 11111111 11111111 11111101
// 10000000 00000000 00000000 00000010
// 10000000 00000000 00000000 00000011
// 负数在计算机中是以补码形式存储
int ret = ~num1;
printf("ret = %d\n", ret);
}
// 2. 位与
void test02()
{
int num1 = 2;
int num2 = 3;
// 00000000 00000000 00000000 00000010
// 00000000 00000000 00000000 00000011
// 00000000 00000000 00000000 00000010
int ret = num1 & num2;
printf("ret = %d\n", ret);
}
// 3. 位或
void test03()
{
int num1 = 2;
int num2 = 3;
// 00000000 00000000 00000000 00000010
// 00000000 00000000 00000000 00000011
// 00000000 00000000 00000000 00000011
int ret = num1 | num2;
printf("ret = %d\n", ret);
}
// 4. 位抑或
void test04()
{
int num1 = 2;
int num2 = 3;
// 00000000 00000000 00000000 00000010
// 00000000 00000000 00000000 00000011
// 00000000 00000000 00000000 00000001
int ret = num1 ^ num2;
printf("ret = %d\n", ret);
}
// 5. 左移
void test05()
{
int num = 2;
// 00000000 00000000 00000000 00000010 << 2
// 00000000 00000000 00000000 00001000
int ret = num << 2;
printf("ret = %d\n", ret);
}
// 6. 右移
void test06()
{
int num = 11;
// 00000000 00000000 00000000 00001011 >> 2
// 00000000 00000000 00000000 00000011
int ret = num >> 2;
printf("ret = %d\n", ret);
}
- 位运算技巧 {#title-1} =======================
// 1.判断数的奇偶性
void test()
{
int num = 2;
// 00000000 00000000 00000000 00000011 &
// 00000000 00000000 00000000 00000001
// 00000000 00000000 00000000 00000001
printf("%s\n", num & 1 == 1 ? "奇数" : "偶数");
}
// 2.获得整型最大值
void test()
{
// 00000000 00000000 00000000 00000001
// 10000000 00000000 00000000 00000000
// 01111111 11111111 11111111 11111111
printf("%d\n", (1 << 31) - 1);
// 01111111 11111111 11111111 11111111
printf("%d\n", ~(1 << 31));
}
// 3.计算乘以2、除以2**
void test()
{
int num = 6;
// 00000000 00000000 00000000 00000110 << 1
// 00000000 00000000 00000000 00001100
printf("%d\n", num << 1);
// 00000000 00000000 00000000 00000110 >> 1
// 00000000 00000000 00000000 00000011
printf("%d\n", num >> 1);
}
// 4.从低位到高位,取 v 的 m 位**
void test()
{
int v = 8; // 取v的第4位
int n = 4;
// 00000000 00000000 00000000 00001000
printf("%d\n", (v >> (n - 1)) & 1);
// 00000000 00000000 00000000 00000001
// 00000000 00000000 00000000 00000001
// 00000000 00000000 00000000 00000001
}
// 5.交换两个数
void test()
{
int num1 = 2;
int num2 = 3;
// 00000000 00000000 00000000 00000010
// 00000000 00000000 00000000 00000011
// 00000000 00000000 00000000 00000001
// num1 或者 num2 抑或这个值得到另外一个值
num1 = num1 ^ num2;
num2 = num1 ^ num2;
num1 = num1 ^ num2;
// num1 ^= num2 ^= num1 ^= num2;
printf("num1=%d num2=%d\n", num1, num2);
}