C语言之位操作

目录

一、什么是位操作

二、位操作有哪些

三、组合位操作


一、什么是位操作

        位操作是指直接对二进制数的位进行操作的一类运算。在计算机中,数据以二进制形式存储和表示,在某些情况下需要对二进制数的位进行特定操作,这就用到了位操作。

        位操作通常用于优化代码、实现位级别的标志操作、提取和设置二进制数中的特定位等场景。但需要注意,位操作对于代码的可读性和可维护性可能有一定的影响,应谨慎使用,并确保操作的正确性和逻辑清晰性。

二、位操作有哪些

假设有两个无符号字符变量 ab,它们的二进制表示分别为:

a = 0b10100110
b = 0b11001100

常见的位操作包括:

1、按位与(&):将两个数的每一位进行与运算,只有当两个位都为1时,结果才为1,否则为0。

a & b = 0b10000100

        此操作将 ab 的每一位进行与运算,只有当两个位都为 1 时,结果位才为 1,否则为 0。

2、按位或(|):将两个数的每一位进行或运算,只有当两个位都为0时,结果才为0,否则为1。

a | b = 0b11101110

        此操作将 ab 的每一位进行或运算,只有当两个位都为 0 时,结果位才为 0,否则为 1。

3、按位异或(^):将两个数的每一位进行异或运算,当两个位相同(都为0或都为1)时,结果为0,否则为1。

a ^ b = 0b01101010

        此操作将 ab 的每一位进行异或运算,当两个位相同(都为 0 或都为 1)时,结果为 0,否则为 1。

4、按位取反(~):对一个数的每一位进行取反操作,将0变为1,将1变为0。

~a = 0b01011001

        此操作对变量 a 的每一位进行取反操作,将 0 变为 1,将 1 变为 0。

5、左移(<<):将一个数的所有位向左移动指定的位数,右侧补0。

a << 2 = 0b10011000

        此操作将变量 a 的所有位向左移动 2 位,右侧补 0。

6、右移(>>):将一个数的所有位向右移动指定的位数,左侧补0或补符号位(取决于所需的移位操作)。

b >> 3 = 0b00011001

此操作将变量 b 的所有位向右移动 3 位,左侧补 0。

三、组合位操作

1、把变量的某位清零,其他位不变

unsigned char var = 0xAF; // 假设变量名为 var,初始值为 0xAF
var &= ~(1 << bitIndex);
  • bitIndex 是需要清零的位的索引,从右往左数,最低位索引为 0。
  • 1 << bitIndex 将数字 1 的二进制表示向左移动 bitIndex 位,得到一个只有指定位为 1 的数值。
  • ~(1 << bitIndex) 对移位后的结果取反,得到一个只有指定位为 0 的数值。
  • var &= ~(1 << bitIndex) 执行按位与操作,将变量 var 与取反后的结果进行按位与运算,并将最终的结果赋值给 var

        这样操作后,变量 var 指定位被清零,其他位保持不变。

 示例:

//定义一个变量 a = 1001 1111 b (二进制数)

unsigned char a = 0x9f;

//对 bit2 清零
a &= ~(1<<2);


/*
    bit从0开始计数,bit2为从左向右起第三个数
    先确定我们要得到的值为1001 1011

    在二进制中,数字 1 表示为 0000 0001(共 8 位),通过左移 2 位,
    我们可以得到 0000 0100。这里的符号 << 表示左移运算,就相当于在二进制数的右侧补充 0。
    括号中的 1 左移两位,(1<<2) 得二进制数: 0000 0100 b
    按位取反,~(1<<2) 得 1111 1011 b

    a 中原来的值为二进制数: a = 1001 1111 b
    所得的数与 a 作“&”运算,a = (1001 1111 b)&(1111 1011 b)
    经过运算后,a 的值 a=1001 1011 b
*/

 2、把变量的某几个连续位清零

        假设要清零变量的第n位到第m位(n<m),可以先构造一个掩码,该掩码的第n位到第m位为0,其他位为1,然后将变量与该掩码进行按位与运算即可。

void clearBits(int& var, int n, int m) 
{
    int mask = ((1 << (m - n + 1)) - 1) << n; // 构造掩码
    var &= ~mask; // 按位与运算清零
}

         其中,1 << (m - n + 1)表示将1左移m-n+1位,即构造一个二进制数的最高位为1,其他位为0的掩码。然后再将其减1,得到一个二进制数的最高位到第n位为1,第n-1位到第0位为0的掩码。最后将该掩码左移n位,即得到一个二进制数的第n位到第m位为0,其他位为1的掩码。

示例:

//定义一个变量 a = 1001 1111 b (二进制数)
unsigned char a = 0x9f;

/*
    若把 a 中的二进制位分成 2 个一组
    即 bit0、bit1 为第 0 组,bit2、bit3 为第 1 组,
    bit4、bit5 为第 2 组,bit6、bit7 为第 3 组
    要对第 1 组的 bit2、bit3 清零
*/

a &= ~(3<<2*1);

/*
    3 = 0000 0011 b
    括号中的 3 左移两位,(3<<2*1) 得二进制数: 0000 1100 b
    按位取反,~(3<<2*1) 得 1111 0011 b

    a 中原来的值为二进制数: a = 1001 1111 b
    所得的数与 a 作”位与&”运算,a = (1001 1111 b)&(1111 0011 b),
    经过运算后,a 的值 a=1001 0011 b
    a 的第 1 组的 bit2、bit3 被清零,而其它位不变。
*/

/*
    上述 (~(3<<2*1)) 中的 1 即为组编号; 如清零第 3 组 bit、bit7 此处应为 3
    括号中的 2 为每组的位数,每组有 2 个二进制位; 若分成 4 个一组,此处即为 4
    括号中的 3是组内所有位都为 1 时的值; 若分成 4 个一组,此处即为二进制数“1111 b”
    例如对第 2 组 bit4、bit5 清零a &= ~(3<<2*2);
*/

3、对变量的某几位进行赋值 

        假设我们有一个整数变量 num,要对第 n 位到第 m 位(包括 nm)进行赋值为 value,可以使用位运算符进行操作。首先,需要将这几位清零,然后将 value 的相应位设置为所需的值。

num = (num & ~((1 << (m+1)) - 1)) | (value << n)

示例:

//a = 1000 0011 b

//此时对清零后的第 2 组 bit4、bit5 设置成二进制数“01 b ”

a |= (1<<2*2);

//a = 1001 0011 b,成功设置了第 2 组的值,其它组不变

 4、对变量的某位取反

        可以使用位异或运算符(^)来对整数类型的变量的某位进行取反操作。假设我们有一个整数变量 num,要对第 n 位进行取反,可以使用如下表达式:

num = num ^ (1 << n)

<< 是左移运算符,将 1 左移 n 位,然后与 num 进行异或运算,即可对第 n 位进行取反。

示例:

//a= 1001 0011 b

//把 bit6 取反,其它位不变
a=(1<<6);

//a = 1101 0011 b

  • 5
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值