一.操作符的分类
c
算术操作符:+、-、* 、 /、%
移位操作符:<< >>
位操作符:& | ^
赋值操作符:= 、+=、-=、*=、/=、%=、<<=、>>=、&=、|=、^=
单目操作符:!、++、--、&、*、+、-、~、sizeof、(类型)
关系操作符:>、>=、<、<= 、== 、!=
逻辑操作符:&&、||
条件操作符:? :
逗号表达式:,
下标引用:[]
函数调用:()
结构成员访问:、. ->
上述的操作符,我们之前已经讲过算术操作符、赋值操作符、逻辑操作符、条件操作符和部分的单目操作符,今天继续介绍一部分,操作符中有一些操作符和二进制有关系,我们先铺垫一下二进制的和进制转换的知识。
二.二进制和进制转换
其实我们经常能听到 2进制、8进制、10进制、16进制 这样的讲法,那是什么意思呢?其实2进制、8进制、10进制、16进制是数值的不同表示形式而已。比如:数值15的各种进制的表示形式:
c
15的2进制:1111
15的8进制:17
15的10进制:15
15的16进制:F
16进制的数值之前写:0x
8进制的数值之前写:0
我们来写代码看一看:
我们重点介绍一下二进制:
首先我们还是得从10进制讲起,其实10进制是我们生活中经常使用的,我们已经形成了很多常识:
c
10进制中满10进1
10进制的数字每一位都是0~9的数字组成
其实二进制也是一样的
2进制中满2进1
2进制的数字每一位都是0~1的数字组成
那么 1101就是二进制的数字了。
1.二进制转10进制
其实10进制的123表示的值是一百二十三,为什么是这个值呢?其实10进制的每一位是有权重的,10进制的数字从右向左是个位、十位、百位......,分别每一位的权重是10,101,102...
如下图:
2进制和10进制是类似的,只不过2进制的每一位的权重,从右向左是:2,21,22...
T如果是2进制的1101,该怎么理解呢?
2.10进制转2进制数字
数字大的可以这样算,数字小的没必要,比如我们可以这样算:
3.二进制转8进制和16进制
二进制转8进制
8进制的数字每一位是0~7的,0~7的数字,各自写成2进制,最多有3个2进制位就足够了,比如7的二进制是111,所以在2进制转8进制数的时候,从2进制序列中右边低位开始向左每3个2进制位会换算一个8进制位,剩余不够3个2进制位的直接换算。
2.2 2进制转8进制和16进制
如:2进制的01101011,换成8进制:0153,0开头的数字,会被当做8进制。
二进制转16进制
16进制的数字每一位是0~9, a~f 的,0~9, a~f的数字,各自写成2进制,最多有4个2进制位就足够了,比如f的二进制是1111,所以在2进制转16进制数的时候,从2进制序列中右边低位开始向左每4个2进制位会换算一个16进制位,剩余不够4个二进制位的直接换算。
如:2进制的01101011,换成16进制:0x6b,16进制表示的时候前面加0x。
三.原码、反码、补码
整数的2进制表示方法有三种,即原码、反码和补码 。有符号整数的三种表示方法均有符号位和数值位 两部分,2进制序列中,最高位的1位是被当做符号位 剩余的都是数值位。符号位都是用0表示"正",用1表示"负"。
c
正整数的原、反、补码都相同。
负整数的三种表示方法各不相同。
我们来画个图看一下:
我们来看个例子:
根据这个数字的正负直接写出的二进制序列叫它的原码。
来看相关概念:
c
原码:直接将数值按照正负数的形式翻译成二进制得到的就是原码。
反码:将原码的符号位不变,其他位依次按位取反就可以得到反码。
补码:反码+1就得到补码。
补码得到原码也是可以使用:取反,+1的操作。
我们把例子补全来看:
我们画图来看原码、反码、补码的转换关系:
例子:
对于整形来说:数据存放内存中其实存放的是补码 。
为什么呢?
在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同
时,加法和减法也可以统一处理(CPU只有加法器)此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。
我们直接画图来举例子
四.移位操作符
<< 和 >> 分别为左移操作符和右移操作符。注:移位操作符的操作数只能是整数。
1.左移操作符
移位规则:左边抛弃、右边补0。左移是移动的二进制序列。
来看例子:
我们要知道这样的左移操作不会改变num本身的值,但是会将产生的效果赋给n,如果想要改变num可以这样写:num<<=1。
我们再来举例一个负数:
从上面例子观察到向左移动一位有乘2的效果,但是不是对所有数字都适用。
2.右移操作符
右移到底是算术右移,还是逻辑右移,是取决于编译器的 ,但是大部分编译器采用的都是算术右移。
移位规则:首先右移运算分两种:
c
1.逻辑右移左边用0填充,右边丢弃
2.算术右移:左边用原该值的符号位填充,右边丢弃
我们也来举一个负数的例子:
我们发现右移一位有除2的效果。
警告:对于移位运算符,**不要移动负数位,**这个是标准未定义的。
例如:
c
1 int num = 10;
2 num >>-1;//error
五.位操作符
位操作符有:&(按位与) |(按位或) ^(按位异或) ~(按位取反)
注:它们的操作数必须是整数。
我们直接来上代码:
两个补码按位与运算的时候,对应的二进制位相与,有0则为0,两个同时为1才为1。这样可得上面结果。
这是按位或操作,两个补码对应的二进制位或运算,有1则为1,有两个0才为0。
这是按位异或运算,两个补码对应的二进制序列它的规则是:相同为0,相异为1。
我们再来看按位取反运算
规则就是:补码的二进制序列,为1变为0,为0的变为1;
记住:这些操作符都是拿二进制位进行计算的。