Bootstrap

C语言:操作符详解1


在这里插入图片描述

一.操作符的分类

算术操作符:+-*/%
移位操作符:<<   >>
位操作符:&   |    ^
赋值操作符:=+=-=*=/=%=<<=>>=&=|=^=
单目操作符:!++--&*+-~sizeof、(类型)
关系操作符:>>=<<===!=
逻辑操作符:&&|| 
条件操作符:? :
逗号表达式:,
下标引用:[]
函数调用:()
结构成员访问:、. ->
上述的操作符,我们之前已经讲过算术操作符、赋值操作符、逻辑操作符、条件操作符和部分的单目操作符,今天继续介绍一部分,操作符中有一些操作符和二进制有关系,我们先铺垫一下二进制的和进制转换的知识。

二.二进制和进制转换

其实我们经常能听到 2进制、8进制、10进制、16进制 这样的讲法,那是什么意思呢?其实2进制、8进制、10进制、16进制是数值的不同表示形式而已。比如:数值15的各种进制的表示形式:

152进制:1111
158进制:17
1510进制:15
1516进制:F
16进制的数值之前写:0x
8进制的数值之前写:0

我们来写代码看一看:

在这里插入图片描述
我们重点介绍一下二进制:

首先我们还是得从10进制讲起,其实10进制是我们生活中经常使用的,我们已经形成了很多常识:

10进制中满101
10进制的数字每一位都是0~9的数字组成
其实二进制也是一样的
2进制中满21
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进制的数字每一位是07的,07的数字,各自写成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表示"负"。

正整数的原、反、补码都相同。
负整数的三种表示方法各不相同。

我们来画个图看一下:

在这里插入图片描述

我们来看个例子:

在这里插入图片描述

根据这个数字的正负直接写出的二进制序列叫它的原码。

来看相关概念:

原码:直接将数值按照正负数的形式翻译成二进制得到的就是原码。
反码:将原码的符号位不变,其他位依次按位取反就可以得到反码。
补码:反码+1就得到补码。

补码得到原码也是可以使用:取反,+1的操作。

我们把例子补全来看:

在这里插入图片描述

我们画图来看原码、反码、补码的转换关系:

在这里插入图片描述

例子:

在这里插入图片描述

对于整形来说:数据存放内存中其实存放的是补码
为什么呢?
在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同
时,加法和减法也可以统一处理(CPU只有加法器)此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。

我们直接画图来举例子

在这里插入图片描述


四.移位操作符

<< 和 >> 分别为左移操作符和右移操作符。注:移位操作符的操作数只能是整数。

1.左移操作符

移位规则:左边抛弃、右边补0。左移是移动的二进制序列。

来看例子:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

我们要知道这样的左移操作不会改变num本身的值,但是会将产生的效果赋给n,如果想要改变num可以这样写:num<<=1。

我们再来举例一个负数:

在这里插入图片描述

从上面例子观察到向左移动一位有乘2的效果,但是不是对所有数字都适用。

2.右移操作符

右移到底是算术右移,还是逻辑右移,是取决于编译器的,但是大部分编译器采用的都是算术右移。

移位规则:首先右移运算分两种:

1.逻辑右移左边用0填充,右边丢弃
2.算术右移:左边用原该值的符号位填充,右边丢弃

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

我们也来举一个负数的例子:

在这里插入图片描述

我们发现右移一位有除2的效果。

警告:对于移位运算符,**不要移动负数位,**这个是标准未定义的。
例如:

1  int num  = 10;
2  num >>-1;//error

五.位操作符

位操作符有:&(按位与) |(按位或) ^(按位异或) ~(按位取反)
注:它们的操作数必须是整数。

我们直接来上代码:

在这里插入图片描述

两个补码按位与运算的时候,对应的二进制位相与,有0则为0,两个同时为1才为1。这样可得上面结果。

在这里插入图片描述

这是按位或操作,两个补码对应的二进制位或运算,有1则为1,有两个0才为0。

在这里插入图片描述

这是按位异或运算,两个补码对应的二进制序列它的规则是:相同为0,相异为1。

我们再来看按位取反运算

在这里插入图片描述
规则就是:补码的二进制序列,为1变为0,为0的变为1;

记住:这些操作符都是拿二进制位进行计算的。

;