Precedencia de operadores en C
La siguiente tabla enumera la precedencia y asociatividad de los operadores de C. Los operadores se listan de arriba abajo, en orden descendente de precedencia.
| Precedencia | Operador | Descripción | Asociatividad |
|---|---|---|---|
| 1 | ++ --
|
Incremento y decremento sufijo/postfijo | De izquierda a derecha |
()
|
Llamada a función | ||
[]
|
Subindicación de arreglo | ||
.
|
Acceso a miembros de estructura y unión | ||
->
|
Acceso a miembros de estructura y unión a través de puntero | ||
(type){list}
|
Literal compuesto(C99) | ||
| 2 | ++ --
|
Incremento y decremento prefijo[1] | De derecha a izquierda |
+ -
|
Más y menos unarios | ||
! ~
|
NO lógico y NO bit a bit | ||
(type)
|
Conversión explícita | ||
*
|
Indirección (desreferencia) | ||
&
|
Dirección de | ||
sizeof
|
Tamaño de[2] | ||
_Alignof
|
Requisito de alineación(C11) | ||
| 3 | * / %
|
Multiplicación, división y resto | De izquierda a derecha |
| 4 | + -
|
Suma y resta | |
| 5 | << >>
|
Desplazamiento izquierdo y derecho bit a bit | |
| 6 | < <=
|
Para operadores relacionales < y ≤ respectivamente | |
> >=
|
Para operadores relacionales > y ≥ respectivamente | ||
| 7 | == !=
|
Para operadores relacionales == y != respectivamente | |
| 8 | &
|
Y bit a bit | |
| 9 | ^
|
XOR bit a bit (o exclusivo) | |
| 10 | |
|
O bit a bit (o inclusivo) | |
| 11 | &&
|
Y lógico | |
| 12 | ||
|
O lógico | |
| 13 | ?:
|
Condicional ternario[3] | De derecha a izquierda |
| 14[4] | =
|
Asignación simple | |
+= -=
|
Asignación por suma y resta | ||
*= /= %=
|
Asignación por producto, cociente y resto | ||
<<= >>=
|
Asignación por desplazamiento izquierdo y derecho bit a bit | ||
&= ^= |=
|
Asignación por Y, XOR y O bit a bit | ||
| 15 | ,
|
Coma | De izquierda a derecha |
- ↑ El operando de
++y--prefijo no puede ser una conversión explícita de tipo. Esta regla prohíbe gramaticalmente algunas expresiones que de todos modos serían semánticamente inválidas. Algunos compiladores ignoran esta regla y detectan la invalidez semánticamente. - ↑ El operando de
sizeofno puede ser una conversión explícita de tipo: la expresiónsizeof (int) * pse interpreta inequívocamente como(sizeof(int)) * p, pero no comosizeof((int)*p). - ↑ La expresión en medio del operador condicional (entre
?y:) se analiza como si estuviera entre paréntesis: su precedencia relativa a?:se ignora. - ↑ Los operandos izquierdos de los operadores de asignación deben ser expresiones unarias (de nivel 2, no de conversión). Esta regla prohíbe gramaticalmente algunas expresiones que de todos modos serían semánticamente inválidas. Muchos compiladores ignoran esta regla y detectan la invalidez semánticamente. Por ejemplo,
e = a < d ? a++ : a = des una expresión que no se puede analizar debido a esta regla. Sin embargo, muchos compiladores ignoran esta regla y la analizan comoe = ( ((a < d) ? (a++) : a) = d ), y luego dan un error porque es semánticamente inválida.
Al analizar una expresión, un operador que aparece en una fila se enlazará más estrechamente (como si estuviera entre paréntesis) a sus argumentos que cualquier operador que aparezca en una fila inferior. Por ejemplo, la expresión *p++ se analiza como *(p++), y no como (*p)++.
Los operadores que están en la misma celda (puede haber varias filas de operadores listados en una celda) se evalúan con la misma precedencia, en la dirección dada. Por ejemplo, la expresión a = b = c se analiza como a = (b = c), y no como (a = b) = c debido a la asociatividad de derecha a izquierda.
Notas
Precedencia y asociatividad son independientes del orden de evaluación.
El estándar en sí no especifica niveles de precedencia. Se derivan de la gramática.
En C++, el operador condicional tiene la misma precedencia que los operadores de asignación, y los operadores prefijo ++ y -- y los operadores de asignación no tienen restricciones sobre sus operandos.
La especificación de asociatividad es redundante para operadores unarios y solo se muestra por completitud: los operadores unarios prefijo siempre se asocian de derecha a izquierda (sizeof ++*p es sizeof(++(*p))) y los operadores unarios postfijo siempre se asocian de izquierda a derecha (a[1][2]++ es ((a[1])[2])++). Nótese que la asociatividad es significativa para los operadores de acceso a miembros, aunque estén agrupados con operadores unarios postfijo: a.b++ se analiza como (a.b)++ y no como a.(b++).
Referencias
- Estándar C23 (ISO/IEC 9899:2024):
- A.3.1 Expresiones
- Estándar C17 (ISO/IEC 9899:2018):
- A.2.1 Expresiones
- Estándar C11 (ISO/IEC 9899:2011):
- A.2.1 Expresiones
- Estándar C99 (ISO/IEC 9899:1999):
- A.2.1 Expresiones
- Estándar C89/C90 (ISO/IEC 9899:1990):
- A.1.2.1 Expresiones
Véase también
Orden de evaluación de los argumentos del operador en tiempo de ejecución.
| Operadores comunes | ||||||
|---|---|---|---|---|---|---|
| asignación | incremento decremento |
aritméticos | lógicos | comparación | miembro acceso |
otros |
|
|
|
|
|
|
|
|
Documentación de C++ para precedencia de operadores en C++
|