位操作符:按位与&、右移>>、左移<<、异或^、按位或|

按位与&、右移>>

按位与&的基本概念:a&b时,只有同时为1结果才为1,即0&1=0,1&0=0;0&0=0;1&1=1

右移>>的基本概念:右移一个比特位,左边补0右边舍弃

题目:统计二进制中1的个数,利用该题分析按位与&、右移>>的应用

典型的错误代码:

#include<stdio.h>
int main()
{
	int num = 0;
	int count = 0;
	scanf("%d", &num);
	while (num)
	{
		if (num % 2 == 1)
		{
			count++;
		}
		num = num / 2;
	}
	printf("%d\n", count);
	return 0;
}  

但是上述代码无法满足负数的情况,比如-1

原码:10000000 00000000 00000000 000000001

反码:11111111 11111111 11111111 11111110

补码:11111111 11111111 11111111 11111111

如果按照上述代码,输入num=-1,-1%2==0,-1/2==0,输出的count实际上是0

所以显然上述代码时错误的

正确的代码:

#include<stdio.h>
int main()
{
	int num = 0;
	int i = 0;
	int count = 0;
	scanf("%d", &num);
	for (i = 0; i < 32; i++)
	{
		if (((num >> i) & 1) == 1)
		{
			count++;
		}
	}
	printf("%d\n", count);
	return 0;
}

上述代码是基于位操作符&(按位与只有两个数都是1结果才为1)来考虑的,我们将32位都拿去与1比较,即可得出二进制中1的个数。

但是上述代码并不是最优解,最经典的代码其实是下述代码:

#include<stdio.h>
int main()
{
	int num = 0;
	int count = 0;
	scanf("%d", &num);
 while(num)
  {
	num = num&(num - 1);
	count++;
  }
 	printf("%d\n", count);
	return 0;
}

num&(num-1)实际上是消除一个1,我们统计总共消除了多少次即可。

上述思路还可以用来写:求两个数二进制不同位的个数

可以自己尝试

异或^

异或^的基本概念:不同为1,相同为0  即0^1=1 1^0=1 0^0=0 1^1=0

题目:不创建变量的情况下交换两个数的值,以该题分析异或^的实际运用

#include<stdio.h>

int main()
{ 
	int m = 0;
	int n = 0;
	scanf("%d%d", &m, &n);
	m = m^n;
	n = m^n;    // 此时m=m^n  所以实际上n=m^n^n 其中n^n为0然后m^0为m,把m的值给了n
	m = n^m;    // 此时m=m^n n=m  所以实际上是m=m^m^n 其中m^m为0然后0^n为n,把n的值给了m
	printf("m=%d n=%d", m, n);
	return 0;
}

按位或|

按位或|的基本概念:两个数只要有一个为1就为1,即 1|1=1, 1|0=1,0|1=1 ,0|0=0

举例:11 | 10 为多少  (这两个是数值为十进制)

11的二进制表示为:1011

10的二进制表示为:1010    

所以11 | 10二进制表示为:1011  即结果为11

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值