Historia de la pregunta
La prioridad de los operadores fue introducida en C para controlar el orden de las evaluaciones en expresiones matemáticas y lógicas. A pesar de que los operadores matemáticos tienen una prioridad históricamente esperada (como en álgebra), la aparición de muchos operadores nuevos (lógicos, a nivel de bits, de asignación, etc.) ha complicado la situación. Para reducir la probabilidad de errores y aumentar la legibilidad, se creó una lista oficial de prioridades y asociatividad de los operadores.
Problema
Debido al mayor número de operadores y su diferente naturaleza (aritméticos, comparativos, de asignación, lógicos, indexación), surgen ambigüedades al componer expresiones complejas. Una comprensión incorrecta del orden de su aplicación conduce a errores lógicos y errores a veces no evidentes, especialmente al combinar operadores a nivel de bits y lógicos, punteros, incrementos y el operador ternario.
Solución
Ejemplo de código:
#include <stdio.h> int main() { int a = 1, b = 2, c = 3, d; d = a + b * c; // b*c se ejecuta primero: d = 1 + (2*3) = 7 printf("%d\n", d); d = a + b << 1; // a + b = 3, luego 3 << 1 (6) printf("%d\n", d); d = a < b ? a++ : b++; printf("%d\n", d); // a < b es verdadero => d = a (1), a se incrementará después }
Características clave:
¿Qué resultado da la expresión x = y > z ? y : z; si se olvidan los paréntesis?
Respuesta: El operador ternario ?: tiene una prioridad más baja que >. Primero se evalúa (y > z), y luego se elige entre y y z. Pero si se combina con la asignación, pueden ocurrir efectos inesperados. Es mejor usar siempre paréntesis x = (y > z) ? y : z;.
*¿Qué resultado da la expresión p++ y por qué?
Respuesta: El operador de post-incremento (++) tiene una prioridad más alta que la desreferencia (*), por lo que *p++ se convierte en *(p++): primero se utiliza p y se incrementa, solo después se desreferencia, lo que puede diferir de *++p (desreferencia después del incremento).
¿Por qué la expresión a & b == c no funciona como se espera?
Respuesta: El operador == tiene una prioridad más alta que &, por lo que la expresión se analiza como a & (b == c), y no como (a & b) == c, lo que puede dar un resultado no esperado. Para la lógica deseada, es necesario usar paréntesis.
if ((a & b) == c) { ... }
Caso negativo
Al optimizar el código, el programador combinó varios operadores sin paréntesis: if( mask & flag == 0 ) ..., como resultado la lógica de verificación no funcionaba correctamente y causó un fallo en el sistema.
Pros:
Contras:
Caso positivo
Uso de agrupamiento explícito: if( (mask & flag) == 0 ) ..., la lógica es transparente, fácil de cambiar los flags.
Pros:
Contras: