运算符优先级确定在一个表达式中首先执行哪个运算符,且该运算符具有多个优先级不同的运算符。
例如:解决
10 + 20 * 30
10 + 20 * 30 is calculated as 10 + (20 * 30)
and not as (10 + 20) * 30
当两个优先级相同的运算符出现在表达式中时,使用运算符关联性。关联可以是L- EFT吨öř飞行或R飞行吨0 1 EFT。
例如:“*”和“/”具有相同的优先级和它们的结合性为L EFT吨öř飞行,所以表达式的“100/10 * 10”被视为“(100/10)* 10”。
Operators Precedence and Associativity are two characteristics of operators that determine the evaluation order of sub-expressions in absence of brackets
例如:解决
100 + 200 / 10 - 3 * 10
1)关联性仅在存在两个或多个相同优先级的运算符时使用。
需要注意的一点是,关联性并未定义单个运算符的操作数求值的顺序。例如,考虑以下程序,+运算符的关联性从左到右,但这并不意味着总是在f2()之前调用f1()。以下程序的输出实际取决于编译器。有关详细信息,请参见此。
// Associativity is not used in the below program.
// Output is compiler dependent.
#include
int x = 0;
int f1()
{
x = 5;
return x;
}
int f2()
{
x = 10;
return x;
}
int main()
{
int p = f1() + f2();
printf("%d ", x);
return 0;
}
2)所有具有相同优先级的运算符具有相同的关联性
这是必要的,否则,编译器将无法确定具有两个相同优先级和不同关联性的运算符的表达式的求值顺序。例如,+和–具有相同的关联性。
3)后缀++和前缀++的优先级和关联性不同
后缀++的优先级大于前缀++,它们的关联性也不同。后缀++的关联性从左到右,前缀++的关联性从右到左。请参阅此示例。
4)逗号在所有运算符的优先级最低,应谨慎使用例如,考虑以下程序,输出为1。有关更多详细信息,请参见此内容。
#include
int main()
{
int a;
a = 1, 2, 3; // Evaluated as (a = 1), 2, 3
printf("%d", a);
return 0;
}
5)在C中没有运算符链
在Python,“ c> b> a”之类的表达式被视为“ c> b和b> a”,但是这种类型的链接在C语言中不会发生。例如,考虑以下程序。以下程序的输出为“ FALSE”。
#include
int main()
{
int a = 10, b = 20, c = 30;
// (c > b > a) is treated as ((c > b) > a), associativity of '>'
// is left to right. Therefore the value becomes ((30 > 20) > 10)
// which becomes (1 > 20)
if (c > b > a)
printf("TRUE");
else
printf("FALSE");
return 0;
}
请参阅以下优先级和关联性表以供参考。
Operator |
Description |
Associativity |
---|---|---|
( ) [ ] . -> ++ — |
Parentheses (function call) (see Note 1) Brackets (array subscript) Member selection via object name Member selection via pointer Postfix increment/decrement (see Note 2) |
left-to-right |
++ — + – ! ~ (type) * & sizeof |
Prefix increment/decrement Unary plus/minus Logical negation/bitwise complement Cast (convert value to temporary value of type) Dereference Address (of operand) Determine size in bytes on this implementation |
right-to-left |
* / % | Multiplication/division/modulus | left-to-right |
+ – | Addition/subtraction | left-to-right |
<< >> | Bitwise shift left, Bitwise shift right | left-to-right |
< <= > >= |
Relational less than/less than or equal to Relational greater than/greater than or equal to |
left-to-right |
== != | Relational is equal to/is not equal to | left-to-right |
& | Bitwise AND | left-to-right |
^ | Bitwise exclusive OR | left-to-right |
| | Bitwise inclusive OR | left-to-right |
&& | Logical AND | left-to-right |
| | | Logical OR | left-to-right |
? : | Ternary conditional | right-to-left |
= += -= *= /= %= &= ^= |= <<= >>= |
Assignment Addition/subtraction assignment Multiplication/division assignment Modulus/bitwise AND assignment Bitwise exclusive/inclusive OR assignment Bitwise shift left/right assignment |
right-to-left |
, |
Comma (separate expressions) | left-to-right |
知道优先级和关联性规则是很好的,但是最好的方法是使用方括号,尤其是对于不太常用的运算符(+,-,* ..等以外的运算运算符)。括号增加了代码的可读性,因为读者不必看表即可了解顺序。