【C语言】移位操作符 位操作符 - 对二进制位进行精准操作【+面试题目】_[初阶篇]

news2024/11/19 4:41:58

快速导航

【前言】

1.移位操作符

1.1左移操作符(<<)

1.2右移操作符(>>)

2.位操作符

2.1 & 按位与

2.2  | (按位或) 

2.3  ^ (按位异或)

3.面试题目

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

3.2统计二进制中1的个数 

3.2.1 方法一:右移(>>)和按位与(&)

3.2.2 方法二:使用取余操作符(%)

3.2.3 方法三:借助num&(num-1)​​​​​​​

【前言】

相信有很多人对移位操作符和位操作符并不是很理解,没有关系,认真读完本篇文章,你对C操作符的理解会上升到一个新高度。

虽然说本篇文章是初阶篇,但是文章内容并不简单,操作的时候涉及到二进制位,那我们就先来看一看何为二进制位?

二进制位简称“位”,是二进制记数系统中表示小于2的整数的符号,一般用1或 0表示,是具有相等概率的两种状态中的一种。

二进制位的位数可表示一个机器字的字长,一个二进制位包含的信息量称为 - 比特。

1.移位操作符

移位操作符有两种:一种是左移操作符(<<),另一种是右移操作符(>>)

这两种操作符都是对整数在存储在电脑中的二进制位进行操作(注意:移位操作符的操作数必须是整数)。

1.1左移操作符(<<)

接下来我们借助一个整数来更好的理解和应用左移操作符:

 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQ2F0enp6NjY2,size_18,color_FFFFFF,t_70,g_se,x_16

在计算机内存中存储的是二进制形式的补码,而正数的原码,反码,补码相同,5在内存中的补码:

 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQ2F0enp6NjY2,size_19,color_FFFFFF,t_70,g_se,x_16

移位操作符,移动的是二进制位,因为整数在内存中存储的是补码,所以移动的是内存中存储的补码 。

补码我们已经给出,接下来看一看移位操作符到底是怎么进行移位呢?

左移操作符移位原则:左边抛弃,右边补0。

#include <stdio.h>

int main()
{
    int a = 5;
    printf("%d\n", a << 1);
    return 0;
}

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQ2F0enp6NjY2,size_20,color_FFFFFF,t_70,g_se,x_16

5左移之后结果为10,看似是有乘2的效果的,那么是不是这样的呢?

下面我们来多举几个栗子验证一下。

#include <stdio.h>
int main()
{
	int a = -1;
	printf("%d\n", a << 1);
	
	a = -10;
	printf("%d\n", a << 1);

	a = 100;
	printf("%d\n", a << 1);
	return 0;
}

负数左移的效果也是一样的(以-1为例):

结论:左移操作符确实有乘2的效果。  

练习使用一下左移操作符:

原题链接:2的n次方计算_牛客题霸_牛客网 

题目描述:不使用累加法的基础上,使用左移操作符(<<) 完成2的n次方的计算。

 代码实现

#include <stdio.h>

int main()
{
    int n = 0;
    scanf("%d", &n);
    printf("%d\n", 1 << n);
    return 0;
}

1.2右移操作符(>>)

右移操作符和左移操作符是相似的,右移操作符和左移操作符最大的区别是在右移之后:

1.左边补符号位(算术右移)

2.左边补0(逻辑右移)

究竟是哪一种取决于程序的运行环境,不同编译器下右移方式可以不同。

int main()
{
	int a = -1;
	printf("%d\n", a >> 1);
	return 0;
}

上面是VS2019下的运行结果,VS2019支持的是算术右移。 

 注意:移位操作符,不要移动负数位,这是标准未定义的;

​​​​​​​对比一下左移操作符乘2效果,右移操作符是否具有除2的效果呢?

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQ2F0enp6NjY2,size_20,color_FFFFFF,t_70,g_se,x_16

对于正数来说,可以认为具有除2的效果,但是不要忘了负数;我们在上面举例的-1右移之后还是-1,就不满足了。 

所以不能直接说右移操作符具有除2的效果。​​​​​​​

2.位操作符

位操作符,是对一个数的二进制位进行操作,两个操作数,且操作数必须是整数。

具体分为三种:& (按位与)     |(按位或)     ^(按位异或)。计算机中位运算操作,均是以二进制补码形式进行的

2.1 & 按位与

两个数的二进制相同位同为1时结果为1,否则为0。

下面看一下使用按位与(&)操作的两种情况 :

2.2  | (按位或) 

 两个数的相同二进制位同为0时结果为0,否则为1。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQ2F0enp6NjY2,size_20,color_FFFFFF,t_70,g_se,x_16

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQ2F0enp6NjY2,size_20,color_FFFFFF,t_70,g_se,x_16

2.3  ^ (按位异或)

两个数相同二进制位相异时为1,相同是为0。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQ2F0enp6NjY2,size_20,color_FFFFFF,t_70,g_se,x_16 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQ2F0enp6NjY2,size_20,color_FFFFFF,t_70,g_se,x_16

3.面试题目

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

在交换两个变量时,我们经常会借助第三个变量tmp;

比如交换a和b的值:

int tmp = a;

a = b;

b = tmp;//那么不创建临时变量的话我们怎么来交换两个变量呢?

使用异或操作符(^),异或的两个特征:0^num = num;num^ num = 0;

 代码实现

int main()
{
    int a = 10;
    int b = 20;
    printf("a=%d, b=%d\n", a, b);
    a = a ^ b;
    b = a ^ b;//b修改为a
    a = a ^ b;//a修改为b
    printf("a=%d, b=%d\n", a, b);
    return 0;
}

缺陷:因为按位异或操作符的操作数只能是整数,所以交换的两个变量也必须是整数,只能完成两个整数的交换,无法完成两个浮点数的交换。 

3.2统计二进制中1的个数 

3.2.1 方法一:右移(>>)和按位与(&)

代码实现:

int getBinaryCount(int num)
{
	int count = 0;//记录二进制中1的个数
	int i = 0;
	for (i = 0; i < 32; i++)
	{
		if (((num >> i) & 1) == 1)
		{
			count++;
		}
	}
	return count;
}

3.2.2 方法二:使用取余操作符(%)

一个十进制的数,想要获取它的每一位,需要进行%10、/10;二进制的数也是一样的,可以通过%2、/2来获取每一位。

代码实现 

int getBinaryCount(unsigned int num)
{
	int count = 0;
	while (num)
	{
		if(num % 2 == 1)
			count++;
		num /= 2;
	}
	return count;
}

这里解释一下为什么要传入unsigned int类型:使用负数举例,如果num是-1的话,进入循环一次之后除2就变为0,无法得到二进制中1的正确个数;

使用unsigned int的话会把-1的补码当成一个正数的补码,这是一个很大的数,可以进行以上操作。

3.2.3 方法三:借助num&(num-1)

代码实现 

int getBinaryCount(int num)
{
	int count = 0;
	while (num)
	{
		num &= num - 1;
		count++;
	}
	return count;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/744.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

复合事件归因分析

1 复合事件 1.1 概述 1.2 类型 1.2.1 先决条件事件&#xff08;preconditioned events&#xff09; 1.2.2 多变量事件&#xff08;multivariate CEs&#xff09; eg.高温干旱 1.2.3 时间复合事件&#xff08;temporally CEs&#xff09; eg.旱涝急转 1.2.4 空间复合事件…

电子电路设计基本概念100问(二)【学习目标:原理图、PCB、阻抗设计、电子设计基本原则、基本原器件等】

笔者电子信息专业硕士毕业&#xff0c;获得过多次电子设计大赛、大学生智能车、数学建模国奖&#xff0c;现就职于南京某半导体芯片公司&#xff0c;从事硬件研发&#xff0c;电路设计研究。对于学电子的小伙伴&#xff0c;深知入门的不易&#xff0c;特开次博客交流分享经验&a…

【每天学习一点新知识】网络安全--拒绝服务攻击

目录 1、SYN泛洪攻击 SYN泛洪攻击原理 攻击过程 防御机制 2、Smurf攻击 Smurf攻击原理 间接攻击 放大攻击 防御机制 3、DDoS DDoS原理 直接DDoS攻击 间接DDoS攻击 防御机制 1、SYN泛洪攻击 SYN泛洪攻击原理 终端访问Web服务器之前需要和服务器之间建立TCP连接。W…

万字长文解析Scaled YOLOv4模型(YOLO变体模型)

一&#xff0c;Scaled YOLOv4 摘要1&#xff0c;介绍2&#xff0c;相关工作 2.1&#xff0c;模型缩放 3&#xff0c;模型缩放原则 3.1&#xff0c;模型缩放的常规原则3.2&#xff0c;为低端设备缩放的tiny模型3.3&#xff0c;为高端设备缩放的Large模型 4&#xff0c;Scaled-YO…

大学毕业后,我就送了2个月外卖,哭了一整晚

先简单介绍一下自己&#xff0c;我来自湛江&#xff0c;大学学的的物流管理专业&#xff0c;现在就职于一家互联网公司&#xff0c;从事软件测试工作。 我来自湛江的一个偏远农村&#xff0c;家里兄弟姐妹多&#xff0c;父母无力负担我的学费&#xff0c;很多时候学费都是靠姐…

红黑树 - c++

文章目录&#xff1a;红黑树的介绍红黑树节点定义红黑树的插入操作红黑树的删除红黑树的验证红黑树 vs AVL树红黑树的介绍 红黑树(Red-Black-Tree)&#xff0c;通常写为 R-B Tree。它是一种特殊的二叉搜索树。红黑树的每个节点上都有一个存储位来标识节点的颜色&#xff0c;可…

积木报表—JimuReport v1.5.4版本发布,免费的可视化Web报表工具

项目介绍 一款免费的低代码可视化报表&#xff0c;像搭建积木一样在线拖拽设计&#xff01;低代码开发必备&#xff0c;功能涵盖&#xff0c;数据报表、打印设计、图表报表、大屏设计等&#xff01; 秉承“简单、易用、专业”的产品理念&#xff0c;极大的降低报表开发难度、缩…

【css伪类选择器及透明度——附项目图片及代码】

不知不觉&#xff0c;又鸽了好长时间了&#xff0c;非常抱歉&#xff0c;没办法&#xff0c;毕竟开学了&#xff0c;今天课少&#xff0c;抽出了两个小时写了一篇css的&#xff0c;每天不是被催更&#xff0c;就是在催更的路上。放心&#xff0c;小陈陈有时间一定会给大家分享好…

SVM 支持向量机

SVM 支持向量机SVM 原理最优化问题线性不可分sklearn 调用 SVM核函数SVM 原理 前置知识&#xff1a;用迭代策略来划分样本&#xff0c;请猛击《神经元的计算》。 SVM 也是用一条迭代的直线来划分不同数据之间的边界&#xff1a; .- 是一条直线&#xff08;线性函数&#xff09…

数据结构c语言版第二版(严蔚敏)第五章笔记

目录 树和二叉树的定义 树的定义 树的基本术语 二叉树的定义 二叉树的性质和存储结构 二叉树的性质 二叉树的存储结构 顺序存储结构 链式存储结构 遍历二叉树和线索二叉树 遍历二叉树 先序遍历 中序遍历 后序遍历 前序遍历的递归算法 中序遍历的递归算法 后序…

SARScape中用sentinel-1数据做SBAS-InSAR完整流程(2/2)

书接上回&#xff1a;SARScape中用sentinel-1数据做SBAS-InSAR完整流程&#xff08;1/2&#xff09; SARScape中用sentinel-1数据做SBAS-InSAR完整流程&#xff08;2/2&#xff09;7 反演第一步Inversion&#xff1a;First Step7.1 导入设置7.2 optional file7.3 parameters参数…

齐博x1用户登录接口

用户的登录主要涉及到小程序登录、APP的帐号密码登录、APP的微信开发平台帐号登录。 相应的地址是&#xff1a;http://qb.net/index.php/index/wxapp.login/index.html 涉及到的方法如下 上面的地址&#xff0c;默认是小程序的登录与注册。 http://qb.net/index.php/index/wxa…

matlab/simulink电力电子仿真傅里叶变换模块(fourier)测幅值相角的设置与使用

matlab/simulink电力电子仿真傅里叶变换模块&#xff08;fourier&#xff09;测幅值相角的设置与使用 今天要说的是一个可以测量信号的幅值和相角的模块&#xff0c;fourier&#xff0c;长下面这样&#xff1a; 有时候我们需要求某个信号的幅值或者相位&#xff0c;或求两个…

用文字描述给黑白照上色,这个免费网站火了!网友:比其他同类都好用

金磊 Alex 发自 凹非寺量子位 | 公众号 QbitAI这是清朝末代皇后婉容广为流传的一张老照片&#xff1a;如果让照片变成彩色的&#xff0c;会是什么样子&#xff1f;竟然没有什么违和感&#xff0c;百年前的老照片似乎在此刻变得鲜活了起来。而这张图上色的背后&#xff0c;并没有…

BUUCTF NewStarCTF 公开赛赛道Week5 Writeup

文章目录WEBGive me your photo PLZBabySSTI_ThreeUnsafe ApacheSo Baby RCE AgainFinal roundMISC最后的流量分析奇怪的PDF 2奇怪的文本Yesec no drumsticks 5qsdzs girlfriend 5WEB Give me your photo PLZ 可上传.htaccess AddType application/x-httpd-php .jpg然后上传…

干货!手把手教你穿透内网

干货&#xff01;手把手教你穿透内网干货&#xff01;手把手教你穿透内网cpolar内网穿透使用场景如何使用cpolar内网穿透&#xff1f; ↓↓1. 注册cpolar账号2. 安装cpolar内网穿透2.1 Windows系统2.2 Linux系统2.2.1 安装2.2.2 向系统添加服务2.2.3 启动服务2.2.4 查看服务状态…

生成二维码或条形码JavaScript脚本库

二维码或条形码在日常生活中现在应用已经非常普遍了&#xff0c;文章分享生成条形码和二维码的JavaScript库。 条形码 条形码是日常生活中比较常见的&#xff0c;主要用于商品。通俗的理解就是一串字符串的集合&#xff08;含字母、数字及其它ASCII字符的集合应用&#xff09…

【机器学习基础】 线性回归

线性回归1、线性回归定义2、线性回归题目示例3、推导公式4、误差5、似然函数6、线性回归评价指标7、梯度下降1、线性回归定义 经典统计学习技术中的线性回归和softmax回归可以视为 线性神经⽹络。给定训练数据特征 X 和对应的已知标签 y &#xff0c;线性回归的⽬标是找到⼀组权…

Seata安装启动

一、下载 https://github.com/seata/seata/releases/download/v1.4.2/seata-server-1.4.2.zip 二、启动 在安装路径下cmd seata-server.bat -h 127.0.0.1 -m file 三、作用 Seata是分布事务解决方案&#xff0c;seata保证微服务远程调用业务的原子性 Seata将为用户提供了 …

Spring Cloud LoadBalancer--负载均衡的原理(源码分析)

原文网址&#xff1a;Spring Cloud LoadBalancer--负载均衡的原理&#xff08;源码分析&#xff09;_IT利刃出鞘的博客-CSDN博客 简介 说明 本文介绍Spring Cloud LoadBalancer负载均衡的原理。 SpringCloud从2020版本开始移除了对Ribbon的依赖&#xff0c;官方使用Spring Cl…