C语言(长期更新)第9讲:操作符详解(一)
C语言(长期更新)
第9讲:操作符详解(一)
跟着潼心走,轻松拿捏C语言,困惑通通走,一去不回头~欢迎开始今天的学习内容,你的支持就是博主最大的动力。博主主页:潼心1412o-CSDN博客
目录
C语言(长期更新)
第9讲:操作符详解(一)
知识回顾
前言
9.1 分类
9.2 进制转换
9.1.1 简介
9.1.2 十进制与其他进制的换算
9.1.3 二进制转8、16进制
9.3 原码、反码、补码
9.4 移位操作符
9.4.1 左移 <<
9.4.2 右移 >>
9.5 按位操作符
9.5.1 基本介绍
9.5.2 异或的特殊用法
9.5.3 练习1:统计补码中1个数
9.5.4 练习2:⼆进制位置0或者置1
9.6 单目操作符
9.7 逗号表达式
9.8 下标访问符[ ]
9.9 函数调用符 ()
知识回顾
上节课我们学习了函数递归的内容,今天我们来补充学习操作符详解的知识,坐稳了,我们发车,gogogo,出发喽!
前言
我们在先前的学习中,已经对操作符有了简单的认识。今天我们会不仅对已经学过的双目操作符等进行更加系统,全面的学习,还会学习补充一些新的操作符。对这些知识的深入掌握会帮助我们更加灵活地使用它们,从而更好地书写代码。
9.1 分类
- 算术操作符 + - * / %
- 移位操作符 << >>
- 位操作符 & | ^
- 赋值操作符 = += -= *= /= %= <<= >>= &= |= ^=
- 单目操作符 !
- 关系操作符 > < ==
- 逻辑操作符 && ||
- 条件操作符 ? :
- 逗号表达式 ,
- 下标引用符 [ ]
- 函数调用符 ()
- 结构成员访问 . 、->
9.2 进制转换
因为移位操作和位操作符都只针对二进制,并且除了在这方面知识会有涉及外,在计算机领域的方方面面都会对进制的转换有所要求,所以我们先学习这方面的内容。
9.1.1 简介
我们常常听到2进制 8进制 10进制 16进制的说法,其实他们只是数值不同的表示形式
比如说15
2进制 1111
8进制 17
10进制 15
16进制 F
- 2进制:逢2进1 由0和1组成
- 8进制:逢8进1 由0到7组成
- 16进制:满16进1 由0到9,a到f(代替10到15)组成
这就涉及到一个问题了——若给你一个17,你怎么知道是10进制的17还是8进制的15?给你一个F,你又怎知是字符还是16进制的15?
8进制中 常常前缀0
16进制中 常常前缀0x
9.1.2 十进制与其他进制的换算
我们惯用10进制衡量数字的大小,若想将其他进制转化为10进制,最好的方法就是用各位的权重进行换算。
以此类推,8进制,16进制也是这样。
10进制转2进制,我们常用的方法是除余法
以此类推,10进制转换成8进制,16进制也同样适用。
9.1.3 二进制转8、16进制
8进制可能出现的最大数字7刚好比2的3次方8小1,二进制为111,也就是说,8进制的一位数字最高也就只会用2进制的3位表示。所以我们在换算时,就可以从右往左将2进制序列每3位进行划分,换为对应的8进制数字。剩下不够3位的直接化为8进制
同理16进制最大数15 二进制位1111,那就每4位化成16进制就好了
9.3 原码、反码、补码
数据的表示和存储都是以2进制的方式进行的
- 整型的2进制:原码反码补码
- 浮点数的2进制:先不学哈哈
在有符号整数中,在二进制序列最高的1位会被当做符号位,其余的31个比特位是数字位,用于数值的存放。(整型是4个字节,每个字节8个bit位,共计32个bit位)
1为负,0为非负
原反补具体的使用方法可能会有一点点抽象,下面看一个具体例子就懂了
整数在内存中存储使用补码
CPU在计算机也是使用补码进行计算的
然而,打印时或者人使用时却使用的是原码
为社么整型在内存存储时非要使用补码呢?
原因有三
其一符号位和数值位可以统一处理
其二加法减法可以统一处理(CPU只有加法器)
此外,原码和补码之间的转换相同 不需要额外的硬件来完成
如上图同样是1-1的计算,使用原码计算错误,补码就可以进行不同符号的加法计算(1因位数不够被挤出去了)
有了二进制基础知识的学习,我们就可以学习移位操作符和位操作符这两个只能用二进制的东西了
9.4 移位操作符
9.4.1 左移 <<
移位规则:逐位左移,左位抛弃,右位补零
我们发现左移后得到的数会使原数乘2倍
9.4.2 右移 >>
移位规则:
- 逻辑右移:逐位右移,右位抛弃,左位补零
- 算术右移:逐位右移,右位抛弃,左位补原先符号位
C语言标准没有给出明确的规定右移到底是采用算术右移,还是逻辑右移
这个是取决于编译器的实现的
9.5 按位操作符
9.5.1 基本介绍
1. & 按位与
操作符使用规则和逻辑与(&&)大致相同,但按位判断,全1为1,有0为0
2. | 按位或
操作符使用规则和逻辑或(||)大致相同,但按位判断,有1为1,全0位为0
3. ^ 按位异或 按位判断,相同为0,不同为1
4. ~ 按位取反
##注:他们的操作数只能是整数
9.5.2 异或的特殊用法
一道变态面试题
在不创建第三个变量的情况下,交换两个数字的值
异或 相同为0,相异为1
a^a=0
a^0=a
异或是支持交换律的
a^b^a=b
a^a^b=b
a出现两次,异或为0,0和b异或还为0
由此,我们可以根据^的特性,实现“找出单身狗”
比如说在一堆数中只有一个数出现1次,其他均出现2次
要找到这个数,只需把它们全部异或在一起,单身狗就会自认出现
9.5.3 练习1:统计补码中1个数
编写代码实现:求⼀个整数存储在内存中的⼆进制中1的个数(就是补码中1个数)
·方法1
我们立即想到只要获得每一位,并判断是不是1,统计1的个数就行
10进制我们写过类似的代码先%10获得末尾的数判断,再/10得到前面1位,循环直至全部统计完
2进制也是类似的,先%2,再/2理论上复制如上方法即可完成运算任务
但是我们输入-1就发现出问题了
有没有什么方法负数也同样适用呢?
·方法2
num&1==1 末尾为1
num&1==0 末尾为0
如何使每一位成为末尾呢?很简单,右移
num>>=1
·方法3
再介绍一个有趣的现象
n&(n-1) 每次去掉最后1个1
这就又给我们提供了一个新的解题思路
##拓展
判断一个数是不是2的次方数
法1:计算n的二进制中1的个数是不是1
法2:看看n&(n-1)==1否
9.5.4 练习2:⼆进制位置0或者置1
编写代码将13⼆进制序列的第5位修改为1,然后再改回0
具体代码是如何实现的呢?
9.6 单目操作符
! ++ -- & * + - ~ sizeof (类型)——强制类型转换操作符
大多数我们在先前的学习中已有涉及,&取地址符和*会在后续指针的内容中进行详细讲解
特别需要强调的一点就是sizeof后面的括号里要是放有表达式,表达式不参与运算
我们知道一个.c文件必须经过编译、链接才能生成可执行的.exe文件
而sizeof括号里的内容在编译时就已经成为a对应的short类型长度2了,在可执行文件运行时就不会运行。假设将括号里的内容拿出来,单独成为一句语句,就不会进行编译,会在可执行文件中保存下来,正常运行。
9.7 逗号表达式
如其名,逗号表达式就是用,连接的语句,逗号表达式在运行时每个语句都会按序执行,最终结果为最后一个语句的结果
除此之外,也可以有这样的应用
9.8 下标访问符[ ]
比如说arr[5](注意此处不是数组定义时,只指代数组的第六个元素)
[ ] 下标访问符有两个操作数,分别是arr和5
9.9 函数调用符 ()
函数调用符比如说printf(“abcde\n”);操作数就有两个,分别是函数名printf和打印内容字符串"abcde"。那么函数调用操作符最少有几个操作数呢?当然是1个了。因为我们先前讲过函数可以不含参数。
好了今天的学习内容就到这里啦,谢谢你的陪伴,我是潼心,下次再见~如果这篇文章对你有帮助的话。请务必给主播一个一键三连,球球了,这对主播很重要~
博主主页:潼心1412o-CSDN博客