📜  C中的运算符优先级和关联性

📅  最后修改于: 2021-06-29 18:26:24             🧑  作者: Mango

运算符优先级确定在一个表达式中首先执行哪个运算符,且多个运算符具有不同的优先级。

例如:解决

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”。

例如:解决

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

知道优先级和关联性规则是很好的,但是最好的方法是使用方括号,尤其是对于不太常用的运算符(+,-,* ..等以外的运算运算符)。括号增加了代码的可读性,因为读者不必看表即可了解顺序。