La siguiente es una tabla que enumera la precedencia y asociatividad de todos los operadores en los lenguajes C y C++ (cuando los operadores también existen en Java, Perl, PHP y muchos otros lenguajes recientes, la precedencia es la misma que la dada). Los operadores se enumeran de arriba a abajo, en precedencia descendente. La precedencia descendente se refiere a la prioridad de la agrupación de operadores y operandos. Considerando una expresión, un operador que aparece en alguna fila se agrupará antes que cualquier operador que aparezca en una fila más abajo. Los operadores que están en la misma celda (puede haber varias filas de operadores listados en una celda) se agrupan con la misma precedencia, en la dirección dada. La precedencia de un operador no se ve afectada por la sobrecarga.
La sintaxis de las expresiones en C y C++ se especifica mediante una gramática de estructura de frases. La tabla que se ofrece aquí se ha deducido de la gramática. Para la norma ISO C 1999, la sección 6.5.6 nota 71 establece que la gramática de C proporcionada por la especificación define la precedencia de los operadores de C, y también establece que la precedencia de los operadores resultante de la gramática sigue de cerca el orden de la sección de la especificación:
«La sintaxis especifica la precedencia de los operadores en la evaluación de una expresión, que es la misma que el orden de las subcláusulas principales de esta subcláusula, la precedencia más alta primero.»
Una tabla de precedencias, aunque en su mayoría es adecuada, no puede resolver algunos detalles. En particular, observe que el operador ternario permite cualquier expresión arbitraria como su operando medio, a pesar de estar listado como de mayor precedencia que los operadores de asignación y coma. Así, a ? b, c : d
se interpreta como a ? (b, c) : d
, y no como el sin sentido (a ? b), (c : d)
. Así, la expresión en medio del operador condicional (entre ?
y :
) se analiza como si estuviera entre paréntesis. Además, tenga en cuenta que el resultado inmediato, sin paréntesis, de una expresión C cast no puede ser el operando de sizeof
. Por lo tanto, sizeof (int) * x
se interpreta como (sizeof(int)) * x
y no sizeof ((int) * x)
.
NotasEditoriales
La tabla de precedencias determina el orden de vinculación en las expresiones encadenadas, cuando no se especifica expresamente mediante paréntesis.
Precedencia y ligaduras
Muchos de los operadores que contienen secuencias de varios caracteres reciben «nombres» construidos a partir del nombre del operador de cada carácter. Por ejemplo, +=
y -=
a menudo se llaman igual(es) más y igual(es) menos, en lugar de los más verbales «asignación por adición» y «asignación por sustracción».La vinculación de los operadores en C y C++ se especifica (en las Normas correspondientes) mediante una gramática del lenguaje factorizada, en lugar de una tabla de precedencias. Esto crea algunos conflictos sutiles. Por ejemplo, en C, la sintaxis para una expresión condicional es:
logical-OR-expression ? expression : conditional-expression
mientras que en C++ es:
logical-OR-expression ? expression : assignment-expression
Por lo tanto, la expresión:
e = a < d ? a++ : a = d
se analiza de forma diferente en los dos lenguajes. En C, esta expresión es un error de sintaxis, porque la sintaxis de una expresión de asignación en C es:
unary-expression '=' assignment-expression
En C++, se analiza como:
e = (a < d ? a++ : (a = d))
que es una expresión válida.
int a = 1, b = 2, weirdVariable = (++a, b), d = 4;
Crítica a la precedencia de los operadores lógicos bitwise e equalityEdit
La precedencia de los operadores lógicos bitwise ha sido criticada. Conceptualmente, & y | son operadores aritméticos como * y +.
Además, en C++ (y versiones posteriores de C) las operaciones de igualdad, con la excepción del operador de comparación a tres bandas, arrojan valores de tipo bool que son conceptualmente un solo bit (1 ó 0) y como tal no pertenecen propiamente a las operaciones «bitwise».
Sinónimos de operadores C++Editar
C++ define ciertas palabras clave para actuar como alias de una serie de operadores:
Palabra clave | Operador |
---|---|
y |
&& |
and_eq |
&= |
bitand |
& |
bitor |
| |
compl |
~ |
no |
! |
not_eq |
!= |
or |
|| |
or_eq |
|= |
xor |
^ |
xor_eq |
^= |
Se pueden utilizar exactamente igual que los símbolos de puntuación a los que sustituyen, ya que no son el mismo operador con un nombre diferente, sino simples sustitutos de tokens para el nombre (cadena de caracteres) del operador respectivo. Esto significa que las expresiones (a > 0 y no bandera)
y ¡(a >&& !flag)
tienen idénticos significados. También significa que, por ejemplo, la palabra clave bitand
puede utilizarse para reemplazar no sólo el operador bit y sino también el operador dirección de, e incluso puede utilizarse para especificar tipos de referencia (por ejemplo, int bit y ref = n
). La especificación ISO C permite estas palabras clave como macros de preprocesador en el archivo de cabecera iso646.h
. Por compatibilidad con C, C++ proporciona la cabecera ciso646
, cuya inclusión no tiene ningún efecto.