关于这一章节的东西,也是学编程的一个很基础的东西,每个语言也都会有,这里记录一些比较重要的知识点,好了进入正题:

运算符可以有如下几种分法:

运算符和表达式_优先级

运算符和表达式_位运算_02

下面对其一一进行学习:

算术运算符:

① ++--运算符前置和后置有很大区别

 运算符和表达式_位运算_03

 运行结果:

运算符和表达式_位运算_04

理解:

对于表达式,需知道它对应于一个唯一的值,而++i和i++都属于表达式,对于i++的值可以这样理解:


int tmp = i;
i = i+1;
return tmp;


而对于++i表达式的值,实际上就是改变的i的值:


i = i+1;
return i;


 ②类型转换:

  运算符的操作数属于不同的数据类型,运算时通常会将这些操作数转换为同一类型,由编译系统自动完成

  在赋值表达式中,自动将赋值运算符右边表达式的值的类型转换成左边变量的类型   级别高低:char->short->int->long->float->double->long double,由低级别的自动转化成高级别的类型。 下面用一个表达式的计算过程图能清晰的表达类型转换的意义:

运算符和表达式_优先级_05

③优先级:

运算符和表达式_位运算_06运算符和表达式_位运算_07

运行结果:

运算符和表达式_运算符_08

这个比较容易理解,而对于一元运算符的优先级呢?这里举一个例子:

*p++ 因为*、++是同级别的运算,所以这时按结合性来计算,而它属于一元,是按从右到左的顺序: 运算符和表达式_优先级_09  

所以: *p++ = *(p++) != (*p)++   赋值运算符: 赋值运算符的优先级低于算术运算符,仅高于逗号运算 运算符和表达式_优先级_10  

关系运算符: 在c语言中没有布尔类型,0表示假,1表示真:运算符和表达式_运算符_11  

逻辑运算符:

运算符和表达式_位运算_12  

下面来看两个例子:

运算符和表达式_位运算_13

说明: 1、++算术运算符比逻辑运算符||、&&优先级要高 2、&&优先级要与||高 3、由于||如果左边值为true,则会短路,所以++x=1,为逻辑真了,所以||右边的表达式就没有计算了。 运算符和表达式_优先级_14

说明: 1、(++x||++y)有短路,所以++y并没有计算, 2、&&如果左边为false,则也会短路,而由于上面表达式中为true,所以,++z会执行到。 位运算符: 将数字转换成二进制形式后再按位处理 运算符和表达式_运算符_15  

其中说明一下右移操作:

运算符和表达式_优先级_16运算符和表达式_运算符_17

运行结果:

运算符和表达式_优先级_18

以十六进制的形式输出:

运算符和表达式_位运算_19

运行结果:

运算符和表达式_位运算_20

为了让十六进制更加清晰,前面加一个ox前缀:

运算符和表达式_优先级_21

输出如下:

运算符和表达式_优先级_22

这时,将它往右移8位

运算符和表达式_运算符_23

运算符和表达式_运算符_23运算符和表达式_位运算_25

分析:

运算符和表达式_位运算_26

运算符和表达式_位运算_26 如果是有符号数,那又是怎么样的呢?

运算符和表达式_优先级_28

运算符和表达式_优先级_28运算符和表达式_位运算_30

C语言中的右移分为逻辑右移算术右移: 逻辑右移:高位补0(对于无符号数来说,>>是指逻辑右移) 算术右移:保留符号位不变(对于正数,高位补0;对于负数,高位补1) 实际上,C语言并没有规定有符号数的>>是逻辑右移还是算术右移,但是,几乎所有的编译器将有符号数的>>都实现成了算术右移了。   知道了上面的位运算,下面用一个实际例子,来将其运用一下:

运算符和表达式_优先级_31

运算符和表达式_优先级_31运算符和表达式_优先级_33

  运算符和表达式_运算符_34

运算符和表达式_运算符_34运算符和表达式_优先级_36

说明:x >> 8 & 0xFF,为什么还要与上0xFF,是为了有可能是算术右移,高位补1(虽说我们这个例子符号位是0),所以这样是为了保证将高八位全去掉】 下面举一些位运算的例子: 运算符和表达式_优先级_37

其中~10为什么是-11呢,原因如下: 运算符和表达式_位运算_38

运算符和表达式_位运算_38位运算符优先级:

运算符和表达式_优先级_40

运算符和表达式_优先级_40位运算示例【这个在实际当中都会用到的,争取要记住】:运算符和表达式_位运算_42

运算符和表达式_位运算_42运算符和表达式_位运算_44

运算符和表达式_位运算_44运算符和表达式_优先级_46   运算符和表达式_位运算_47 解析: 运算符和表达式_运算符_48

下面这两个位操作,是会经常用到的【重要】运算符和表达式_优先级_49


运算符和表达式_位运算_50

这个也是上面提到过的,下面我们来论证一下该等式:

运算符和表达式_优先级_51

上面这是求一个正数的取反操作,那如果对一个负数进行取反,该等式也成立么,先用代码看下结果:

运算符和表达式_运算符_52

运算符和表达式_位运算_53


下面关于运算符的优化级进行一个总结:

运算符和表达式_位运算_54 

运算符和表达式_位运算_55 

下面对所有运算符的优化级进行一个总结,以便之后对优化级有疑惑时来进行查找:

运算符和表达式_运算符_56

运算符和表达式_位运算_57

运算符和表达式_运算符_58

以一个范例来说明一下优先级:

运算符和表达式_优先级_59


修改优先级:运算符和表达式_运算符_60

 下面来使用一下三目及逗号运算符:

运算符和表达式_优先级_61

编译运行:

运算符和表达式_运算符_62

注意:printf("%d\n",1,2,3);并非是逗号表达式,而是函数的参数传递】

常见的一些优先级错误:运算符和表达式_位运算_63 

建议:关于表达式的优级,只要把握“算术运算符优先级高于关系运算符高于逻辑运算符高于赋值运算符"原则,并记住上面经常范的错误,就能搞定它了!】