Бьерн Страуструп - Язык программирования С++. Главы 2-4
Страница 40. Порядок вычислений


 

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

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

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

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

             &&    ||   ,

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

            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)/ могут
различаться весьма значительно.

 
« Предыдущая статья   Следующая статья »