新手入门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 = 5b = a - b;	//b = 3 a = 8a = a - b;	//a = 5 a = 3printf("%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 = aa = a ^ b;		// a ^ b ^ a = bprintf("%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博客

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

为什么需要MDL锁

点击上方蓝字关注我 在数据库管理中&#xff0c;元数据&#xff08;metadata&#xff09;的保护至关重要&#xff0c;而MySQL中的"元数据锁"&#xff08;MDL锁&#xff09;就是它的守护者。 1. 什么是MDL锁MDL锁&#xff0c;全名Metadata Lock&#xff0c;是MySQL中…

WordPress使用

WordPress功能菜单 仪表盘 可以查看网站基本信息和内容。 文章 用来管理文章内容&#xff0c;分类以及标签。编辑文章以及设置分类标签&#xff0c;分类和标签可以被添加到 外观-菜单 中。 分类名称自定义&#xff1b;别名为网页url链接中的一部分&#xff0c;最好别设置为中文…

为M系Mac安装Centos

下载镜像 需要使用特殊镜像&#xff0c;官网或国内的arch 镜像源不可安装 https://share.weiyun.com/2qc0S2VV CentOS-7-aarch64-08191738.mpg https://www.aliyundrive.com/s/1DCW2E5EySR 原文链接&#xff1a;https://blog.csdn.net/acdemic964850/article/details/1290565…

docker部署grafana+zabbix监控

1. grafana介绍 Grafana 是一个开源的数据可视化工具&#xff0c;它可以帮助用户将数据源中的数据进行图形化展示和实时监控&#xff0c;以便于用户能够更加直观地理解数据。Grafana 支持多种数据源&#xff0c;包括 Graphite、Elasticsearch、InfluxDB、Prometheus 等&#x…

【鸿蒙 HarmonyOS 4.0】开发工具安装

一、准备开发环境 1.1、安装IDE 鸿蒙应用开发需要使用配套的IDE——HUAWEI DevEco Studio。 DevEco Studio基于IntelliJ IDEA Community&#xff08;IDEA社区版&#xff09;构建&#xff0c;为鸿蒙应用提供了一站式开发环境&#xff0c;集成了开发、运行、调试以及发布应用的…

企微hook框架

https://wwm.lanzoum.com/ipUTp1ot1twh 密码:hvev 免费的企微框架 支持文本消息&#xff0c;图片消息&#xff0c;视频消息&#xff0c;文件消息。 其他可自行下载测试。 有兴趣可以进群交流。720192224 BOOL WxWorkSendData(string data) { WX_GETOBJDATA ob…

数据库专题——分库分表

一. 分库分表介绍二. 分库分表实践 一. 分库分表介绍 1.1 分库分表解决了什么问题 先说分库&#xff1a; 《高性能MySQL》中提到了两种数据库扩展方式&#xff1a;垂直扩展和水平扩展。前者意味着买更多性能强悍的硬件&#xff0c;但是总会达到扩展的天花板&#xff0c;且成本…

软件测试需要学习什么?好就业吗?

目前来说的话&#xff0c;整个it 都不太好&#xff01;但是既然你问了&#xff0c;我也就告诉你吧&#xff01; 1功能测试 &#xff1a;前端和后端&#xff0c;前端就是简单的页面&#xff0c;你需要考虑的是&#xff1a;必填项&#xff0c;边界值&#xff0c;组合&#xff0c…

WebRTC最新版报错解决:city.wav:missing and no known rule to make it (二十六)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒体系统工程师系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只…

学习 python的第四天,顺便分享两首歌:we don‘ talk anymore,You ‘re Still The One

诸君晚上好&#xff0c;现在是&#x1f303;晚上&#xff0c;今天是学习python的第四个学习日&#xff0c;不知不觉学了四天了&#xff0c;还是那句话&#xff1a;不积跬步无以至千里、不积小流无以成江海&#xff01; 暂时回顾下前面的学习日吧&#xff1a; 第一个学习日----…

Spring Boot打war包部署到Tomcat,访问页面404 !!!

水善利万物而不争&#xff0c;处众人之所恶&#xff0c;故几于道&#x1f4a6; 文章目录 Spring Boot打war包部署到Tomcat&#xff0c;访问页面404 &#xff01;&#xff01;&#xff01;解决办法&#xff1a;检查Tomcat版本和Jdk的对应关系&#xff0c;我的Tomcat是6.x&#x…

Web前端3D JS框架和库 整理

在WebGL库和SVG/Canvas元素的支持下&#xff0c;JavaScript变得惊人的强大。几乎可以为网络构建任何东西&#xff0c;包括基于浏览器的游戏和本地应用&#xff0c;许多最新的突破性功能都在3D上运行。 为此&#xff0c;「数维图小编」整理了19个交互式3D Javascript库和框架&am…