新手入门C语言之移位操作符和位操作符

在C语言中,移位操作符和位操作符是专门针对二进制的数字进行,因此,在描述移位操作符和位操作符之前,我们先来了解十进制,二进制,八进制,十六进制等的含义以及相互之间的转化。

一.进制以及相互的转化

十进制,二进制,八进制,十六进制等只是数值的不同表示形式,十进制就是逢10进1位,二进制就是逢2进1,以此类推。

十进制每个位置上的值的范围是0-9,二进制是0-1,那么他们是如何进行转化的呢?

1.二进制转化为十进制

首先来看,我们是怎么读出十进制的数字的,实际上,例如:123,我们是运用了

这样的计算方法来获得答案的,3对应的是10的0次方,2×10的一次方,以此类推,最后求和即可

那么我们想把二进制数字转换为十进制的数字,实际上也可以运用这样的计算方法,只不过是改成成了✖2的多少次方。

例如,我们求二进制数字1101转换为十进制的数字:

如果我们想将一个八进制数字转换为十进制数字,也是非常简单的:

2.十进制转换为二进制

例如,我们要将十进制数字125转换为二进制数字,我们运用这样的方法:

1.将十进制数字除以2,保留整数部分,将余数写在后面

2.一直进行1过程,直到为0

3.余数按反向书写即可获得二进制数字

3.二进制转化为八(十六)进制

从右向左,三个为一组,无法组成一组就单独进行计算,例如二进制数字1011101转换为八进制数字,我们是这样做的:

转化为十六进制的时候,从右向左,四个为一组即可

需要注意,十六进制每个位置的范围是0~F,包括0~9,A~F,A是10,F是15

确定八进制的数字时候前面加0,例如023,就是八进制的数字,十六进制前面加0x或0X,十六进制的符号大小写与x的相同

5.八(十六)进制转化为二进制

只需要二进制转化的反向进行转化即可

二.原码,反码,补码

三者描绘的都是整数

由于int类型是4个字节,32个bit,每个bit位置可以存放1个二进制数字,但是只有31位可以放大小,最开头的一位放入的数字表示正负

原码:整数的二进制表示,其中我们知道数字分为正数和负数,因此,我们需要额外来表示正负,如果数字为正数的时候,原码的符号位位0,负数则符号位为1

反码,补码:正数的反码和补码与原码一样

负数的反码:负数的原码除了符号位所有位置取反,如果原位置是1,现在改为0

负数的补码:负数的反码+1

转化过程如图:

事实上,原码可以经过取反+1变为补码,补码也可以通过取反+1变为原码

我们在运算的时候,统一使用的都是补码来进行运算

三.移位操作符

移位操作符分为:<<左移操作符    >>右移操作符

书写方法是 a >> (移位的数量),例如:

int b = a >> 2;

1.左移操作符的移动规律:

采用二进制数字全部左移,空位补0的方法,例如,我们写出10的补码以

现在向左移位,空位补0,超出范围的去掉

我们会发现,最后得到的结果是20,因为向左移动,代表着*2

负数也是如此,不过记得,移动的是补码,移动后也是补码

2.右移操作符的移动规律

一般来说,采用数字移动的规律,就是全部右移,然后空位补符号位的数字

四.位操作符

位操作符分为:

1.按位与&:

两个数字的补码的二进制数字在某一个位置上都为1时才为1,只要有0则位0,例如:

int a = 4;	//00000000000000000000000000000100	4补码
int b = -7; //11111111111111111111111111111001 -7补码
            //00000000000000000000000000000000

我们发现,此时没有相同的,故a&b = 0

2.按位或|:

对应位置有1就是1,都0才是0,例如

int a = 4;	//00000000000000000000000000000100	4补码
int b = -7;	//11111111111111111111111111111001	-7补码
            //11111111111111111111111111111101   a|b的补码  
			//10000000000000000000000000000011    还原为原码
			//-3

一定要记得获得的是补码哦

3.按位异或^:

相同为0,想异为1

int a = 4;	//00000000000000000000000000000100	4补码
int b = -7;	//11111111111111111111111111111001	-7补码
            //11111111111111111111111111111101
				//-3

4.按位取反~:

所有位置变为与原本不同的数

五.例题

1.不创建(临时)第三个变量,实现整数交换

我们在实现整数交换时,运用的是这种方法:

int main() {
	int a = 3;
	int b = 5;
	int c = 0;
	c = a;
	a = b;
	b = c;
	printf("%d %d", a, b);
	return 0;
}

假设有两个瓶子,分别装了醋和酱油,现在让两个瓶子里面的东西反过来,我们额外拿来了一个瓶子,然后进行了操作。

但在这个题目中,他让我们不创建临时变量,也就是不能额外拿来一个瓶子,实现整数的交换

我们可以采用这种方法:

int main() {
	int a = 3;
    int b = 5;
	//当a与b特别大的时候,超过最大值出现位数丢失(溢出)
	a = a + b;	//a = 8	b = 5
	b = a - b;	//b = 3 a = 8
	a = a - b;	//a = 5 a = 3

	printf("%d %d", a, b);
	return 0;
}

这样就可以交换a与b的值了,但是如果a与b两个整数非常大的时候,我们想加可能超过最大的范围,因此,这个方法有一定的局限性

我们在之前学习了^,它有如下的式子 a ^

a = 0,因为两者完全相同,同时 a ^ 0 = a,我们可以写出如下的代码:

int main() {
	int a = 3;
	int b = 5;
	a = a ^ b;
	b = a ^ b;		// a ^ b ^ b = a
	a = a ^ b;		// a ^ b ^ a = b
	printf("%d %d", a, b);
	return 0;
}

在这里,我们将a ^ b 视为了一个整体,进行的运算

2.计算一个数字的二进制数的1的数量

如果一个数字%2等于1,此时它的二进制数字的最后一位为1,我们可以写出如下的函数:

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

其中m要是unsigned int类型,因为m传进去是一串二进制数,如果是负数还需要单独判断,此时,我们将他们统一视为了正数进行的判断

当然,我们也可以通过移位操作符,来判断每一位上是否为1,写出如下的函数:

int count1(unsigned int m) {
	int count = 0;
	int i = 0;
	for (i = 0; i < 32; i++) {
		if (((m >> i) & 1) == 1)
			count++;
	}
	return count;
}

使得m不断向右移动,来计算

同时,n = n ^ (n-1)的方法可以更快的进行运算,函数如下:

// n = n & (n-1)	让n的二进制中最右边的1消失
// n = 0时,执行几次就是有几个1		有几个1统计几次
int count2(unsigned int m) {
	int count = 0;

	while (m) {
		count++;
		m = m & (m - 1);
	}
	return count;
}

感谢您的观看!

如果您想要进行进一步的训练请移步

C语言进制习题-CSDN博客

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Qt 设置隐式加载dll路径

在c++中DLL的加载方式有两种,显式加载和隐式加载。 隐式加载 在程序从开始运行时,就会按照系统中一定的搜索路径,寻找动态库,找到就自动加载它,才能成功运行程序,这些步骤,是系统自动完成的。 显示加载 我们对动态库的调用,是在代码中直接使用LoadLibrary,或其他加载函…

Project_Euler-26 题解

Project_Euler-26 题解 题目 思路 暴力枚举。 题目中已经给了一个范围&#xff1a; d < 1000 d<1000 d<1000&#xff0c;我们可以尝试顺着这个思路往下走&#xff0c;遍历这1000个值&#xff0c;分别查看 1 / d 1/d 1/d 的值中有没有循环节&#xff0c;并看看他们有…

python快速实现可使用不同颜色画笔的画布功能界面

核心组件&#xff1a;tkinter库 Tkinter是Python的标准GUI&#xff08;图形用户界面&#xff09;工具包&#xff0c;它提供了创建GUI应用程序的功能。Tkinter是Python自带的库&#xff0c;因此无需额外安装即可使用。它基于Tk GUI工具包&#xff0c;是Python的标准GUI工具包之一…

Linux修改shell工具连接端口

nano /etc/ssh/sshd_config 或者 vi /etc/ssh/sshd_config 或者 vim /etc/ssh/sshd_config

idea2023新UI风格不见了怎么办?

用了一段时间idea2023,有一天不知道点了什么&#xff0c;整个UI又变成了2022的风格 如果想换成2023的UI风格怎么办&#xff1f; 点击file->setting->new UI->勾选Enable new UI&#xff0c;restart就可以回到最新版本的UI了 新风格

JavaSE-05笔记【面向对象02】

文章目录 1. 类之间的关系2. is-a、is-like-a、has-a2.1 is-a2.2 is-like-a2.3 has-a 3. Object类3.1 toString()3.2 finalize()&#xff08;了解即可&#xff09;3.3 与 equals 方法 4. package 和 import4.1 package4.2 import4.3 JDK 常用开发包 5. 访问权限控制5.1 privat…

[DP学习] 期望DP

一般思路 注&#xff1a;可以用方差求平方的期望 例题一 思路 重点&#xff1a;如何设状态&#xff0c;如何转移。 设状态 f[i] i 张能买到不同卡片的种类数的期望值&#xff08;直接对问题设置状态&#xff09; 状态转移&#xff1a;由于从f[i1]转移到 f[i] 时&#xff0…

什么是飞行时间传感器以及 ToF 传感器如何工作?

译自https://www.seeedstudio.com/blog/2020/01/08/what-is-a-time-of-flight-sensor-and-how-does-a-tof-sensor-work/ 作者:亿达 您是否听说过飞行时间(也称为 ToF)用于您的手机、相机等,但不知道它们的用途及其工作原理? 通过本指南,您将了解有关 ToF 传感器和相机的…

unity学习(38)——创建(create)角色脚本(panel)--EventSystem

1.在scripts文件夹下创建一个脚本CreatePlayerPanel.cs&#xff0c;脚本挂到panel上&#xff01;给panel加个tag&#xff0c;叫createPanel&#xff0c;脚本内容如下&#xff1a; using System.Collections; using System.Collections.Generic; using TMPro; using UnityEngin…

javaEE图书馆自习室订座系统信用springmvc+springboot+mybatis

研究的内容是设计和实现图书馆自习室系统&#xff0c;便捷广大师生对自习室的使用&#xff0c;协助图书馆自习室管理。在设计过程中&#xff0c;系统的用户角色和权限分配如下&#xff1a; &#xff08;1&#xff09;馆长 用户管理&#xff1a;拥有自习室管理员、普通用户的所有…

可视化 RAG 数据 — 用于检索增强生成的 EDA

原文地址&#xff1a;Visualize your RAG Data — EDA for Retrieval-Augmented Generation 2024 年 2 月 8 日 Github&#xff1a;https://github.com/Renumics/rag-demo/blob/main/notebooks/visualize_rag_tutorial.ipynb 为探索Spotlight中的数据&#xff0c;我们使用Pa…

前端学习——vue学习

文章目录 1. < el-form> 属性 model、prop、rules2. v-bind 与 v-model3. v-if 与 v-show4. v-for 循环语句5. 计算属性 computed6. 监视属性 watch7. 下拉框 el-select、el-option8. 自定义事件9. async与await实现异步调用 1. < el-form> 属性 model、prop、rule…

[深度学习]yolov9+bytetrack+pyqt5实现目标追踪

【简介】 目标追踪简介 目标追踪是计算机视觉领域中的一个热门研究方向&#xff0c;它涉及到从视频序列中实时地、准确地跟踪目标对象的位置和运动轨迹。随着深度学习技术的快速发展&#xff0c;基于深度学习的目标追踪方法逐渐展现出强大的性能。其中&#xff0c;YOLOv9&…

STM32F103x 的时钟源

AHB (Advanced High-performance Bus) 高速总线&#xff0c;用来接高速外设的。 APB (Advanced Peripheral Bus) 低速总线&#xff0c;用来接低速外设的&#xff0c;包含APB1 和 APB2。 APB1&#xff1a;上面连接的是低速外设&#xff0c;包括电源接口、备份接口、 CAN 、 US…

【MySQL 探索之旅】初始MySQL数据库

&#x1f4da;博客主页&#xff1a;爱敲代码的小杨. ✨专栏&#xff1a;《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更新的动力❤️ &#x1f64f;小杨水平有…

three.js第一个3D案例

在正式学习Three.js之前&#xff0c;先做一些必要的准备工作&#xff0c;具体说就是下载threejs官方文件包&#xff0c;threejs官方文件包提供了很多有用的学习资源。 threejs官方文件包所有版本&#xff1a;https://github.com/mrdoob/three.js/releases threejs文件资源目录…

python递归算法

递归算法 一、嵌套调用的过程二、递归的基本原则1、递归的基本原则2、无限递归调用3、正常递归调用4、阶乘问题5、力扣&#xff1a;231. 2 的幂6、力扣面试题 08.05. 递归乘法7、力扣、326. 3 的幂8、力扣342. 4的幂 一、嵌套调用的过程 def show1():print("show 1 run s…

IDEA生成Java Doc帮助文档

使用场景 使用IDEA&#xff08;本次使用2020.3版&#xff09;将自己写的常用的工具类打成jar包&#xff0c;安装到maven本地仓库&#xff0c;最后生成对应的doc参考文档。 操作流程 方法一 选中项目 右键 show in Explor&#xff0c;如下图&#xff1a; 选中地址栏 cmd 输入…

C++基础知识(六:继承)

首先我们应该知道C的三大特性就是封装、继承和多态。 此篇文章将详细的讲解继承的作用和使用方法。 继承 一个类&#xff0c;继承另一个已有的类&#xff0c;创建的过程 父类(基类)派生出子类(派生类)的过程 继承提高了代码的复用性 【1】继承的格式 class 类名:父类名 {}; 【…

【Leetcode】2583. 二叉树中的第 K 大层和

文章目录 题目思路代码结果 题目 题目链接 给你一棵二叉树的根节点 root 和一个正整数 k 。 树中的 层和 是指 同一层 上节点值的总和。 返回树中第 k 大的层和&#xff08;不一定不同&#xff09;。如果树少于 k 层&#xff0c;则返回 -1 。 注意&#xff0c;如果两个节点与根…