Группировка с помощью круглых скобок
В предыдущих разделах мы уже не раз видели, что некоторые выражения могут вызывать неожиданные результаты из-за приоритетов операций. Для явного изменения порядка расчета необходимо пользоваться круглыми скобками. Заключенная в них часть выражения получает повышенный приоритет по сравнение с окружением, невзирая на приоритеты по умолчанию. Пары скобок могут быть вложенными, однако делать уровень вложенности больше 3-4 не рекомендуется. Слишком сложные выражения лучше разделить на несколько отдельных.
В скрипте ExprParentheses.mq5 показана эволюция расстановки скобок в одном выражении. Исходный замысел для него в том, чтобы взвести бит в переменной flags с помощью операции сдвига влево '<<'. Номер бита берется из переменной offset, если она не нулевая, или равным 1 в противном случае (напомним, нумерация идет с нуля). Затем полученное значение умножается на coefficient. Прикладного смысла в этом примере искать не стоит, но на практике встречаются и более хитрые конструкции.
int offset = 8;
|
Первый вариант без скобок кажется подозрительным даже компилятору. Тот выдает уже знакомое нам предупреждение "выражение не является логическим" ("expression not boolean"). Дело в том, что минимальным приоритетом из всех операторов здесь обладает тернарный условный. Из-за этого вся левая часть до знака '?' считается его условием. Внутри условия вычисления идут в следующем порядке: умножение, побитовый сдвиг, сравнение "больше", побитовое ИЛИ, в результате чего получается целое число. Оно, конечно, может использоваться как true или false, но такие намерения желательно всегда "сообщать" компилятору с помощью явного приведения типов. В его отсутствии компилятор считает выражение подозрительным, и не зря. Результат первого расчета равен 8. Он неверный.
Добавим скобки вокруг тернарного оператора. Предупреждение компилятора пропадет. Однако выражение по-прежнему считается неправильно. Поскольку приоритет умножения выше побитового ИЛИ, переменные coefficient и flags перемножаются до того, как применяется битовая маска, получаемая сдвигом влево. Результат равен 256.
Наконец, добавив еще одни скобки, мы получим правильный результат 2560.