快捷方式记住C语言运算符的求值顺序和优先级
快捷方式记住C语言运算符的求值顺序和优先级
这个问题已经有答案了:
有没有快捷的方法或最佳途径来记住C中的优先级和评估顺序,因为它扮演了主要角色,我(和大多数人)经常会忘记并最终弄乱。请帮帮我....
我想给个例子...
void main() { int a=1; a = a++ + ++a; printf("%d",a); }//prints 5; void main() { int a=1; int x; x = a++ + ++a; printf("%d",x); }//prints 4;
还有表达式
x = ++a + a++;
会得到不同的结果
我希望如果后缀递增有更高的优先级,那么a++
应该首先被评估,请告诉我是否错误,并请解释它的运作方式..
记忆C运算符优先级的一种快捷方法。
PUMA IS REBL(拼“REBL”就像“REBEL”一样)。
“IS”中的“I”不代表任何运算符,只是为了完成句子。
(注意: 所有没有指定结合性的运算符都是从左到右的)。
P - Primary(主要)
U - Unary(一元)
M - Multiplicative(乘法)
A - Additive(加法)
S- Shift(移位)
R- Relational(比较)
E- Equality(等于)
B- BitWise(位运算& gt; ^ & gt; | )
L- Logical(逻辑运算logical && & gt; logical ||)
最后三个运算符分别是:
T- Ternary(三元)
A- Assignment(赋值)
C- Comma(逗号)
(像TACO一样,T代表三元,A代表赋值,Co代表逗号。)
对于结合性,除了一元、赋值和三元以外,其他运算符都是从左到右的(AUTO是从右边走的,即赋值、一元和三元是从右到左的)。
建议查看注释以获得更多信息。
首先,形如a++ + ++a
,++a + a++
等表达式会导致未定义行为,任何结果都是可能的。从语言标准(n1256)可知:
6.5 表达式
……
2 在相邻的两个序列点前后,一个对象通过对表达式的求值最多被修改一次。72)此外,只能读取先前的值以确定要存储的值。73)
……
72) 浮点状态标志(flag)不是对象,可以在表达式中设置多次。73) 该段落使得
i = ++i + 1;
和a[i++] = i;
等语句出现未定义的状态,但允许i = i + 1;
和a[i] = i;
等语句
因此,请勿这样做。
像x = a++ + ++b
这样定义良好的表达式将被解析为x = ((a++) + (++b))
。两种形式的++
运算符的优先级高于加法,而加法的优先级高于赋值。该表达式的结果将与x = a + (b + 1)
相同。
其次,请记住++
和--
运算符都具有结果和副作用,如下所示:
表达式 结果 副作用 ---------- ------ ----------- i++ i i = i + 1 ++i i + 1 i = i + 1 i-- i i = i - 1 --i i - 1 i = i - 1
需要记住的重要一点是:副作用不必在表达式被求值后立即应用,它只需要在下一个序列点之前应用。因此,x = a++ + ++b
可能以如下方式进行评估:
t1 = a; t2 = b + 1; x = t1 + t2; b = b + 1; a = a + 1;
在这种情况下,对a
和b
的更新被延迟到加法和赋值给x
之后。
关于优先级,以下是从高到低的一般顺序:
- 后缀运算符(所有后缀运算符的优先级相同,因此运算符序列将从左到右求值)
- 数组下标运算符
[]
- 函数调用运算符
()
- 成分选择运算符
.
和->
- 后缀++和--
- 数组下标运算符
- 一元运算符(所有一元运算符的优先级相同,因此序列将从左到右求值)
- 前缀++和--
sizeof
- 按位取反运算符
~
- 逻辑非运算符
!
- 一元符号操作符
-
和+
- 取地址运算符
&
- 解引用运算符
*
- 强制类型转换表达式
(
类型名)
- 乘法运算符
*
、/
、%
- 加法运算符
+
和-
- 移位运算符
<<
和>>
- 关系运算符
<
、>
、<=
、>=
- 相等运算符
==
和!=
- 按位与
&
- 按位异或
^
- 按位或
|
- 逻辑与
&&
- 逻辑或
||
- 条件运算符
?:
- 赋值运算符
=
,+=
,-=
,*=
,/=
,%=
,<<=
,>>=
,&=
,^=
,|=
- 顺序(逗号)运算符
,
因此,像*x++
这样的表达式将被解析为*(x++)
,因为后缀++
的优先级高于一元*
。同样,sizeof x + 1
将被解析为(sizeof x) + 1
,因为sizeof
的优先级高于加法。表达式p++->x
将被解析为(p++)->x
,因为后缀++
和->
运算符的优先级相同,因此它们将从左到右解析。
这是最短的快捷方式之一; 当有疑问时,请使用括号。