O quadro seguinte é uma tabela que lista a precedência e associatividade de todos os operadores nas linguagens C e C++ (quando os operadores também existem em Java, Perl, PHP e muitas outras linguagens recentes, a precedência é a mesma que foi dada). Os operadores são listados de cima para baixo, em precedência decrescente. A precedência decrescente refere-se à prioridade do agrupamento de operadores e operandos. Considerando uma expressão, um operador que esteja listado em alguma fila será agrupado antes de qualquer operador que esteja listado numa fila mais abaixo. Os operadores que se encontram na mesma célula (pode haver várias filas de operadores listados numa célula) são agrupados com a mesma precedência, na direcção indicada. A precedência de um operador não é afectada pela sobrecarga.
A sintaxe das expressões em C e C++ é especificada por uma estrutura gramatical de frases. A tabela aqui dada foi inferida a partir da gramática. Para a norma ISO C 1999, a secção 6.5.6 nota 71 afirma que a gramática em C fornecida pela especificação define a precedência dos operadores em C, e também afirma que a precedência do operador resultante da gramática segue de perto a ordenação da secção da especificação:
“A sintaxe especifica a precedência dos operadores na avaliação de uma expressão, que é a mesma que a ordem das subcláusulas principais desta subcláusula, a precedência mais alta primeiro.”
Uma tabela de precedência, embora na sua maioria adequada, não pode resolver alguns detalhes. Em particular, note-se que o operador ternário permite qualquer expressão arbitrária como o seu operando médio, apesar de estar listado como tendo maior precedência do que os operadores de atribuição e de vírgula. Assim a ? b, c : d
é interpretado como a ? (b, c) : d
, e não como o sem sentido (a ? b), (c : d)
. Assim, a expressão no meio do operador condicional (entre ?
e :
) é interpretada como se estivesse entre parênteses. Note também que o resultado imediato, sem parênteses, de uma expressão em C não pode ser o operando de sizeof
. Portanto, sizeof (int) * x
é interpretado como (sizeof(int)) * x
e não sizeof ((int) * x)
.
NotesEdit
A tabela de precedentes determina a ordem de encadernação em expressões encadeadas, quando não é expressamente especificada por parênteses.
Precedência e encadernações
/div>
Muitos dos operadores que contêm sequências multi-caracteres recebem “nomes” construídos a partir do nome do operador de cada carácter. Por exemplo, +=
e -=
são frequentemente chamados mais igual(es) e menos igual(es), em vez dos mais verbosos “atribuição por adição” e “atribuição por subtracção”.A ligação dos operadores em C e C++ é especificada (nas Normas correspondentes) por uma gramática de linguagem factorizada, em vez de uma tabela de precedências. Isto cria alguns conflitos subtis. Por exemplo, em C, a sintaxe para uma expressão condicional é:
logical-OR-expression ? expression : conditional-expression
enquanto que em C+++ é:
logical-OR-expression ? expression : assignment-expression
Hence, a expressão:
e = a < d ? a++ : a = d
é analisada de forma diferente nas duas línguas. Em C, esta expressão é um erro de sintaxe, porque a sintaxe para uma expressão de atribuição em C é:
unary-expression '=' assignment-expression
Em C++, é parsed as:
e = (a < d ? a++ : (a = d))
, que é uma expressão válida.
int a = 1, b = 2, weirdVariable = (++a, b), d = 4;
Crítica à precedência dos operadores bitwise e igualdadeEdit
A precedência dos operadores lógicos bitwise foi criticada. Conceitualmente, & e | são operadores aritméticos como * e +.
Mais ainda, em operações de igualdade C++ (e versões posteriores de C), com excepção do operador de comparação de três vias, os valores do tipo bool que são conceptualmente um único bit (1 ou 0) e como tal não pertencem propriamente às operações “bitwise”.
C++ sinónimos de operadorEditar
C++ define certas palavras-chave para agir como pseudónimos para um certo número de operadores:
Keyword | |
---|---|
&& |
|
&= |
|
bit e |
& |
| |
|
! |
|
!= |
|
xor |
^ |
Estes podem ser utilizados exactamente da mesma forma que os símbolos de pontuação que substituem, pois não são o mesmo operador com um nome diferente, mas sim simples substituições simbólicas para o nome (cadeia de caracteres) do respectivo operador. Isto significa que as expressões (a > 0 e não bandeira)
e (a >&& !flag)
têm significados idênticos. Significa também que, por exemplo, o bitand
palavra-chave pode ser utilizada para substituir não só o bitwise-e operador, mas também os destinatários-do operador, e pode mesmo ser utilizada para especificar tipos de referência (por exemplo, int bitand ref = n
). A especificação ISO C permite estas palavras-chave como macros de pré-processador no ficheiro de cabeçalho iso646.h
. Para compatibilidade com C, C++ fornece o cabeçalho ciso646
, cuja inclusão não tem efeito.