按位操作符相关例题详解

本文通过实例讲解了操作符如按位与(&),按位或(|),按位异或(^),取反(~)在编程中的使用,涉及变量交换、二进制中1的计数、不同位查找、二进制位置修改以及整数奇偶位打印等,适合初学者理解基础IT技术概念。
摘要由CSDN通过智能技术生成

前言:

本篇文章致力于通过例题讲解帮助读者理解操作符的使用。

阅读须知:

1. ‘ & ’按位与,两个1取1,其余为0。

2.‘ | ’按位或,两个0取0,其余为1。

3. ‘ ^ ’按位异或,相异取1。

4.‘ ~ ’按位取反。

5.n^n=0,n^0=n。

6.(n>>i)&1可以求二进制最右边的数。

注意:在计算机中我们针对的改变是补码的,但计算机打印在屏幕上的是转化后的原码,不要搞错了。


目录:

(一)交换两个变量(不创建临时变量)

1.题目要求

2.代码演示

3.代码解析

(二)统计二进制中1的个数

1.题目要求

2.思路分析

方法一:

方法二

方法三:

3.代码演示

代码1:

代码2:

代码3:

(三)求两个数二进制中不同位的个数

1.题目要求

2.思路分析

3.代码演示

(四)二进制位置1或0

1.题目要求

2.思路分析

3.代码演示

结果:

(五)单身狗1

1.题目要求

2.思路分析

3.代码演示

(六)打印整数二进制的奇数位和偶数位

1.题目要求


(一)交换两个变量(不创建临时变量)

1.题目要求

不允许创建临时变量,交换两个整数的内容

2.代码演示

#include<stdio.h>
int main()
{
	int a = 1;
	int b = 2;
	a = a ^ b;
	b = a ^ b;
	a = a ^ b;
	printf("a=%d,b=%d\n", a, b);
	return 0;
}

3.代码解析

‘ ^ ’按位异或的特点是:相异取一。两个相同的数,它们二进制的每一位都相同,所以每一位都取0,所以有n^n=0。两个不同的数,一个数是0,取相异的位为1,其余为0,于是有n^0=n。

(二)统计二进制中1的个数

1.题目要求

写一个函数返回参数二进制中 1 的个数。(题源:牛客网)

比如: 15    0000 1111    4 个 1               

2.思路分析

方法一:

我们可以类比十进制求1 的个数的方法:

所以我们可以通过不断地除2和%2得到15的二进制数,再去找1

由此我们得到关键步骤:

while (num)//当num等于0时,条件为假,跳出循环
	//且0的补码中全是0							
{
	if (num % 2 == 1)
	{count++;}
	num = num / 2;
}

注意:我们假设当num=-2时,就有(-2)%2 == 0,无法进行count ++ ,但是我们知道负数的符号位始终为1,应当进行count++操作,所以为了避免这种情况发生,我们要在while循环前声明:unsigned int num!!!

方法二:

我们这里也可以用按位与‘&’来做,我们想知道二进制最低位是否为1时用&。

我们可以通过这个方法来找1,我们不只要判断最低位,还要判断其他位是否为1,所以我们可以通过让n的补码不断地>>1(右移1位),这一步可以通过for循环来完成。

注意:(n>>i)里的n值不变,改变的是括号这个整体的值。

for(i=0;i<32;i++)
{
    if((n>>i)&1==1)
//n不断地右移,把每一个数逐一放在最低位,然后左边不断补0
//如果括号内的表达式可以运行就count++
    {count++};
}

这里给大家推一遍过程:

方法三:

还有一种很少见的方法,为大家简单做个介绍:n=n&(n-1)

由此我们可以得到思路,利用while循环判断n是否是非0,若为真,执行一次n=n&(n-1)

,再去掉一个1,每执行一次就count++,直到n=0,二进制中没有1了为止。

3.代码演示

代码1:
#include<stdio.h>
int main()
{
	unsigned int num;
	int count = 0;
	printf("请输入一个整数:");
		scanf_s("%d", &num);
		while (num)//当num等于0时,条件为假,跳出循环
			//且0的补码中全是0							
		{
			if (num % 2 == 1)
			{count++;}
			num = num / 2;
		}
		printf("其二进制数共有%d个1。", count);
	return 0;
}
代码2:
{
	int count = 0;
	int n,i;
	printf("请输入一个整数:");
		scanf_s("%d", &n);
		for (i = 0; i < 32; i++)
		{
			if((n>>i)&1==1)//(n>>i)并没有改变n的值,而是改变了它们运算的结果
			{
				count++;
			}
		}
		printf("其二进制数共有%d个1",count);
		return 0;
}
代码3:
#include<stdio.h>
int main()
{
	int n;
	int count = 0;
	scanf_s("%d", &n);
	while (n)
	{
		n = n & (n - 1);
		count++;
	}
	printf("共有%d个1",count);
	return 0;
}

(三)求两个数二进制中不同位的个数

1.题目要求

编程实现:两个int(32位)整数m和n的二进制表达中,有多少个位(bit)不同?(题源:牛客网) 

输入例子:

1999 2299

输出例子:7

2.思路分析

我们设想一下,我们知道一个数的补码一共有32位,如果我输入的两个整数一个是3,一个是5:

我们要查找这两个数的补码中有几个位不一样,我们可以利用按位异或的特点:不一样的位取1,其余为0。由此得到一个新的二进制数:

我们由第二个大题第二个方法可知,我们可以通过这个代码查找出有几个1,这样就知道二进制不同位的个数了。

for(i=0;i<32;i++)
{
    if((n>>i)&1==1)
//n不断地右移,把每一个数逐一放在最低位,然后左边不断补0
//如果括号内的表达式可以运行就count++
    {count++};
}

3.代码演示

#include <stdio.h>

int main()
 {
    int a, b;
    int count = 0;
    
    scanf("%d %d", &a, &b);

    int c = a ^ b;

    for (int i = 0; i < 32; i++) 
    {
        if(((c >> i) & 1) == 1)
        {
            count++;
        }
    }

    printf("%d", count);

    return 0;
}

(四)二进制位置1或0

1.题目要求

比如:将13的二进制序列的第五为修改为1,然后再改回0。

2.思路分析

3.代码演示

代码1:
#include<stdio.h>
int main()
{
	int n;
	printf("请输入一个整数:");
		scanf_s("%d", &n);
			n |= (1 << 4);
			printf("%d\t", n);
			n &=(~(1 << 4));
			printf("%d", n);

	return 0;
}
代码2:
#include<stdio.h>
int main()
{
	int n;
	printf("请输入一个整数:");
		scanf_s("%d", &n);
			n |= (1 << 4);
			printf("%d\t", n);
			n ^=(1 << 4);
			printf("%d", n);

	return 0;
}
结果:

(五)单身狗1

1.题目要求

在一个整型数组中,只有一个数字出现一次,其他数组都是成对出现的,请找出那个只出现一次的数字。

例如:

数组中有:1 2 3 4 5 1 2 3 4,只有5出现一次,其他数字都出现2次,找出5

2.思路分析

跟据第一题,我们知道n^n=0,n^0=n。而题目中的数组里只有一个数出现了一次,所以我们如果让它们每一个数都相异或:

由此就可以得到我们的单身狗了。

3.代码演示

​
#include<stdio.h>
int Alone(int arr[], int n)
{
	int i;
	int result = 0;
	for (i = 0; i < n; i++)
	{
		result ^= arr[i];//和阶乘的写法类似
	}
	return result;
}
int main()
{
	int alone;
	int result = 0;
	int arr[] = {1,2,3,4,5,1,2,3,4};
	int n = sizeof(arr) / sizeof(arr[0]);//求数组的个数
	//注意数组名不要写错了
	alone = Alone(arr, n);//注意这里arr没有【】!
	printf("单身狗是%d", alone);
	return 0;
}

​

(六)打印整数二进制的奇数位和偶数位

1.题目要求

获取一个整数二进制序列中所有的偶数位和奇数位,分别打印出二进制序列

2.思路分析

第一步:我们首先假设最低位是第31个,最高位是第0个。然后再用for循环,每循环一次就让i减一个2,分别求二进制的奇数位和偶数位。

第二步:二进制中只由0和1组成,我们可以通过让二进制数经过这个代码:(num>>i)&1(第二个答题第二个方法)求出每循环一次后的最低位是多少,再printf打印出来。

3.代码演示

#include<stdio.h>
void Printbit(int num)
//不需要返回值,直接打印即可,所以在函数前加个void
{
	printf("偶数位:");
	for (int i = 31; i >= 1; i -= 2)
		//个数从0开始计数,所以这里的第一个数是偶数位
	{
		printf("%d ", (num >> i) & 1);//把最低位的数字求出来
	}
	printf("\n");
	printf("奇数位:");
	for (int i = 30; i >= 0; i -= 2)
	{
		printf("%d ", (num >> i) & 1);
	}
	printf("\n");
}
int main()
{
	int num;
	printf("请输入一个整数:");
	scanf_s("%d", &num);
	Printbit(num);
	return 0;
}


好了今天就先分享这么多,有问题的朋友请再评论区留言,我会回复的。如果你喜欢本篇文章的内容可以为我点个赞吗?非常感谢^ ^

  • 35
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值