C Operator Precedence
La siguiente tabla enumera la precedencia y asociatividad de los operadores de C. Los operadores se listan de arriba a abajo, en precedencia descendente.
| Precedencia | Operador | Descripción | Asociatividad |
|---|---|---|---|
| 1 |
++
--
|
Incremento y decremento sufijo/postfijo | Izquierda a derecha |
()
|
Llamada a función | ||
[]
|
Subíndice de arreglo | ||
.
|
Acceso a miembro de estructura y unión | ||
->
|
Acceso a miembro de estructura y unión a través de puntero | ||
(
type
){
list
}
|
Literal compuesto (C99) | ||
| 2 |
++
--
|
Incremento y decremento prefijo [nota 1] | Derecha a izquierda |
+
-
|
Más y menos unarios | ||
!
~
|
NOT lógico y NOT bit a bit | ||
(
type
)
|
Conversión de tipo (cast) | ||
*
|
Indirección (desreferencia) | ||
&
|
Dirección de | ||
sizeof
|
Tamaño de [nota 2] | ||
_Alignof
|
Requerimiento de alineación (C11) | ||
| 3 |
*
/
%
|
Multiplicación, división y resto | Izquierda a derecha |
| 4 |
+
-
|
Suma y resta | |
| 5 |
<<
>>
|
Desplazamiento a izquierda y derecha bit a bit | |
| 6 |
<
<=
|
Para operadores relacionales < y ≤ respectivamente | |
>
>=
|
Para operadores relacionales > y ≥ respectivamente | ||
| 7 |
==
!=
|
Para relaciones = y ≠ respectivamente | |
| 8 |
&
|
AND bit a bit | |
| 9 |
^
|
XOR bit a bit (o exclusivo) | |
| 10 |
|
|
OR bit a bit (o inclusivo) | |
| 11 |
&&
|
AND lógico | |
| 12 |
||
|
OR lógico | |
| 13 |
?:
|
Condicional ternario [nota 3] | Derecha a izquierda |
| 14 [nota 4] |
=
|
Asignación simple | |
+=
-=
|
Asignación por suma y diferencia | ||
*=
/=
%=
|
Asignación por producto, cociente y resto | ||
<<=
>>=
|
Asignación por desplazamiento izquierdo y derecho bit a bit | ||
&=
^=
|=
|
Asignación por AND, XOR y OR bit a bit | ||
| 15 |
,
|
Coma | Izquierda a derecha |
-
↑
El operando del prefijo
++y--no puede ser una conversión 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 de tipo: la expresión sizeof ( int ) * p se interpreta inequívocamente como ( sizeof ( int ) ) * p , pero no como sizeof ( ( int ) * p ) . -
↑
La expresión en el medio del operador condicional (entre
?y:) se analiza como si estuviera entre paréntesis: se ignora su precedencia relativa a?:. - ↑ Los operandos izquierdos de los operadores de asignación deben ser expresiones unarias (nivel-2 no 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 = d es una expresión que no puede analizarse debido a esta regla. Sin embargo, muchos compiladores ignoran esta regla y la analizan como e = ( ( ( 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 alguna fila se vinculará más estrechamente (como si estuviera entre paréntesis) a sus argumentos que cualquier operador que aparezca en una fila más abajo. 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
La precedencia y la asociatividad son independientes del orden de evaluación .
El estándar en sí no especifica niveles de precedencia. Estos se derivan de la gramática.
En C++, el operador condicional tiene la misma precedencia que los operadores de asignación, y los operadores de 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 para completitud: los operadores unarios prefijos siempre asocian de derecha a izquierda ( sizeof ++* p es sizeof ( ++ ( * p ) ) ) y los operadores unarios sufijos siempre 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 se agrupan con operadores unarios sufijos: a. b ++ se analiza como ( a. b ) ++ y no como a. ( b ++ ) .
Referencias
- 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 Expressions
Véase también
Orden de evaluación de los argumentos de operadores en tiempo de ejecución.
| Operadores comunes | ||||||
|---|---|---|---|---|---|---|
| asignación |
incremento
decremento |
aritméticos | lógicos | comparación |
acceso a
miembros |
otros |
|
a
=
b
|
++
a
|
+
a
|
!
a
|
a
==
b
|
a
[
b
]
|
a
(
...
)
|
|
Documentación de C++
para
Precedencia de operadores en C++
|