c语言位运算符和位运算,位运算举例,位段

avatar
作者
筋斗云
阅读量:0

位运算符

1. 按位与运算符 (&)

按位与运算符对两个整数的每一位进行“与”操作,只有当两个位都是1时,结果才为1,否则为0。
int a = 5;  // 二进制: 00000101
int b = 3;  // 二进制: 00000011
int result = a & b;  // 结果: 00000001 (1)

2. 按位或运算符 (|)

按位或运算符对两个整数的每一位进行“或”操作,只要有一个位是1,结果就为1,否则为0。
int a = 5;  // 二进制: 00000101
int b = 3;  // 二进制: 00000011
int result = a | b;  // 结果: 00000111 (7)

3. 按位异或运算符 (^)

按位异或运算符对两个整数的每一位进行“异或”操作,当两个位不同,结果为1,相同时为0。
int a = 5;  // 二进制: 00000101
int b = 3;  // 二进制: 00000011
int result = a ^ b;  // 结果: 00000110 (6)

4. 取反运算符 (~)

取反运算符对整数的每一位进行“取反”操作,0变1,1变0。
int a = 5;  // 二进制: 00000101
int result = ~a;  // 结果: 11111010 (对于32位整数,结果为-6)

在有符号整数中,按位取反是针对补码进行操作的,因此取反后的结果表示的是该数的补码形式。

5. 左移运算符 (<<)

左移运算符将一个整数的二进制表示向左移动指定的位数,右侧用0填充,左侧的位丢弃。
int a = 5;  // 二进制: 00000101
int result = a << 1;  // 结果: 00001010 (10)

6. 右移运算符 (>>)

右移运算符将一个整数的二进制表示向右移动指定的位数,左侧用符号位填充(对于有符号整数),右侧的位丢弃。
int a = 5;  // 二进制: 00000101
int result = a >> 1;  // 结果: 00000010 (2)

复杂的位运算举例

交换两个整数而不使用临时变量
int x = 5;  // 二进制: 00000101
int y = 3;  // 二进制: 00000011

x = x ^ y;  // x 变为 00000110 (6)
y = x ^ y;  // y 变为 00000101 (5)
x = x ^ y;  // x 变为 00000011 (3)

// 最终 x = 3, y = 5
 

判断一个整数是否为2的幂
int n = 16;  // 二进制: 00010000
bool isPowerOfTwo = (n & (n - 1)) == 0;  // true,因为16是2的幂

位段(Bit Fields)

位段是C语言结构体的一部分,可以指定成员变量占用的位数。在嵌入式系统或需要节省内存的应用中非常有用。

定义位段
#include <stdio.h>

struct {
    unsigned int a : 1;  // 占1位
    unsigned int b : 3;  // 占3位
    unsigned int c : 4;  // 占4位
} bitFields;

int main() {
    bitFields.a = 1;  // 设置位段a为1
    bitFields.b = 5;  // 设置位段b为5(二进制: 101)
    bitFields.c = 9;  // 设置位段c为9(超出范围,结果取最低4位:二进制: 1001)

    printf("a: %u, b: %u, c: %u\n", bitFields.a, bitFields.b, bitFields.c);
    return 0;
}

在这个例子中,bitFields结构体包含三个位段:

- a 占用1位,范围是0到1。
- b 占用3位,范围是0到7。
- c 占用4位,范围是0到15。

位段的使用可以显著节省内存,但也带来了一些潜在的问题:

1. 位段的内存布局和对齐方式依赖于具体的编译器和平台。
2. 位段的访问和操作可能比普通整数操作稍慢。

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!