关于这一章节的东西,也是学编程的一个很基础的东西,每个语言也都会有,这里记录一些比较重要的知识点,好了进入正题:
运算符可以有如下几种分法:
![](https://i-blog.csdnimg.cn/blog_migrate/8317e42cde2e388a1f7e803265f938d6.png)
![](https://i-blog.csdnimg.cn/blog_migrate/c3f9b2b37d93032c63da024ae2f503cf.png)
下面对其一一进行学习:
算术运算符:
①
++
和--
运算符前置和后置有很大区别
![](https://i-blog.csdnimg.cn/blog_migrate/2353cf990a26667e666810993b1f92be.png)
运行结果:
![](https://i-blog.csdnimg.cn/blog_migrate/5ee18e1f7593d51475b639853ad1ff1e.png)
理解:
对于表达式,需知道它对应于一个唯一的值,而++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,由
低级别的自动转化成高级别的类型。
下面用一个表达式的计算过程图能清晰的表达类型转换的意义:
![](https://i-blog.csdnimg.cn/blog_migrate/60c7d2ced17684c6b452e1b2b864aa6c.png)
③优先级:
![](https://i-blog.csdnimg.cn/blog_migrate/4a86b1dabcaf5acf846807499a701fd7.png)
![](https://i-blog.csdnimg.cn/blog_migrate/a662834c0b34936ece3cf5ae2d0aa2cc.png)
运行结果:
![](https://i-blog.csdnimg.cn/blog_migrate/a39e037332feb4f0072dea11899c6e6c.png)
这个比较容易理解,而对于一元运算符的优先级呢?这里举一个例子:
*p++
因为*、++是同级别的运算,所以这时按结合性来计算,而它属于一元,是按从右到左的顺序:
![](https://i-blog.csdnimg.cn/blog_migrate/913f8981dd72410c476f3e2e66e3c70f.png)
所以:
*p++ = *(p++) != (*p)++
赋值运算符:
赋值运算符的优先级低于算术运算符,仅高于逗号运算
![](https://i-blog.csdnimg.cn/blog_migrate/99c46f90d21540546aefbc9fb44737ab.png)
关系运算符:
在c语言中没有布尔类型,0表示假,1表示真:
![](https://i-blog.csdnimg.cn/blog_migrate/5a3aa65761a4db9c02a76c18809c8507.png)
逻辑运算符:
![](https://i-blog.csdnimg.cn/blog_migrate/02c4b8e30df6208fc3df4c55725b4df7.png)
下面来看两个例子:
![](https://i-blog.csdnimg.cn/blog_migrate/215d4c4097f585d3817bd3ff49a845b2.png)
说明:
1、++算术运算符比逻辑运算符||、&&优先级要高
2、&&优先级要与||高
3、由于||如果左边值为true,则会短路,所以++x=1,为逻辑真了,所以||右边的表达式就没有计算了。
![](https://i-blog.csdnimg.cn/blog_migrate/d7ab5cdd660a65b333a44b6ed7f07de9.png)
说明:
1、(++x||++y)有短路,所以++y并没有计算,
2、&&如果左边为false,则也会短路,而由于上面表达式中为true,所以,++z会执行到。
位运算符:
将数字转换成二进制形式后再按位处理
![](https://i-blog.csdnimg.cn/blog_migrate/d55f7ced2f95365809331fb8c3a810b4.png)
其中说明一下右移操作:
![](https://i-blog.csdnimg.cn/blog_migrate/80c03c7e5ea47b5aa188b73b9e86a5c3.png)
![](https://i-blog.csdnimg.cn/blog_migrate/83a6de5b01f5e9d7f7c92cb48018b708.png)
运行结果:
![](https://i-blog.csdnimg.cn/blog_migrate/e13b93cce12d4a5c6c1d79bedd42c025.png)
以十六进制的形式输出:
![](https://i-blog.csdnimg.cn/blog_migrate/d4de3166268fdb63ac75bd52714a9a33.png)
运行结果:
![](https://i-blog.csdnimg.cn/blog_migrate/47f58e7d71d9a0c9cd39b19abf3ad5f8.png)
为了让十六进制更加清晰,前面加一个ox前缀:
![](https://i-blog.csdnimg.cn/blog_migrate/7518253212b3484d1f3401a7cd692892.png)
输出如下:
![](https://i-blog.csdnimg.cn/blog_migrate/55efd2d61ef1c4dc8a059344b2c1f3e9.png)
这时,将它往右移8位
![](https://i-blog.csdnimg.cn/blog_migrate/7dc2802ac6984a21343a0cc62b91bfb9.png)
![](https://i-blog.csdnimg.cn/blog_migrate/ead42960b0919e35d60b945454cd72aa.png)
分析:
![](https://i-blog.csdnimg.cn/blog_migrate/3bd4903a940d0740580f4dfe59754432.png)
如果是
有符号数,那又是怎么样的呢?
![](https://i-blog.csdnimg.cn/blog_migrate/13765efee789a4ef26bda6e28e5427e1.png)
![](https://i-blog.csdnimg.cn/blog_migrate/240818ef57aaac8374dbfa9000dcd0ea.png)
C语言中的右移分为
逻辑右移和
算术右移:
逻辑右移:高位补0(对于无符号数来说,>>是指逻辑右移)
算术右移:保留符号位不变(对于正数,高位补0;对于负数,高位补1)
实际上,C语言并没有规定有符号数的>>是逻辑右移还是算术右移,但是,几乎所有的编译器将有符号数的>>都实现成了算术右移了。
知道了上面的位运算,下面用一个实际例子,来将其运用一下:
![](https://i-blog.csdnimg.cn/blog_migrate/a76e057ac631b49f3582172b4aeb3376.png)
![](https://i-blog.csdnimg.cn/blog_migrate/38eaab4e39c7baa1d88936160204ebb2.png)
![](https://i-blog.csdnimg.cn/blog_migrate/34ef57a7f4a098abcd6b1919c776d0e8.png)
![](https://i-blog.csdnimg.cn/blog_migrate/616d30d18f2631977cc61eb3ccd56096.png)
【
说明:x >> 8 & 0xFF,为什么还要与上0xFF,是为了有可能是算术右移,高位补1(虽说我们这个例子符号位是0),所以这样是为了保证将高八位全去掉】
下面举一些位运算的例子:
![](https://i-blog.csdnimg.cn/blog_migrate/c07dc863a25006529daad9ca520236d5.png)
其中~10为什么是-11呢,原因如下:
![](https://i-blog.csdnimg.cn/blog_migrate/600a51b38f984e52f391831ae2584918.png)
位运算符
优先级:
![](https://i-blog.csdnimg.cn/blog_migrate/3811c0c837ea9004966f78834b839a5f.png)
位运算示例【这个在实际当中都会用到的,争取要记住】:
![](https://i-blog.csdnimg.cn/blog_migrate/6704a631cf4979d2b36905317833fd08.png)
![](https://i-blog.csdnimg.cn/blog_migrate/6afd03f184161959e33efad1c94892b7.png)
![](https://i-blog.csdnimg.cn/blog_migrate/1a8542d4990015d4a57062f025561e99.png)
![](https://i-blog.csdnimg.cn/blog_migrate/931725078b1aa920a4658989418658d6.png)
解析:
![](https://i-blog.csdnimg.cn/blog_migrate/afac55454259cdac7e973086d0aba47a.png)
下面这两个位操作,是会经常用到的
【重要】
![](https://i-blog.csdnimg.cn/blog_migrate/f31deb5122567dafd6291687f0e9623d.png)
关于这两个位运算的应用,在博文:
linux系统编程之文件与io(五) - cexo - 博客园有用到,一般是用来设置状态,并清除状态
![](https://i-blog.csdnimg.cn/blog_migrate/081c0f1ae7ff32b9aae965c3893ada57.png)
这个也是上面提到过的,下面我们来论证一下该等式:
![](https://i-blog.csdnimg.cn/blog_migrate/2e96caa448e66e218c524fdedc69eb4a.png)
上面这是求一个正数的取反操作,那如果对一个负数进行取反,该等式也成立么,先用代码看下结果:
![](https://i-blog.csdnimg.cn/blog_migrate/0a63a68c225d651b4a8b5254dd8ef457.png)
![](https://i-blog.csdnimg.cn/blog_migrate/d03f5e467adfbc4b9fd5ba4e79bfd038.png)
下面关于运算符的优化级进行一个总结:
![](https://i-blog.csdnimg.cn/blog_migrate/3aa6595bb08849300d8ced4f7f69f6a3.png)
![](https://i-blog.csdnimg.cn/blog_migrate/ba9f504acfc5b7e62a4b0c4236ef232a.png)
下面对所有运算符的优化级进行一个总结,以便之后对优化级有疑惑时来进行查找:
![](https://i-blog.csdnimg.cn/blog_migrate/fa12e48636d22b128541543998691344.png)
![](https://i-blog.csdnimg.cn/blog_migrate/9072064fe4076f29587f69d41622e85d.png)
![](https://i-blog.csdnimg.cn/blog_migrate/5462f71dc5ab9ec3c095fe3fa0b97da9.png)
以一个范例来说明一下优先级:
![](https://i-blog.csdnimg.cn/blog_migrate/b3f6650a398f10ea32dd263ae2e40b1d.png)
修改优先级:
![](https://i-blog.csdnimg.cn/blog_migrate/25585b1499b13618313e258d9ec598af.png)
下面来使用一下三目及逗号运算符:
![](https://i-blog.csdnimg.cn/blog_migrate/9177e26c54e51723acbfb8add289b5e9.png)
编译运行:
![](https://i-blog.csdnimg.cn/blog_migrate/2b73f2a2140d7c2edd28fdb1544552b8.png)
【
注意:printf("%d\n",1,2,3);并非是逗号表达式,而是函数的参数传递】
常见的一些优先级错误:
![](https://i-blog.csdnimg.cn/blog_migrate/46ed06950b7874d70821a2ea6d1523c6.png)
【
建议:关于表达式的优级,只要把握“算术运算符优先级高于关系运算符高于逻辑运算符高于赋值运算符"原则,并记住上面经常范的错误,就能搞定它了!】