C语言位运算符 #
一、位运算符概述 #
1.1 六种位运算符 #
| 运算符 | 名称 | 示例 | 说明 |
|---|---|---|---|
| & | 按位与 | a & b | 两位都为1则1 |
| | | 按位或 | a | b | 有一位为1则1 |
| ^ | 按位异或 | a ^ b | 两位不同则1 |
| ~ | 按位取反 | ~a | 0变1,1变0 |
| << | 左移 | a << n | 左移n位 |
| >> | 右移 | a >> n | 右移n位 |
1.2 位运算真值表 #
按位与 (&):
| a | b | a & b |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |
按位或 (|):
| a | b | a | b |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 1 |
按位异或 (^):
| a | b | a ^ b |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |
二、按位与运算 #
2.1 基本使用 #
c
#include <stdio.h>
void print_binary(int n) {
for (int i = 7; i >= 0; i--) {
printf("%d", (n >> i) & 1);
}
printf("\n");
}
int main() {
int a = 0b11001010;
int b = 0b10101100;
printf("a = "); print_binary(a);
printf("b = "); print_binary(b);
printf("a & b = "); print_binary(a & b);
return 0;
}
输出:
text
a = 11001010
b = 10101100
a & b = 10001000
2.2 应用:清零特定位 #
c
#include <stdio.h>
int main() {
int a = 0xFF;
int mask = 0x0F;
printf("清零高4位: 0x%X\n", a & mask);
return 0;
}
2.3 应用:取特定位 #
c
#include <stdio.h>
int main() {
int a = 0xAB;
int low_nibble = a & 0x0F;
int high_nibble = (a >> 4) & 0x0F;
printf("低4位: 0x%X\n", low_nibble);
printf("高4位: 0x%X\n", high_nibble);
return 0;
}
2.4 应用:判断奇偶 #
c
#include <stdio.h>
int main() {
int n = 7;
if (n & 1) {
printf("%d是奇数\n", n);
} else {
printf("%d是偶数\n", n);
}
return 0;
}
三、按位或运算 #
3.1 基本使用 #
c
#include <stdio.h>
int main() {
int a = 0b11001010;
int b = 0b10101100;
printf("a = 0x%X\n", a);
printf("b = 0x%X\n", b);
printf("a | b = 0x%X\n", a | b);
return 0;
}
3.2 应用:设置特定位 #
c
#include <stdio.h>
int main() {
int a = 0x00;
a = a | 0x01;
printf("设置第0位: 0x%X\n", a);
a = a | 0x80;
printf("设置第7位: 0x%X\n", a);
return 0;
}
3.3 应用:组合标志 #
c
#include <stdio.h>
#define READ 0x01
#define WRITE 0x02
#define EXECUTE 0x04
int main() {
int permissions = READ | WRITE;
if (permissions & READ) {
printf("可读\n");
}
if (permissions & WRITE) {
printf("可写\n");
}
if (permissions & EXECUTE) {
printf("可执行\n");
}
return 0;
}
四、按位异或运算 #
4.1 基本使用 #
c
#include <stdio.h>
int main() {
int a = 0b11001010;
int b = 0b10101100;
printf("a = 0x%X\n", a);
printf("b = 0x%X\n", b);
printf("a ^ b = 0x%X\n", a ^ b);
return 0;
}
4.2 应用:翻转特定位 #
c
#include <stdio.h>
int main() {
int a = 0x55;
printf("原值: 0x%X\n", a);
printf("翻转: 0x%X\n", a ^ 0xFF);
return 0;
}
4.3 应用:交换两个数 #
c
#include <stdio.h>
int main() {
int a = 10, b = 20;
printf("交换前: a=%d, b=%d\n", a, b);
a = a ^ b;
b = a ^ b;
a = a ^ b;
printf("交换后: a=%d, b=%d\n", a, b);
return 0;
}
4.4 应用:简单加密 #
c
#include <stdio.h>
int main() {
char key = 0x55;
char data = 'A';
char encrypted = data ^ key;
char decrypted = encrypted ^ key;
printf("原数据: %c\n", data);
printf("加密后: 0x%X\n", encrypted);
printf("解密后: %c\n", decrypted);
return 0;
}
五、按位取反运算 #
5.1 基本使用 #
c
#include <stdio.h>
int main() {
unsigned char a = 0x55;
printf("a = 0x%X\n", a);
printf("~a = 0x%X\n", (unsigned char)~a);
return 0;
}
5.2 应用:清零特定位 #
c
#include <stdio.h>
int main() {
int a = 0xFF;
int bit3 = 0x08;
printf("清零第3位: 0x%X\n", a & ~bit3);
return 0;
}
六、移位运算 #
6.1 左移运算 #
c
#include <stdio.h>
int main() {
int a = 5;
printf("a = %d (二进制: ", a);
for (int i = 7; i >= 0; i--) printf("%d", (a >> i) & 1);
printf(")\n");
printf("a << 1 = %d\n", a << 1);
printf("a << 2 = %d\n", a << 2);
printf("a << 3 = %d\n", a << 3);
return 0;
}
左移n位相当于乘以2^n。
6.2 右移运算 #
c
#include <stdio.h>
int main() {
int a = 20;
printf("a = %d\n", a);
printf("a >> 1 = %d\n", a >> 1);
printf("a >> 2 = %d\n", a >> 2);
int b = -20;
printf("\nb = %d\n", b);
printf("b >> 1 = %d\n", b >> 1);
return 0;
}
右移n位相当于除以2^n(注意负数右移是算术移位)。
6.3 应用:快速乘除 #
c
#include <stdio.h>
int main() {
int a = 10;
printf("%d * 2 = %d\n", a, a << 1);
printf("%d * 4 = %d\n", a, a << 2);
printf("%d * 8 = %d\n", a, a << 3);
printf("%d / 2 = %d\n", a, a >> 1);
printf("%d / 4 = %d\n", a, a >> 2);
return 0;
}
七、位运算应用 #
7.1 判断某位是否为1 #
c
#include <stdio.h>
int main() {
int a = 0b10101010;
int bit = 5;
if (a & (1 << bit)) {
printf("第%d位是1\n", bit);
} else {
printf("第%d位是0\n", bit);
}
return 0;
}
7.2 设置某位为1 #
c
#include <stdio.h>
int main() {
int a = 0;
int bit = 3;
a |= (1 << bit);
printf("设置第%d位后: 0x%X\n", bit, a);
return 0;
}
7.3 清零某位 #
c
#include <stdio.h>
int main() {
int a = 0xFF;
int bit = 3;
a &= ~(1 << bit);
printf("清零第%d位后: 0x%X\n", bit, a);
return 0;
}
7.4 翻转某位 #
c
#include <stdio.h>
int main() {
int a = 0xF0;
int bit = 3;
a ^= (1 << bit);
printf("翻转第%d位后: 0x%X\n", bit, a);
return 0;
}
7.5 统计1的个数 #
c
#include <stdio.h>
int count_ones(int n) {
int count = 0;
while (n) {
count += n & 1;
n >>= 1;
}
return count;
}
int main() {
int a = 0b10111011;
printf("%d中1的个数: %d\n", a, count_ones(a));
return 0;
}
八、总结 #
位运算符 #
| 运算符 | 说明 | 应用 |
|---|---|---|
| & | 按位与 | 清零、取位 |
| | | 按位或 | 设置位 |
| ^ | 按位异或 | 翻转、交换 |
| ~ | 按位取反 | 取反 |
| << | 左移 | 乘以2^n |
| >> | 右移 | 除以2^n |
常用操作 #
| 操作 | 代码 |
|---|---|
| 判断第n位 | a & (1 << n) |
| 设置第n位 | a |= (1 << n) |
| 清零第n位 | a &= ~(1 << n) |
| 翻转第n位 | a ^= (1 << n) |
注意事项 #
- 注意有符号数的移位
- 注意运算符优先级
- 使用unsigned类型避免符号问题
下一步,让我们学习赋值运算符!
最后更新:2026-03-26