C语言位操作符详解

操作符

  • 左移和右移操作符
  • 位操作符

左移和右移操作符

注:移位操作符的操作数只能是整数。
左移操作符 <<

#include

int main()
{
	int a = -3 << 1;
	int b = 5 << 1;

	printf("a = %d b = %d",a,b);

	return 0;
}

整数在内存中存储的是补码,不论是左移还是右移都移动二进制位,也就是移动内存中的补码,- 3往左移动一个二进制位:
-3的原码是:1000000 0000000 0000000 00000011
-3的反码是:11111111 11111111 11111111 11111100
-3的补码是:11111111 11111111 11111111 11111101
C语言位操作符详解_第1张图片
那么5的原码是:00000000 00000000 00000000 00000101
整数原,反,补码相同
向左移动一个二进制位:
C语言位操作符详解_第2张图片
所以-3向左移动一位是 -6
5向左移动一位是 10
我们来验证一下:
C语言位操作符详解_第3张图片
-3左移一位是-6,5左移一位是10,可以发现左移1位有乘2的效果
再次来验证一下:
C语言位操作符详解_第4张图片

右移操作符>>
将数字的补码向右移动一个二进制位
我们还是拿-3和5来举例
C语言位操作符详解_第5张图片
注意:向右移动的时候,大部分编译器都是补符号位

  1. 逻辑移位
    左边用0填充,右边丢弃
  2. 算术移位
    左边用原该值的符号位填充,右边丢弃
    对于移位运算符,不要移动负数位,这个是标准未定义的。

5向右移动一位:
C语言位操作符详解_第6张图片
来验证一下:
C语言位操作符详解_第7张图片

位操作符

1,按位与 &
两个操作数都为1,结果才是1

#define _CRT_SECURE_NO_WARNINGS
#include

int main()
{
	int a = -3 & 5;
	int b = 5 & -3;

	printf("a = %d b = %d",a,b);

	return 0;
}

C语言位操作符详解_第8张图片
验证一下:
C语言位操作符详解_第9张图片

2,按位或 |
两个操作数都为0,结果才是0
还是用-3和5举例:
C语言位操作符详解_第10张图片
验证一下:
C语言位操作符详解_第11张图片

3,按位异或 ^
两个操作数相同,结果是0,两个操作数不相同,结果是1
还是用-3和5举例:
C语言位操作符详解_第12张图片
验证一下:
C语言位操作符详解_第13张图片
我们再通过一个经典的题目来仔细分析一下按位异或
现在有一个变量a = 10,变量b = 20
怎样再不创建新的变量的条件下,交换两个变量的数据
首先我们会想到:
a = a + b;
b = a - b;
a = a - b;

讲到异或,那我们肯定是用异或的方式来交换:

#define _CRT_SECURE_NO_WARNINGS
#include

int main()
{
	int a = 10;
	int b = 20;

	a = a ^ b;
	b = a ^ b;
	a = a ^ b;

	printf("a = %d b = %d",a,b);

	return 0;
}

上图:
C语言位操作符详解_第14张图片
验证一下:
C语言位操作符详解_第15张图片
首先a ^ b 等于 10 ^ 20得到30,可以把30看做是一个密码
当用a去异或b的时候,也就是30 ^ 20得到10
再用a ^ b,也就是30 ^ 10,得到20,如何赋值给a
达到一个交换的效果

4,按位取反 ~
按位取相反数 0变成1,1变成0
还是用-3和5举例:
C语言位操作符详解_第16张图片
验证:C语言位操作符详解_第17张图片

你可能感兴趣的:(c语言,算法,c++)