Precedência e ordem da avaliação

A precedência e a associatividade dos operadores C afetam o agrupamento e a avaliação dos operandos nas expressões. A precedência de um operador é significante somente quando outros operadores com precedência maior ou menor estão presentes. As expressões com operadores de maior precedência são avaliadas primeiro. A precedência também pode ser descrita pela palavra "associação". Os operadores com uma precedência mais alta, em teoria, têm uma associação mais fechada.

A tabela a seguir resume a precedência e a associatividade (a ordem em que os operandos são avaliados) dos operadores C, listando-os em ordem decrescente de precedência. Onde vários operadores aparecem juntos, eles têm a mesma precedência e são avaliados de acordo com sua associatividade. Os operadores na tabela são descritos nas seções que começam com Operadores de sufixo. O restante desta seção fornece informações gerais sobre a precedência e associatividade.

Precedência e associatividade de operadores C

Símbolo 1 Tipo de operação Capacidade de associação
[ ] ( ) . ->
++ -- (sufixo)
Expression Da esquerda para a direita
sizeof & * + - ~ !
++ -- (prefixo)
Unário Da direita para a esquerda
typecasts Unário Da direita para a esquerda
* / % Multiplicativo Da esquerda para a direita
+ - Aditiva Da esquerda para a direita
<< >> Deslocamento bit a bit Da esquerda para a direita
< > <= >= Relacional Da esquerda para a direita
== != Igualitário Da esquerda para a direita
& Bitwise-AND Da esquerda para a direita
^ Bitwise-exclusive-OR Da esquerda para a direita
| Bitwise-inclusive-OR Da esquerda para a direita
&& Logical-AND Da esquerda para a direita
|| Logical-OR Da esquerda para a direita
? : Expressão condicional Da direita para a esquerda
= *= /= %=
+= -= <<= >>= &=
^= |=
Atribuição simples e composta 2 Da direita para a esquerda
, Avaliação sequencial Da esquerda para a direita

1 Os operadores são listados em ordem decrescente de precedência. Quando vários operadores aparecem na mesma linha ou em um grupo, eles têm a mesma precedência.

2 Todos os operadores de atribuição simples e composta têm a mesma precedência.

Uma expressão pode conter vários operadores com a mesma precedência. Quando vários desses operadores aparecem no mesmo nível em uma expressão, a avaliação procede de acordo com a associatividade do operador, da direita para a esquerda ou da esquerda para a direita. A direção da avaliação não afeta os resultados das expressões que incluem mais de um operador de multiplicação (*), adição (+) ou binário bit a bit (&, | ou ^) no mesmo nível. A ordem das operações não é definida pela linguagem. O compilador é livre para avaliar essas expressões em qualquer ordem, se ele puder garantir um resultado consistente.

Somente os operadores de avaliação sequencial (,), AND lógico (&&), OR lógico (||), de expressão condicional (? :) e de chamada de função constituem pontos de sequência e, portanto, garantem uma ordem específica de avaliação de seus operandos. O operador da chamada de função é o conjunto de parênteses depois do identificador da função. O operador de avaliação sequencial (,) é garantido para avaliar seus operandos da esquerda para a direita. (O operador vírgula em uma chamada de função não é o mesmo que o operador de avaliação sequencial e não fornece essa garantia). Para obter mais informações, consulte Pontos de sequência.

Os operadores lógicos também garantem a avaliação de seus operandos da esquerda para a direita. No entanto, eles avaliam o menor número de operandos necessários para determinar o resultado da expressão. Isso é chamado de avaliação de" curto-circuito". Assim, alguns operandos da expressão não podem ser avaliados. Por exemplo, na expressão

x && y++

o segundo operando, y++, será avaliado somente se x for true (diferente de zero). Assim, y não será incrementado se x for false (0).

Exemplos

A lista a seguir mostra como o compilador associa automaticamente várias expressões de exemplo:

Expression Associação automática
a & b || c (a & b) || c
a = b || c a = (b || c)
q && r || s-- (q && r) || s--

Na primeira expressão, o operador AND bit a bit (&) tem uma maior precedência que o operador OR lógico (||), então a & b forma o primeiro operando da operação OR lógica.

Na segunda expressão, o operador OR lógico (||) tem maior precedência que o operador de atribuição simples (=), então b || c é agrupado como o operando à direita na atribuição. Observe que o valor atribuído a a é 0 ou 1.

A terceira expressão mostra uma expressão corretamente formada que pode gerar um resultado inesperado. O operador AND lógico (&&) tem maior precedência que o operador OR lógico (||), então q && r é agrupado como um operando. Como os operadores lógicos asseguram a avaliação dos operandos da esquerda para a direita, q && r é avaliado antes de s--. No entanto, se q && r for avaliado como um valor diferente de zero, s-- não será avaliado e s não será diminuído. Se não diminuir s for causar um problema em seu programa, s-- deverá aparecer como o primeiro operando da expressão ou s deverá ser diminuído em uma operação separada.

A expressão a seguir é ilegal e gera uma mensagem de diagnóstico no tempo de compilação:

Expressão ilegal Agrupamento padrão
p == 0 ? p += 1: p += 2 ( p == 0 ? p += 1 : p ) += 2

Nessa expressão, o operador de igualdade (==) tem a precedência mais alta, então p == 0 é agrupado como um operando. O operador de expressão condicional (? :) tem a próxima precedência mais alta. Seu primeiro operando é p == 0, e o segundo operando é p += 1. No entanto, o último operando do operador de expressão condicional é considerado p em vez de p += 2, já que essa ocorrência de p se associa ainda mais ao operador de expressão condicional do que ao operador de atribuição composta. Um erro de sintaxe ocorre porque += 2 não tem um operando à esquerda. Você deve usar parênteses para evitar erros desse tipo e gerar um código mais legível. Por exemplo, você pode usar parênteses como mostrado abaixo para corrigir e esclarecer o exemplo anterior:

( p == 0 ) ? ( p += 1 ) : ( p += 2 )

Confira também

Operadores C