Namespaces
Variants

C Operator Precedence

From cppreference.net

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
  1. 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.
  2. El operando de sizeof no 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 ) .
  3. 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 ?: .
  4. 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 + = b
a - = b
a * = b
a / = b
a % = b
a & = b
a | = b
a ^ = b
a <<= b
a >>= b

++ a
-- a
a ++
a --

+ a
- a
a + b
a - b
a * b
a / b
a % b
~a
a & b
a | b
a ^ b
a << b
a >> b

! a
a && b
a || b

a == b
a ! = b
a < b
a > b
a <= b
a >= b

a [ b ]
* a
& a
a - > b
a. b

a ( ... )
a, b
( type ) a
a ? b : c
sizeof


_Alignof
(desde C11)
(hasta C23)

alignof
(desde C23)

Documentación de C++ para Precedencia de operadores en C++