当前位置: 首页 > news >正文

【C语言】位操作符与移位操作符练习

目录

前言:

1.一道变态的面试题

2.输入一个整数 n ,输出该数32位二进制表示中1的个数。其中负数用补码表示。

方法一:

方法二:

方法三:

3.打印整数二进制的奇数位和偶数位


前言:

前篇我们学习过C语言的位与移位操作符详解【C语言】位与移位操作符详解-CSDN博客

这篇博客将带领大家继续练习相关知识。

1.一道变态的面试题

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

解析:通过上节我们学习的位与移位操作符,我们可以大概知道需要用到它们。

通过学习我们可知:

①a & a = a ②a | a = a ③a ^ a = 0 ④a & 0 = 0 ⑤a | 0 = a ⑥a ^ 0 = a

要交换两个整数的内容我们要使用③⑥两个公式

a^a^b=b

代码如下:

#define _CRT_SECURE_NO_WARNINGS 1
//不允许创建临时变量,交换两个整数的内容
#include<stdio.h>
int main()
{int a = 3;int b = 5;a = a ^ b;b = a ^ b;//实际上是a^b^b=a^0=aa = a ^ b;//实际上是a^b^a=0^b=bprintf("%d\n", a);printf("%d\n", b);return 0;
}

 运行结果如下:

2.输入一个整数 n ,输出该数32位二进制表示中1的个数。其中负数用补码表示。

方法一:

解析:我们知道按位与是同真为真也就是二进制中都是1才为1,只要有一个不为1就是0;

所以如果我们将n按位与1(1的二进制除了最后一位其他都是0),那么我们就可以知道n最后一位是1还是0了,如果再通过右移操作符将n的二进制一回移动一个,那么我们就可以得知n每位是1还是0了,问题就得到解决啦~

🎉🎉✨检测num中某一位是0还是1的方式:

1.将num向右移动i位

2.将移完位之后的结果与1按位与,如果.结果是0,则第i个比特位是0,结果是非0,则第i个比特位是1

以下是解析图:

代码如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>//2.输入一个整数 n ,输出该数32位二进制表示中1的个数。
// 其中负数用补码表示。
int main()
{int n = 0;printf("请输入整数n:");scanf("%d", &n);int i = 0;//创建i变量用以循环32次int count = 0;//创建count变量用以记录i的个数for (i = 0; i < 32; i++){count += (n>>i) & 1;}printf("\n%d的二进制中1的个数为:%d\n",n,count);return 0;
}

运行结果如下:

 

方法一

优点:用位操作代替取模和除法运算,效率稍微比较高

缺陷:不论是什么数据,循环都要执行32次 

方法二:

代码如下: 

int main()
{int n = 0;printf("请输入整数n:");scanf("%d", &n);int count = 0;//创建变量计数while (n & (n - 1))//当n与相邻位按位与不为0时{n = n & (n - 1);count++;}count += 1;//注意最后为0的也要算进去printf("\n二进制中1的个数为:%d\n",  count);return 0;
}

这里要注意两点💥:

(1)n&(n-1)后要将它的值赋给n,而不是将n-1赋给n;

n = n & (n - 1);

(2)最后n&(n-1) = 0时while已经出了循环,所以最后count还要+1; 

count += 1;//注意最后为0的也要算进去

代码运行结果如下: 

方法三:

代码如下:

int main()
{int n = 0;printf("请输入整数n:");scanf("%d", &n);int count = 0;//创建变量计数while (n){if (n % 2 == 1)count++;n =n/ 2;}printf("\n二进制中1的个数为:%d\n", count);
}

运行结果如下:

上述方法缺陷:进行了大量的取模以及除法运算,取模和除法运算的效率本来就比较低。 

3.打印整数二进制的奇数位和偶数位

思路:
1.提取所有的奇数位,如果该位是1,输出1,是0则输出0

2.以同样的方式提取偶数位置(我们可以用移位操作符来提取)


💫检测num中某一位是0还是1的方式:

1.将num向右移动i位

2.将移完位之后的结果与1按位与,如果.结果是0,则第i个比特位是0,结果是非0,则第i个比特位是1

代码如下:

int main()
{int num = 0;printf("请输入整数num:");scanf("%d", &num);for (int i = 31; i >= 1; i -= 2){printf("%d ", (num >> i) & 1);}printf("\n");for (int i = 30; i >= 0; i -= 2){printf("%d ", (num >> i) & 1);}printf("\n");return 0;
}

运行结果如下:

http://www.lryc.cn/news/302410.html

相关文章:

  • 第十四届“中关村青联杯”全国研究生数学建模竞赛-A题:无人机在抢险救灾中的优化运用
  • Android 9.0 Launcher3桌面显示多个相同app图标的解决办法
  • WordPress主题YIA在广告位添加图片广告时下方有空白怎么办?
  • 5.15 BCC工具之kvm_hypercall.py解读
  • git 解除本地分支与其它分支(远程分支)的关联
  • conda 所有的命令及其讲解
  • mysql 数据库主从复制搭建
  • 小白水平理解面试经典题目LeetCode 1025 Divisor Game【动态规划】
  • 基于单片机的智能宠物喂食器设计
  • 探索单片机应用领域:从智能家居到工业自动化
  • Nginx介绍和使用
  • 异步编程——CompletableFuture用法详解
  • Linux常用命令(不断更新)
  • C++ 浮点数二分 数的三次方根
  • 辽宁博学优晨教育科技有限公司视频剪辑培训专业之选
  • 数据转换成json格式
  • css3的var()函数
  • 武汉灰京文化展望未来游戏产业,科技创新引领全面升级的游戏体验
  • SOLIDWORKS Visualize 界面介绍
  • 负载均衡下webshell连接nginx解析漏洞、sql注入第一关
  • 养老项目技术架构和工程结构
  • 免费白嫖一个互联网创业者交流论坛,真香!
  • Zilliz Cloud 再发新版本:性能提升超 10 倍,AI 应用开发流程再简化!
  • 基于SpringBoot的高校竞赛管理系统
  • 【国产MCU】-CH32V307-通用定时器(GPTM)-编码模式与旋转编码器驱动
  • 国外高防服务器需要注意哪些方面
  • MySQL系列之索引入门(下)
  • IO进程:fread\fwrite图像拷贝,read\write文件拷贝,时间函数
  • 基于java的企业校园招聘平台的设计与实现
  • Rocky Linux网卡静态配置