Precedência e a ordem de avaliação
A precedência e associatividade de operadores c afetam o agrupamento e a avaliação dos operandos em expressões.Precedência do operador, um é significativa apenas se outros operadores com maior ou menor precedência estão presentes.Expressões com maior precedência de operadores são avaliadas primeiro.Precedência também pode ser descrita pela palavra "ligação." Operadores de prioridade são considerados tem ligação mais rígida.
A tabela a seguir resume a precedência e associatividade (a ordem na qual os operandos são avaliados) dos operadores C, listando-os na ordem de precedência do maior para o menor.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 começando com Operadores de sufixo.O restante desta seção fornece informações gerais sobre precedência e associatividade.
Precedência e associatividade de operadores c
Symbol1 |
Tipo de operação |
Associatividade |
---|---|---|
[ ] ( ) . – > posfixada ++ e o sufixo – |
Expression |
Esquerda para a direita |
prefixo ++ e o prefixo –sizeof & * + – ~! |
Unário |
Direita para a esquerda |
typecasts |
Unário |
Direita para a esquerda |
* / % |
Multiplicativos |
Esquerda para a direita |
+ – |
Aditivo |
Esquerda para a direita |
<< >> |
Bit a bit shift |
Esquerda para a direita |
< > <> = = |
Relacional |
Esquerda para a direita |
== != |
Igualdade |
Esquerda para a direita |
& |
Bit a bit- E |
Esquerda para a direita |
^ |
Bit a bit exclusivo ou |
Esquerda para a direita |
| |
OR bit a bit-inclusive |
Esquerda para a direita |
& & |
Lógico- E |
Esquerda para a direita |
|| |
Lógica OR |
Esquerda para a direita |
?: |
Expressão condicional |
Direita para a esquerda |
= *= /= %= + = – = <> = = & = ^= |= |
Assignment2 simples e compostas |
Direita para a esquerda |
, |
Avaliação seqüencial |
Esquerda para a direita |
1.Operadores estão listados em ordem decrescente de precedência.Se vários operadores aparecerem na mesma linha ou em um grupo, eles têm a mesma precedência.
2.Todos os operadores de simples e compostos-atribuição têm a mesma precedência.
Uma expressão pode conter vários operadores com a mesma precedência.Quando vários operadores tais aparecem no mesmo nível em uma expressão, avaliação continuará de acordo com a associatividade do operador, da direita para a esquerda ou da esquerda para a direita.A direção de avaliação não afeta os resultados de expressões que incluem mais de uma multiplicação (*), acréscimo (+), ou bit a bit binário (& | ^) o operador de mesmo nível.Ordem de operações não está definido pelo idioma.O compilador é livre para avaliar tais expressões em qualquer ordem, se o compilador pode garantir um resultado consistente.
Somente a seqüencial-avaliação (,) lógico- E (& &), a lógica OR (||), a expressão condicional (? :), e os operadores de chamada de função constituem pontos de seqüência e, portanto, garantem uma determinada ordem de avaliação de seus operandos.O operador de chamada de função é o conjunto de parênteses após o identificador da função.O operador seqüencial de avaliação (,) é garantido para avaliar seus operandos da esquerda para a direita.(Observe que o operador de vírgula em uma chamada de função não é o mesmo que o operador seqüencial de avaliação e não fornece qualquer garantia de tal). Para obter mais informações, consulte Pontos de seqüência.
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 circuito curto.Assim, alguns operandos da expressão não podem ser avaliados.Por exemplo, na expressão
x && y++
o segundo operando, y++, é avaliada somente se x é verdadeiro (diferente de zero).Assim, y não é aumentado se x for false (0).
Exemplos
A lista a seguir mostra como o compilador automaticamente vincula várias expressões de amostra:
Expression |
Vinculaçã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 bit a bit- E operador (&) tem precedência maior do que o operador lógico OR (||), de modo que a & b o primeiro operando da operação lógica OR de formulários.
Na segunda expressão, o operador lógico OR (||) tem precedência maior do que o operador de atribuição de simples (=), de modo que b || c é agrupado como operando direito na atribuição.Observe que o valor atribuído a a é 0 ou 1.
A terceira expressão mostra uma expressão formada corretamente que pode produzir um resultado inesperado.A lógica- E operador (&&) tem precedência maior do que o operador lógico OR (||), de modo que q && r é agrupado como um operando.Uma vez que os operadores lógicos garantem a avaliação dos operandos da esquerda para a direita, q && r é avaliada antes de s––.No entanto, se q && r for avaliada como um valor diferente de zero, s–– não é avaliada, e s não é diminuído.Se não decrementar s poderia causar um problema no seu programa, s–– deve ser exibido como o primeiro operando da expressão, ou s deve ser diminuída em uma operação separada.
A expressão a seguir é ilegal e produz uma mensagem de diagnóstico em tempo de compilação:
Expressão ilegal |
Padrão de agrupamento |
---|---|
p == 0 ? p += 1: p += 2 |
( p == 0 ? p += 1 : p ) += 2 |
Nesta expressão, o operador de igualdade (==) tem a precedência mais alta, então, p == 0 é agrupado como um operando.O operador condicional-expression (? :) tem a precedência mais alta.Seu primeiro operando é p == 0, e seu segundo operando é p += 1.No entanto, o último operando do operador condicional-expressão será considerado como p em vez de p += 2, desde esta ocorrência de p vincula ao operador condicional-expressão mais de perto do que para o operador de atribuição de compostos.Ocorre um erro de sintaxe, pois += 2 não tem um operando esquerdo.Você deve usar parênteses para evitar erros desse tipo e produzir um código mais legível.Por exemplo, você pode usar parênteses como mostrado a seguir para corrigir e esclarecer o exemplo anterior:
( p == 0 ) ? ( p += 1 ) : ( p += 2 )