- Conceptos básicos
- Operaciones de asignación
- Operaciones aritméticas
- Incremento y decremento
- Operaciones de comparación
- Operaciones lógicas
- Operaciones a nivel de bits
- Operaciones de modificación
- Operador ternario condicional
- Coma
- Operadores especiales sizeof y typename
- Agrupación con paréntesis
- Prioridades de las operaciones
Agrupación con paréntesis
En las secciones anteriores hemos visto ya más de una vez que algunas expresiones pueden provocar resultados inesperados debido a las prioridades de las operaciones. Para cambiar de forma explícita el orden de cálculo debemos utilizar paréntesis. Parte de la expresión encerrada en ellos obtiene una prioridad más alta en comparación con el entorno, sin tener en cuenta las prioridades por defecto. Se pueden anidar pares de paréntesis, pero no se recomienda hacer más de 3-4 niveles de anidamiento: es mejor dividir las expresiones demasiado complejas en varias más sencillas.
El script ExprParentheses.mq5 muestra la evolución de la colocación de paréntesis dentro de una expresión. La intención inicial para ello es fijar el bit de la variable flags utilizando la operación de desplazamiento a la izquierda '<<'. El número de bit se toma de la variable offset si no es cero, o en caso contrario, como 1 (recuerde que la numeración empieza por cero). A continuación, el valor obtenido se multiplica por coefficient. No es necesario buscar ningún sentido práctico en este ejemplo. Sin embargo, también pueden darse estructuras más sofisticadas.
int offset = 8;
|
La primera versión, sin paréntesis, parece sospechosa incluso para el compilador. Emite un aviso que ya hemos visto: «expresión no booleana». La cuestión es que el operador condicional ternario tiene aquí la prioridad más baja de todos los operadores. Por esta razón, toda la parte izquierda situada delante de '?' se considera su condición. Dentro de la condición, los cálculos siguen el siguiente orden: multiplicación, desplazamiento de bits, comparación «más que» y OR a nivel de bits, que da como resultado un número entero. Por supuesto, se puede utilizar como true o false, pero se desea «comunicar» tales intenciones al compilador utilizando la conversión de tipos explícita. Si está ausente, el compilador considera que la expresión es sospechosa, y no en vano. El primer cálculo da como resultado 8. Esto es incorrecto.
Añadamos paréntesis en torno al operador ternario. El aviso del compilador desaparecerá. No obstante, la expresión sigue calculándose de forma errónea. Dado que la prioridad de la multiplicación es mayor que la de OR a nivel de bits, las variables coefficient y flags se multiplican antes de utilizar la máscara de bits, que se obtiene desplazando a la izquierda. El resultado es 256.
Finalmente, habiendo añadido otro par de paréntesis, obtendremos el resultado correcto: 2560.