【C位运算&基础+面试题】位运算中阶详解及面试题
❤️山顶的风景很美❤️
本篇基础:需要你要对正负数的二进制序列的原反补码有所了解。
测试题: 先来一道测试题看看你究竟掌握了没有:
品茗股份有限公司的一道面试题:
不使用第3个变量的情况下,交换2个数的大小。 例如: 交换前:a=3,b=5; 交换后:a=5,b=3;
给你几分钟,如果做不出来的话,就听博主给你娓娓道来。(?答案在文末)
文章目录
一. 按(二进制)位操作符
正数和负数需先转换成相应的二进制的补码,再进行移位运算
操作对象:补码
1-1.左移操作符<<(乘法)
?用法:
int a=7<<1;//为例
?规则:
将a的二进制序列的补码向左移动1位,左边丢弃,右边补0
?图示:
?代码结果:
1-2.右移操作符>>(除法)
?用法:
int a=-7>>1;//为例
?规则:
将a的二进制序列的补码向右移动1位 至于后续操作是什么呢?以下有如下两种公认的两种说法: 算术右移:右边丢弃,左边补原符号位 逻辑右移:右边丢弃,左边补0
?图示:
?代码结果:(我的编译器支持的是算术右移)
1-3.除乘二小技巧
?备注:按位操作符:
按位操作的正数m<<位移的位数n = m乘以2的n次方 按位操作的正数m>>位移的位数n = m除以2的n次方
?最常用的当然是乘2除2的操作:(这个的运行是时间比/*2快,推荐使用)
?代码结果:
二.(二进制)位操作符
操作对象:补码
2-1按位与&(类似乘法)
?技巧:
相当于乘法
?规则:
只有两个数的二进制的补码同时为1,结果才为1,否则为0
?用法:
int c=3&5;//为例
printf("%d",c);
?图示:
?代码结果:
2-2.按位或(类似加法)
?技巧:
相当于加法
?规则:
只有两个数的二进制的补码同时为0,结果才为0,否则为1
?刷题技巧:
- ? 0|5,0|7 任何数和0|保持不变
- ? 1|5,1|7 任何数和1|被设置为1
?用法:
int c=3 | 5;//为例
printf("%d",c);
?图示:
?代码结果:
2-3.按位异或^
深入点了解^:纯粹的按位或
?规则:
逐比特位,相同为0,不同为1
?刷题翻译:
支持结合律和交换律
任何数和0异或,都是他本身
?用法:
int c=3^5;//为例
printf("%d",c);
?图示:
?代码结果:
三. 三道实战题
3-1.求一个正数的二进制序列中有几个1
?思路:n = n & (n - 1);
?1.设这个正数n,n-1就是使n-1的二进制的原码/补码少1; ?2.再将n与n-1按位与,由按位与的性质,n和n-1的二进制的最后一位一定相差1,肯定就是一个1,一个0,按位与后就是0,每进行一次就使得n减少一个1; ?3.给个循环,当n全为0时结束,最后循环的次数就是这个正数的二进制序列中有几个1。
?图示:
?图解:
?代码:
#include<stdio.h>
int main1()
{
//1.求一个正数的二进制序列中有几个1
int n = 0, count=0;
scanf("%d", &n);
while (n)
{
n = n & (n - 1);
count++;
}
printf("这个数的二进制序列中有%d个1", count);
return 0;
}
?运行结果:
3-2.现有两个正数m,n,m的二进制序列要改变多少多少处可以得到n
?整体思路:
?1.先进行异或操作 如c=a^b; c得到的是a,b变量二进制中不同的地方,标记为1(a,b均为正数) ?2。相当于求异或后不同之处(已标记为1)1的个数,即为题一思路
?代码:
#include<stdio.h>
int main()
{
// 2.现有两个正数m,n,m的二进制序列要改变多少多少处可以得到n
int m = 0, n = 0, temp = 0, count = 0;
scanf("m=%d n=%d", &m, &n);
temp = m ^ n;
while (temp)
{
temp = temp & (temp - 1);
count++;
}
printf("m的二进制序列要改变%d处可以得到n", count);
}
?结果:
3-3.不使用第三个变量,交换两个数的值(答案?)
?代码:
#include<stdio.h>
int main()
{
//3.不使用第三个变量,交换两个数的值(答案?)
int a=0, b=0;
scanf("a=%d b=%d", &a, &b);;
printf("交换前:a=%d\tb=%d\n", a, b);
a = a ^ b;
b = a ^ b;
a = a ^ b;
printf("交换后:a=%d\tb=%d\n", a, b);
return 0;
}
?图示:
?运行结果:
?最后,到这里就结束了,码字不易,耗时耗力,欢迎三联一波。???
想了解更多位运算的应用题目,速戳位运算题目合集
相关文章
- 万万没想到,go的数据库操作,也能像php一样溜了
- Typora+PicGo+GitHub实现图片快速上传
- Linux计划任务服务程序
- 2022 如何在 GitHub 上搭建个人网站(github.io)
- 虚拟机安装linux无法访问外网解决办法
- 用过 mongodb 吧, 这三个大坑踩过吗?
- 教你配置windows上的windbg,linux上的lldb,打入clr内部这一篇就够了
- MongoDB 在评论中台的实践
- 使用mongodb作为Quartz.Net下的JobStore实现底层的持久化机制
- mongodb之使用explain和hint性能分析和优化
- mongodb 3.x 之实用新功能窥看[2] ——使用$lookup做多表关联处理
- mongodb 3.x 之实用新功能窥看[1] ——使用TTLIndex做Cache处理
- 双十一来了,别让你的mongodb宕机了
- GO语言开发环境搭建笔记
- PHP判断网络连通
- 开启phpMyAdmin的远程登录
- PHP_cURL初始化和执行方法
- PHP经典函数收集
- PHP所有函数列表
- php bbcode过滤