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