可以使用C对变量中的个别位进行操作。您可能对人们想这样做的原因感到奇怪。这种能力有时确实是必须的,或者至少是有用的。C提供位的逻辑运算符和移位运算符。
1. 位运算符
- 位运算符
- 取反 ~,对于每个位按位取反。
- 位与 &,对于每个位,只有两个操作数的对应位都是 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); }
2. 位运算技巧
// 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); }