Язык программирования C++ для профессионалов

       

Порядок вычислений


Порядок вычисления подвыражений, входящих в выражение, не всегда определен. Например:

int i = 1; v[i] = i++;

Здесь выражение может вычисляться или как v[1]=1, или как v[2]=1. Если нет ограничений на порядок вычисления подвыражений, то транслятор получает возможность создавать более оптимальный код. Транслятору следовало бы предупреждать о двусмысленных выражениях, но к сожалению большинство из них не делает этого.

Для операций

&& || ,

гарантируется, что их левый операнд вычисляется раньше правого операнда. Например, в выражении b=(a=2,a+1) b присвоится значение 3. Отметим, что операция запятая отличается по смыслу от той запятой, которая используется для разделения параметров при вызове функций. Пусть есть выражения:

f1(v[i],i++); // два параметра f2( (v[i],i++) ) // один параметр

Вызов функции f1 происходит с двумя параметрами: v[i] и i++, но порядок вычисления выражений параметров неопределен. Зависимость вычисления значений фактических параметров от порядка вычислений - далеко не лучший стиль программирования. К тому же программа становится непереносимой. Вызов f2 происходит с одним параметром, являющимся выражением, содержащим операцию запятая: (v[i], i++). Оно эквивалентно i++.

Скобки могут принудительно задать порядок вычисления. Например, a*(b/c) может вычисляться как (a*b)/c (если только пользователь видит в этом какое-то различие). Заметим, что для значений с плавающей точкой результаты вычисления выражений a*(b/c) и (a*b)/c могут различаться весьма значительно.



Содержание раздела