前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【C位运算&基础+面试题】位运算中阶详解及面试题

【C位运算&基础+面试题】位运算中阶详解及面试题

作者头像
MicroFrank
发布2023-01-16 13:01:20
2830
发布2023-01-16 13:01:20
举报
文章被收录于专栏:同步文章1234同步文章1234

❤️山顶的风景很美❤️

本篇基础:需要你要对正负数的二进制序列的原反补码有所了解。

测试题: 先来一道测试题看看你究竟掌握了没有:

品茗股份有限公司的一道面试题

不使用第3个变量的情况下,交换2个数的大小。 例如: 交换前:a=3,b=5; 交换后:a=5,b=3;

给你几分钟,如果做不出来的话,就听博主给你娓娓道来。(😇答案在文末)

文章目录

  • 一. 按(二进制)位操作符
    • 1-1.左移操作符<<(乘法)
    • 1-2.右移操作符>>(除法)
    • 1-3.除乘二小技巧
  • 二.(二进制)位操作符
    • 2-1按位与&(类似乘法)
    • 2-2.按位或(类似加法)
    • 2-3.按位异或^
    • 三. 三道实战题
      • 3-1.求一个正数的二进制序列中有几个1
      • 3-2.现有两个正数m,n,m的二进制序列要改变多少多少处可以得到n
      • 3-3.不使用第三个变量,交换两个数的值(答案😇)

一. 按(二进制)位操作符

正数和负数需先转换成相应的二进制的补码,再进行移位运算

操作对象:补码

1-1.左移操作符<<(乘法)

🎈用法:

代码语言:javascript
复制
int a=7<<1;//为例

🎈规则:

将a的二进制序列的补码左移动1位,左边丢弃,右边补0

🎈图示:

在这里插入图片描述
在这里插入图片描述

🎈代码结果:

在这里插入图片描述
在这里插入图片描述

1-2.右移操作符>>(除法)

🎈用法:

代码语言:javascript
复制
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

在这里插入图片描述
在这里插入图片描述

🎈用法:

代码语言:javascript
复制
int c=3&5;//为例
printf("%d",c);

🎈图示:

在这里插入图片描述
在这里插入图片描述

🎈代码结果:

在这里插入图片描述
在这里插入图片描述

2-2.按位或(类似加法)

🎈技巧:

相当于加法

🎈规则:

只有两个数的二进制的补码同时为0,结果才为0,否则为1

在这里插入图片描述
在这里插入图片描述

🎈刷题技巧:

  1. 👌 0|5,0|7 任何数和0|保持不变
  2. 👌 1|5,1|7 任何数和1|被设置为1

🎈用法:

代码语言:javascript
复制
int c=3 | 5;//为例
printf("%d",c);

🎈图示:

在这里插入图片描述
在这里插入图片描述

🎈代码结果:

在这里插入图片描述
在这里插入图片描述

2-3.按位异或^

深入点了解^:纯粹的按位或

🎈规则:

逐比特位,相同为0,不同为1

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

🎈刷题翻译:

支持结合律和交换律

在这里插入图片描述
在这里插入图片描述

任何数和0异或,都是他本身

在这里插入图片描述
在这里插入图片描述

🎈用法:

代码语言:javascript
复制
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。

🎈图示:

在这里插入图片描述
在这里插入图片描述

🎈图解:

在这里插入图片描述
在这里插入图片描述

🎈代码:

代码语言:javascript
复制
#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的个数,即为题一思路

🎈代码:

代码语言:javascript
复制
#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.不使用第三个变量,交换两个数的值(答案😇)

🎈代码:

代码语言:javascript
复制
#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;
}

🎈图示:

在这里插入图片描述
在这里插入图片描述

🎈运行结果:

在这里插入图片描述
在这里插入图片描述

👌最后,到这里就结束了,码字不易,耗时耗力,欢迎三联一波。🙌🙌🙌

想了解更多位运算的应用题目,速戳位运算题目合集

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-05-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 一. 按(二进制)位操作符
    • 1-1.左移操作符<<(乘法)
      • 1-2.右移操作符>>(除法)
        • 1-3.除乘二小技巧
        • 二.(二进制)位操作符
          • 2-1按位与&(类似乘法)
            • 2-2.按位或(类似加法)
              • 2-3.按位异或^
                • 三. 三道实战题
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档