Namespaces
Variants

Precedencia de operadores en C

De es.cppreference.net

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
  1. 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.
  2. El operando de sizeof no puede ser una conversión explícita 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 medio del operador condicional (entre ? y :) se analiza como si estuviera entre paréntesis: su precedencia relativa a ?: se ignora.
  4. 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 = d es una expresión que no se puede analizar 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 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

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++