C Traps:优先级常见错误
逻辑与关系运算符
if (flags & FLAG != 0) {...}
这类错误以前也犯过,因为!=的优先级比&要高所以实际上是这样的
if (flags & (FLAG != 0))
可以把&、|也作为一种逻辑操作,而逻辑操作符的优先级总是比比较操作符、运算操作符来得低。可以这样想,首先进行了一些运算,然后才比较他们的值,通过比较有了布尔值,最后就进行逻辑与、或操作了。
位移与算术运算符
上面的错误可能会在不清楚的情况下使用括号,但是下面的情况则很难会觉察到,记得好几次都是莫名其妙的位移操作出现过问题。
res = hi << 4 + low
实际上相当于:
res = hi << (4 + low)
这种编码错误个人感觉非常难以察觉,尤其在对优先级生疏的情况下。类似的有
res = low + hi << 4
相当于
res = (low + hi) << 4
赋值与比较运算符
while ((c=getc(in) != EOF) {...}
内层的括号是不可缺少的,因为赋值运算优先级低于比较运算符。
虽然有时码农编码是重复劳动,但是码农的基本功还是需要努力修炼的。
给出一个C++的优先级表
| Precedence | Operator | Description | Associativity |
|---|---|---|---|
| 1 | :: |
Scope resolution | Left-to-right |
| 2 | ++ -- |
Suffix/postfix increment and decrement | |
() |
Function call | ||
[] |
Array subscripting | ||
. |
Element selection by reference | ||
-> |
Element selection through pointer | ||
| 3 | ++ -- |
Prefix increment and decrement | Right-to-left |
+ − |
Unary plus and minus | ||
! ~ |
Logical NOT and bitwise NOT | ||
(type) |
Type cast | ||
* |
Indirection (dereference) | ||
& |
Address-of | ||
sizeof |
Size-of | ||
new, new[] |
Dynamic memory allocation | ||
delete, delete[] |
Dynamic memory deallocation | ||
| 4 | .* ->* |
Pointer to member | Left-to-right |
| 5 | * / % |
Multiplication, division, and remainder | |
| 6 | + − |
Addition and subtraction | |
| 7 | << >> |
Bitwise left shift and right shift | |
| 8 | < <= |
For relational operators < and ≤ respectively | |
> >= |
For relational operators > and ≥ respectively | ||
| 9 | == != |
For relational = and ≠ respectively | |
| 10 | & |
Bitwise AND | |
| 11 | ^ |
Bitwise XOR (exclusive or) | |
| 12 | | |
Bitwise OR (inclusive or) | |
| 13 | && |
Logical AND | |
| 14 | || |
Logical OR | |
| 15 | ?: |
Ternary conditional | Right-to-left |
= |
Direct assignment (provided by default for C++ classes) | ||
+= −= |
Assignment by sum and difference | ||
*= /= %= |
Assignment by product, quotient, and remainder | ||
<<= >>= |
Assignment by bitwise left shift and right shift | ||
&= ^= |= |
Assignment by bitwise AND, XOR, and OR | ||
| 16 | throw |
Throw operator (for exceptions) | |
| 17 | , |
Comma | Left-to-right |
记忆:
1. 获得要进行操作的数(()函数返回值或括号表达式值,[]数组下表,. ->成员引用,从左向右结合:a->b->c->d合法)
2. 进行单目操作(自增,自减,取地址,解引用,sizeof等,从右向左结合:*p++等同于*(p++))
3. 进行双目操作(乘除模,加减,位移,关系,位逻辑,逻辑,逻辑运算优先级低于其他关系算术运算,或低于与,从左向右结合)
4. 赋值(从右向左结合:a=b=c)
5. 逗号表达式(从左向右结合)
() 函数调用、括号肯定可以记住
参考:
1. C traps and pitfalls
2. http://en.cppreference.com/w/cpp/language/operator_precedence
C Traps:优先级常见错误的更多相关文章
- 040_字符串连接符 041_条件运算符目 042_运算符优先级_逻辑与或优先问题 043_自动类型转化 044_强制类型转换 045_基本类型常见错误_溢出_L问题
040_字符串连接符 package test_package; /** * 字符串运算符 * @author * */public class TestOperator05 { public sta ...
- GO 新开发者要注意的陷阱和常见错误
转自:http://colobu.com/2015/09/07/gotchas-and-common-mistakes-in-go-golang/ 初级 开大括号不能放在单独的一行 未使用的变量 未使 ...
- Go的50度灰:Golang新开发者要注意的陷阱和常见错误(转)
目录 [−] 初级 开大括号不能放在单独的一行 未使用的变量 未使用的Imports 简式的变量声明仅可以在函数内部使用 使用简式声明重复声明变量 偶然的变量隐藏Accidental Variable ...
- [转载]Go的50度灰:Golang新开发者要注意的陷阱和常见错误
初级 开大括号不能放在单独的一行 未使用的变量 未使用的Imports 简式的变量声明仅可以在函数内部使用 使用简式声明重复声明变量 偶然的变量隐藏Accidental Variable Shadow ...
- Golang新开发者要注意的陷阱和常见错误
转自:http://colobu.com/2015/09/07/gotchas-and-common-mistakes-in-go-golang/ 目录 [−] 初级 开大括号不能放在单独的一行 未使 ...
- .Net常见错误
常见错误 #1: 把引用当做值来用,或者反过来 C++ 和其他很多语言的程序员,习惯了给变量赋值的时候,要么赋单纯的值,要么是现有对象的引用.然而,在C# 中,是值还是引用,是由写这个对象的程序员决定 ...
- 100 个常见错误「GitHub 热点速览 v.22.35」
本周的特推非常得延续上周的特点--会玩,向别人家的女朋友发送早安.这个错误是如何发生的呢?如何有效避免呢?自己用 daily_morning 免部署.定制一个早安小助手给女友吧. 除了生活中的错误,工 ...
- 初识JAVA(二)(送给Java和安卓初学者)----常见错误
博主接着上篇的来讲哦,以后的更新中,博主会出一些练习题,有兴趣的可以做做然后吧代码粘贴到下面,大家可以一起研究学习,一起进步,本篇文章主要讲的是: 一.常见错误 二.连接上篇一起的训练 无论是什么方向 ...
- ubuntu 常见错误--Could not get lock /var/lib/dpkg/lock
ubuntu 常见错误--Could not get lock /var/lib/dpkg/lock 通过终端安装程序sudo apt-get install xxx时出错:E: Could not ...
随机推荐
- Servlet中相对路径与绝对路径
相对路径与绝对路径: 相对路径:相对路径指的是相对于当前文件所在目录的路径! http://localhost:8080/servlet01/ http://localhost:8080/servle ...
- 平衡二叉树(AVL)的理解和实现(Java)
AVL的定义 平衡二叉树:是一种特殊的二叉排序树,其中每一个节点的左子树和右子树的高度差至多等于1.从平衡二叉树的名字中可以看出来,它是一种高度平衡的二叉排序树.那么什么叫做高度平衡呢?意思就是要么它 ...
- POJ 2377
#include<stdio.h> #define MAXN 1005 #include<iostream> #include<algorithm> #define ...
- POJ 2376
#include<iostream>//by chengdacaizi. #include<stdio.h> #define MAXN 25005 using namespac ...
- ubuntu 下更新pip后发生 ImportError: cannot import name 'main'的问题解决
今天刚使用ubuntu 由于安装的是pip 8的版本,我感觉pip版本有些低就随手将将pip更新了,刚新到pip 10版本的,没想到刚更新完就报错了, 发生 ImportError: cannot i ...
- Ubuntu之tar与curl操作
1,压缩备份: tar cfvj /tmp/test.tar.bz2 /tmp/test tar cfvz /tmp/test.tar.gz /tmp/test tar xfvj /tmp/tes ...
- python代码位置引发的错误
觉得python对代码位置的要求简直是变态,缩进引发的错误我以前在博客里讲过了,如果不懂可以看看我以前的博客,今天又遇到了一个代码位置所引发的错误,现在给大家分享一下: 我想要打印出来一个5*5的实心 ...
- Spring Security构建Rest服务-1400-授权
安全分为 认证和授权,前边讲的都是认证,现在说授权. 前端业务系统的权限简单些,一般只区分是否登录,复杂点的还会区分 VIP用户等简单的角色,权限规则基本不变. 后台系统比较复杂,角色众多,权限随着业 ...
- windows 64位 下 安装 tomcat
tomcat 版本 windows 64位 .zip apache-tomcat-7.0.42.zip 注意: 1. 安装目录不得有 空格 或 中文字符 2. 然后,在系统环境变量下,新建一个变量: ...
- Check类的validate方法解读
此方法的实现如下: public void validate(JCTree tree, Env<AttrContext> env, boolean checkRaw) { Validato ...