C语言-位运算符

本文详细介绍了C语言中的位运算符,如左移(<<),右移(>>),按位与(&),按位或(|),按位异或(^)和按位取反(~),并展示了它们的运算规则、实例和应用场景,强调了这些运算在提高性能中的作用。
摘要由CSDN通过智能技术生成

一、位运算符

位运算符:用来操作二进制位(bit)
注意:位运算符的运算过程都是基于二进制的补码运算

运算符描述运算规则
<<二进制左移将一个数的各二进制位全部左移指定的位数,左边的二进制位丢弃,右边补0
>>二进制右移将一个数的各二进制位全部右移指定的位数,正数左补0,负数左补1,右边丢弃。
&按位与两个二进制位都为 1,结果为1,否则为0。
|按位或两个二进制位只要有一个为1(包含两个都为 1 的情况),结果为1,否则为0。
^按位异或两个二进制位一个为0,一个为1,结果为1,否则为0。
~按位取反将每一个二进制位(包括符号位)变成相反值,即 0 变成 1 , 1 变成 0 。

结合赋值运算符的经验,这里有:<<= 、 >>= 、 &= 、 ^= 等

二、左移:<<

1.运算规则

运算规则:在一定范围内,数据每向左移动一位,相当于原数据 * 2。(正数、负数都适用),效率比使用 *

【注意】当左移的位数n超过该数据类型的总位数时,相当于左移(n-总位数)位

2.实例

3<<4 类似于 3 ∗ 2 4 3 * 2^4 324 => 3 * 16 => 48


在这里插入图片描述

-3<<4 类似于 − 3 ∗ 2 4 -3 * 2^4 324 => -3*16 => -48


在这里插入图片描述

3.练习

高效的方式计算2 * 8的值

答案:2 << 38  << 1 // 这两个就不比效率了,都同时常数级别的

三、右移:>>

1.运算规则

运算规则:在一定范围内,数据每向右移动一位,相当于原数据 / 2。(正数、负数都适用),效率比使用 /

【注意】

  • 如果不能整除,向下取整
  • 右移运算符最好只用于无符号整数,不要用于负数。因为不同系统对于右移后如何处理负数的符号位,有不同的做法,可能会得到不一样的结果。

2.实例

69>>4 类似于 69 / 2 4 69 / 2^4 69/24 => 69 / 16 => 4


在这里插入图片描述

-69>>4 类似于 − 69 / 2 4 -69 / 2^4 69/24 => -69 / 16 => 4


在这里插入图片描述

四、按位与:&

1.运算规则

运算规则:对应位都是1才为1,否则为0。

  • 1 & 1 结果为1
  • 1 & 0 结果为0
  • 0 & 1 结果为0
  • 0 & 0 结果为0

2.实例

9 & 7 = 1

在这里插入图片描述

-9 & 7 = 7

在这里插入图片描述

五、按位或:|

1.运算规则

运算规则:对应位只要有1即为1,否则为0。

  • 1 | 1 结果为1
  • 1 | 0 结果为1
  • 0 | 1 结果为1
  • 0 & 0 结果为0

2.实例

9 | 7 = 15

在这里插入图片描述

-9 | 7 = -9

在这里插入图片描述

六、按位异或:^

1.运算规则

运算规则:对应位一个为1一个为0,才为1,否则为0。

  • 1 ^ 1 结果为0
  • 1 ^ 0 结果为1
  • 0 ^ 1 结果为1
  • 0 ^ 0 结果为0

2.实例

9 ^ 7 = 14

在这里插入图片描述

-9 ^ 7 = -16

在这里插入图片描述

七、按位取反:~

1.运算规则

运算规则:对应位为1,则结果为0;对应位为0,则结果为1。

  • ~0就是1
  • ~1就是0

2.实例

~9 = -10

在这里插入图片描述

Tips:-10 取反就是 9

~-9 = -8

在这里插入图片描述

八、应用

  大家肯定和我一样,心里一万个为什么,学这个有啥用啊???确实,我们平常写代码时几乎不会使用,但是 C语言 的源码中会用到,为了追求更高的性能。例如下面几个场景:

1.特定位清零

待清零的位与0,其它位与1

示例:设字符型 x 的当前值为 53,将其最低两位清 0,其余位保持不变

int main() {
    char x = 53; // 0b00110101
    x = x & 252; // 0b11111100
    printf("%d", x); //0b00110100
    return 0;
}

2.判断特定位是否为零

待判定位与 1,其它位与 0;判与运算结果是否为 0

示例:设字符型 x 的当前值为 53,判定其最高位是否为 0

int main() {
    char x = 53; // 0b00110101
    x = x & 128; // 0b10000000
    if(x == 0)
        printf("最高位为0");
    else
        printf("最高位不为0");
    
    return 0;

}

3.保留特定位

待保留位全部与 1,其余位与 0

示例:设字符型 x 的当前值为 53,保留其最低 4 位,其余位清零

int main() {
    char x = 53; // 0b00110101
    x = x & 15;  // 0b00001111

    printf("%d\n",x); //0b00000101

    return 0;

}

4.特定位置为1,其余为不变

待置为1的位或1,其它位或0

示例:设字符型 x 的当前值为 53,将其最低两位置 1,其余位保持不变

int main() {
    char x = 53; // 0b00110101
    x = x | 3;   // 0b00000011

    printf("%d\n",x); //0b00110111

    return 0;

}

5.特定位取反

待取反位异或 1,保持位异或 0

示例:设字符型 x 的当前值为 53,将其最低两位取反,其余位保持不变

int main() {
    char x = 53; // 0b00110101
    x = x ^ 3;   // 0b00000011

    printf("%d\n",x); //0b00110110

    return 0;

}
  • 9
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值