C语言(操作符)1

                     Hi~!这里是奋斗的小羊,很荣幸各位能阅读我的文章,诚请评论指点,关注+收藏,欢迎欢迎~~     

                        💥个人主页:小羊在奋斗

                        💥所属专栏:C语言   

        本系列文章为个人学习笔记,在这里撰写成文一为巩固知识,二为同样是初学者的学友展示一些我的学习过程及心得。文笔、排版拙劣,望见谅。 

                                1、操作符的分类

                                2、原码、反码、补码

                                3、移位操作符

                                4、位操作符

                                5、逗号操作符

1、操作符的分类

        (1)算术操作符:+、-、*、/、%

        (2)移位操作符:<<、>>

        (3)位操作符:&、|、^、~

        (4)赋值操作符:=、+=、-=、*=、/=、%=、<<=、>>=、&=、|=、^=

        (5)单目操作符:!、++、--、&、*、+、-、~、sizeof、(类型)

        (6)关系操作符:>、>=、<、<=、==、!=

        (7)逻辑操作符:&&、||

        (8)条件操作符:?:

        (9)逗号表达式:,

        (10)下标引用:[ ]

        (11)函数调用:()

        (12)结构体成员访问:. 、->

2、原码、反码、补码

        整数的二进制表示方法有三种,即原码、反码和补码,有符号整数的三种表示方法均由符号位数值位组成,二进制序列中,最高位的1位是符号位,后面的都是数值位。符号位0表示正,1表示负

        正整数和无符号整数的原码、反码和补码都相同,负整数的三种表示方法各有不同。

        原码:直接将数值按照正负数的形式翻译成二进制得到的就是原码;

        反码:将原码的符号位不变,数值位按位取反就是反码;

        补码:反码+1得到补码。

        原码转换补码、补码转换原码都是取反+1

        对整型来说,数据在内存中存放的是补码。为什么呢?

        在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码可以将符号位和数值位统一处理。同时,加法和减法也可以统一处理,因为CPU只有加法器。此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。

        比如,我们计算1-1,因为CPU只有加法器,所以我们用1+(-1)的形式计算:

3、移位操作符

        (1)移动的是存储在内存中二进制位(补码);

        (2)移位操作符的操作数只能是整数;

       3.1 左移操作符:<<        

        移位规则:左边抛弃,右边补0 

        将10左移一位:

        将-5左移一位:

 

        规律:左移一位有乘2的效果;同样的,左移n位等于乘以2的n次方

        3.2 右移操作符:>>

        移位规则:(1)逻辑右移:左边补0;右边丢弃

                          (2)算术右移:左边补原该值的符号位,右边丢弃

        逻辑右移或算术右移是取决于编译器的,通常采用的都是算术右移

        将10右移一位: 

        

将-4右移一位:

        规律:右移一位有除2的效果,同样的,右移n位等于除以2的n次方。 

         注意:对于移位操作符,不要移动负数位,这个是未定义的。

4、位操作符

        注意:它们的操作数也必须都是整数。

        &:按位与(有0则为0

        因为3与-6的结果为正数,补码和原码相同,所以这里直接用了补码计算。

        |:按位或(有1则为1) 

        

        ^:按位异或(相同为0,相异为1) 

         ~:按位取反(单目操作符

例题1: 不能创建临时变量,实现两个整数的交换

        方法一:要实现两个整数的交换,我们首先会想到创建一个临时变量来解决。

        这无疑是一个最简单高效的方法。但题目明确说明了不能创建临时变量,那我们就要另想办法了。 

        方法二:既然不能创建临时变量,那我们只能对这两个数本身下手了。

        大家觉得上面这个办法怎么样?我们按照题目要求完成了任务。

        但是,这个办法是受限的。如果两个整数太大的话相加会溢出,那有没有完美的办法呢?

既然这样问,那答案肯定是有的,办法就在我们上面新学到的知识中。

        方法三:使用异或操作符

        不知道你第一次看到这个代码的时候有没有懵逼呢?反正我是挺惊讶的。那接下来我们就来分析上面的代码具体是怎么实现的。

         首先我们知道,按位异或操作符的规则是:相同为0,想异为1。因为4^4=0,所以a^a=0;因为4^0=4,所以a^0=a;因为4^4^5=5,经过计算4^5^4=5,所以异或操作符是支持交换律的。

        因为异或操作符不存在进位,所以不会发生溢出。 需要说明的是,这只是我们为了加深对异或操作符的理解而想出的一个题目,未来我们交换两个整数还是用创建临时变量的方法更好,可读性高,效率高。

 例题2:编写代码求一个整数存储在内存中的二进制中1的个数

        方法一:我们可以想办法拿到二进制的每一位,然后统计1的个数。

        说起拿到二进制的每一位,就想到了我们之前的一个例题,其中有拿到十进制数的每一位的方法,通过模10除10即可;同样的,我们也可以通过模2除2来得到二进制数的每一位。

        10的二进制表示为1010,有2个1。 看似我们完成了要求,但当我们输入负数的时候,结果却是错的。原因在于形参是有符号的整型,负数取模的结果不会为1,很显然这个方法对负数不起作用。我们把形参定义为无符号的整型,当负数传过来的时候,我们把它当做无符号的整型看待,因为无符号整型的原码、反码、补码都相同,这时候就把这个无符号整形看作一个正数,从而解决问题。

        方法二:对整数二进制的最低位与1再向右移位,循环执行。这个方法不用关心是不是有符号无符号数的问题。

        我们利用按位与的特点,如果二进制最低位是1,按位与1得到1;如果二进制最低位是0,按位与1得到0;再循环执行,我们就能得到二进制中1的个数。

        这个方法也是可行的, 但它还不是最优的。

        方法三:其实有一个专门用来计算一个数的二进制表示中有多少个1的算法:n &= (n - 1)

         这个算法牛逼的地方在于,n &= (n - 1) 这个式子执行一次,二进制表示的数就会少一个1,执行多少次,就有多少个1;也就是说输入的数有几个1就执行几次,效率很高

        这种算法除非见过,一般人还真想不出来,不过我们记住就行,不必太执着其中的原理。

例题3:判断一个数是不是2的次方数

        2的次方数,有没有什么特点呢?通过上面我们了解了二进制,很容易就能想到,2的次方数二进制表示中只有一个1,那我们利用上面方法三中的代码判断结果是不是1就行了。虽然能解决问题,但是这个方法有点啰嗦。

        我们知道2的次方数二进制表示中只有一个1,而 n &= (n - 1) 这个式子执行一次,二进制表示的数就会少一个1,那如果 n &= (n - 1) 等于0的话,不就说明 n 是2的次方数吗?

 例题4:二进制位置0或置1

              编写代码将11二进制表示的第五位修改为1,然后再改回0。

        11的二进制表示:00000000000000000000000000001011

        修改第五位为1:  00000000000000000000000000011011

        再将第五位改回:00000000000000000000000000001011

        只改第五位,其他位不能改变要怎么实现呢?这就要用到我们学过的按位或(|)操作符了,我们知道,按位或操作符的规则是有1则为1,那我们给11的二进制按位或00000000000000000000000000010000就可以实现只修改第五位而其他位不变的效果,而这个数我们只需要给1向左移4位就能得到。

        那再将第五位修改回来,方法应该也跟上面差不多。这里就要用到按位与(&)操作符,我们知道按位与操作符的规则是有0则为0,那我们给修改过的数按位与上11111111111111111111111111101111就可以实现只修改第五位而保持其他位不变的效果,而这个数我们只需要给1向左移4位再按位取反就能得到。

        通过上面几个例题,我们可以深刻体会到操作符背后强大的功能,而这些作用我们在没有深入学习之前可能根本想象不到。 操作符的作用是很大的,尤其是在嵌入式中,使用操作符来实现一些功能及其频繁。

 5、逗号表达式

        逗号表达式,就是用逗号隔开的多个表达式。逗号表达式从左向右依次执行,整个表达式的结果是最后一个表达式的结果。

        注意:千万不要想当然的以为整个表达式的结果是最后一个表达式的结果就直接去算最后一个表达式,一定要从左到右每个表达式都执行。 

        另外,逗号表达式还有一个神奇的用法,来看示例:

        这两个代码的效果是一样的,第二种运用了逗号表达式从左向右依次执行的特点,使代码更简单一些。 

                                         点击跳转主页—> 💥个人主页小羊在奋斗

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

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

相关文章

【JavaWeb】Day62.SpringBootWeb案例——基础登录功能

登录功能 需求 在登录界面中&#xff0c;我们可以输入用户的用户名以及密码&#xff0c;然后点击 "登录" 按钮就要请求服务器&#xff0c;服务端判断用户输入的用户名或者密码是否正确。如果正确&#xff0c;则返回成功结果&#xff0c;前端跳转至系统首页面。 接…

Python数据分析系列(一):python入门

文章目录 前言一、Python运行方式二、Python集成开发环境(IDE)三、Python开发平台—Anaconda1、下载2、安装3、使用3.1 Anaconda应用介绍3.2 配置Python库3.3 集成开发环境使用3.3.1.Spyder3.3.2 Jupyter Notebook四、Python入门概念1、入门函数:print()与input()2、python书写…

SAP PP学习笔记08 - 作业区(工作中心Work Center),作业区Customize

上一章讲了作业手顺&#xff08;工艺路线Routing&#xff09;。 SAP PP学习笔记07 - 作业手顺&#xff08;工艺路线Routing&#xff09;-CSDN博客 这一章来讲讲作业区&#xff08;工作中心 Work Center&#xff09;。 1&#xff0c;作业区&#xff08;工作中心&#xff09;中…

挑战一周完成Vue3项目Day3: 品牌管理+平台属性管理+SPU管理+SKU管理

一、真实接口替换mock接口 &#xff08;1&#xff09;替换各个环境下的服务器地址&#xff08; .env.development、.env.production、.env.test &#xff09; VITE_SERVE"http://sph-api.atguigu.cn" &#xff08;2&#xff09; 配饰代理跨域&#xff1a;vite.con…

如何测试响应式网站

我们每天通过多种设备访问互联网。移动电话&#xff0c;台式机/笔记本电脑&#xff0c;平板电脑&#xff0c;平板电脑…我们所掌握的设备数量已经增长为天文数字。作为消费者&#xff0c;体验很棒。我们可以随时随地在任何设备上自由访问互联网。但对于Web开发人员&#xff0c;…

磁盘格式化文件恢复:一文看懂数据恢复操作

当你意识到关键的硬盘已经被格式化&#xff0c;而且你不能获取里面的内容时&#xff0c;这会是非常令人沮丧的。这种情况可能是因为硬盘被不小心格式化&#xff0c;或者是你在试图修正一些问题、调整文件系统或者释放存储空间时&#xff0c;有意进行的格式化。无论具体情况是什…

Go 语言变量

变量来源于数学&#xff0c;是计算机语言中能储存计算结果或能表示值抽象概念。 变量可以通过变量名访问。 Go 语言变量名由字母、数字、下划线组成&#xff0c;其中首个字符不能为数字。 声明变量的一般形式是使用 var 关键字&#xff1a; var identifier type 可以一次声…

线程基础知识

进程是资源分配的最小单位&#xff0c;线程是程序执行的最小单位… 为什么使用线程 多线程之间会共享同一块地址空间和所有可用数据的能力&#xff0c;这是进程所不具备的线程要比进程更轻量级 &#xff0c;由于线程更轻&#xff0c;所以它比进程(fork创建进程以执行新的任务…

Postgresql 从小白到高手 十一 :数据迁移ETL方案

文章目录 Postgresql 数据迁移ETL方案1、Pg 同类型数据库2 、Pg 和 不同数据库 Postgresql 数据迁移ETL方案 1、Pg 同类型数据库 备份 : pg_dump -U username -d dbname -f backup.sql插入数据&#xff1a; psql -U username -d dbname -f backup.sqlpg_restore -U username…

远程桌面连接服务器怎样连接不上的六个常见原因

远程桌面连接服务器无法连接的问题可能由多种原因引起。以下是一些常见的问题及其解决方案&#xff1a; 1. 网络连接问题&#xff1a;远程桌面连接的基础是稳定的网络连接。如果网络连接不稳定或中断&#xff0c;那么你将无法连接到远程桌面。检查你的网络连接&#xff0c;确保…

Codigger数据篇(中):数据可控性的灵活配置

在数据服务领域中&#xff0c;数据可控性无疑是至关重要的一环。数据可控性不仅关乎数据的安全性和隐私性&#xff0c;更直接影响到数据价值的实现。Codigger&#xff0c;在其数据可控性方面的灵活配置&#xff0c;为用户提供了更加便捷、高效的数据管理体验。 一、自主选择数…

Spring6 当中 Bean 的生命周期的详细解析:有五步,有七步,有十步

1. Spring6 当中 Bean 的生命周期的详细解析&#xff1a;有五步&#xff0c;有七步&#xff0c;有十步 文章目录 1. Spring6 当中 Bean 的生命周期的详细解析&#xff1a;有五步&#xff0c;有七步&#xff0c;有十步每博一文案1.1 什么是 Bean 的生命周期1.2 Bean 的生命周期 …

ThinkPHP Lang多语言本地文件包含漏洞(QVD-2022-46174)漏洞复现

1 漏洞描述 ThinkPHP是一个在中国使用较多的PHP框架。在其6.0.13版本及以前&#xff0c;存在一处本地文件包含漏洞。当ThinkPHP开启了多语言功能时&#xff0c;攻击者可以通过lang参数和目录穿越实现文件包含&#xff0c;当存在其他扩展模块如 pear 扩展时&#xff0c;攻击者可…

esp32学习

开启自动补全功能 Arduino IDE 2.0开启代码补全及修改中文_arduino ide怎么设置中文-CSDN博客 PWM 、 ADC转换 在使用这个adc默认配置的时候adc引脚的输入电压必须是介于0-1之间&#xff0c;如何高于1v的电压都会视为一个最高值&#xff0c;如果要增加测量电压你就需要配置一…

【JAVA】part5-Java集合

Java 集合 Java集合概述 Java数组的局限性 数组初始化后大小不可变&#xff1b;数组只能按索引顺序存取。 Java的java.util包主要提供了以下三种类型的集合&#xff1a; List&#xff1a;一种有序列表的集合&#xff0c;例如&#xff0c;按索引排列的Student的List&#xff1b…

车载气象站:可移动监测的气象站

TH-CZ5车载气象站是一种专门针对车辆、船舶等应急环境检测设备而设计的可移动监测的气象站。 一、系统介绍 车载气象站系统采用先进的高精度GPS及三轴电子罗盘&#xff0c;可实现车行驶时的风速、风向检测。整机为野外型设计&#xff0c;同时还可对气温、相对湿度、雨量、气压…

Linux修改文件权限命令 chmod

【例子引入】 以下面命令为例&#xff1a; chmod 777 Random.py 当写入下面名为Random.py的代码后&#xff1a; 如果直接运行&#xff0c;会显示权限不够 当输入 chmod 777 Random.py 更改权限后&#xff0c;才能够正常运行 在终端中输入 这条命令是关于Linux或Unix-like系…

FlaUI

FlaUI是一个基于微软UIAutomation技术&#xff08;简称UIA&#xff09;的.NET库&#xff0c;它主要用于对Windows应用程序&#xff08;如Win32、WinForms、WPF、Store Apps等&#xff09;进行自动化UI测试。FlaUI的前身是TestStack.White&#xff0c;由Roemer开发&#xff0c;旨…

Socket编程--TCP连接以及并发处理

流程图 网络传输流程&#xff1a; TCP连接&#xff1a; api 客户端&#xff1a; socket: 创建套接字 domain: AF_INET &#xff1a;IPv4 type: SOCK_STREAM(tcp)、SOCK_DGRAM&#xff08;udp&#xff09; protocol: 0 默认协议 返回值&#xff1a;成功返回一个新的套接字…

Linux-进程间通信(进程间通信介绍、匿名管道原理及代码使用、命名管道原理及代码使用)

一、进程通信介绍 1.1进程间通信的目的 数据传输&#xff1a;一个进程需要将它的数据发送给另一个进程资源共享&#xff1a;多个进程之间共享同样的资源。通知事件&#xff1a;一个进程需要向另一个或一组进程发送消息&#xff0c;通知它&#xff08;它们&#xff09;发生了某…
最新文章