f() + g() * h() + j()

• Приоритет гарантирует умножение результатов вызова функций g() и h().

• Порядок гарантирует добавление результата вызова функции f() к произведению g() и h(), а также добавление результата сложения к результату вызова функции j().

• Однако нет никаких гарантий относительно порядка вызова этих функций.

Если функции f(), g(), h() и j() являются независимыми и не влияют на состояние тех же объектов или выполняют ввод и вывод, то порядок их вызова несуществен. Но если любые из этих функций действительно воздействуют на тот же объект, то выражение ошибочно, а его поведение непредсказуемо.

Упражнения раздела 4.1.3

Упражнение 4.3. Порядок вычисления большинства парных операторов оставляется неопределенным, чтобы предоставить компилятору возможность для оптимизации. Эта стратегия является компромиссом между созданием эффективного кода и потенциальными проблемами в использовании языка программистом. Полагаете этот компромисс приемлемым? Кто-то да, кто- то нет.

Совет. Манипулирование составными выражениями

При написании составных выражений могут пригодиться два эмпирических правила.

1. В сомнительных случаях заключайте выражения в круглые скобки, чтобы явно сгруппировать операнды в соответствии с логикой программы.

2. При изменении значения операнда не используйте этот операнд в другом месте того же оператора.

Важнейшим исключением из второго правила является случай, когда часть выражения, изменяющая операнд, сама является операндом другой части выражения. Например, в выражении *++iter инкремент изменяет значение итератора iter, а измененное значение используется как операнд оператора *. В этом и подобных выражениях порядок обработки операндов не является проблемным. Но в больших выражениях те части, которые изменяют операнд, должны обрабатываться в первую очередь. Такой подход не создает никаких проблем и применяется достаточно часто.

<p>4.2. Арифметические операторы</p>

Таблица 4.1. Арифметические операторы

(левосторонний порядок)

ОператорДействиеПрименение
+Унарный плюс+ выражение
-Унарный минус- выражение
*Умножениевыражение * выражение
/Делениевыражение / выражение
%Остатоквыражение % выражение
+Сложениевыражение + выражение
-Вычитаниевыражение - выражение

В табл. 4.1 (и таблицах операторов последующих разделов) операторы сгруппированы по приоритету. Унарные арифметические операторы имеют более высокий приоритет, чем операторы умножения и деления, которые в свою очередь имеют более высокий приоритет, чем парные операторы вычитания и сложения. Операторы с более высоким приоритетом группируются перед операторами с более низким приоритетом. Все эти операторы имеют левосторонний порядок, т.е. при равенстве приоритетов они группируются слева направо.

Если не указано иное, то арифметические операторы могут быть применены к любому арифметическому типу (см. раздел 2.1.1) или любому типу, который может быть преобразован в арифметический тип. Операнды и результаты этих операторов являются r-значениями. Как упоминается в разделе 4.11, в ходе вычисления операторов их операнды малых целочисленных типов преобразуются в больший целочисленный тип и все операнды могут быть преобразованы в общий тип.

Унарные операторы плюс и минус могут быть также применены к указателям. Использование парных операторов + и - с указателями рассматривалось в разделе 3.5.3. Будучи примененным к указателю или арифметическому значению, унарный плюс возвращает (возможно, преобразованную) копию значения своего операнда.

Унарный оператор минус возвращает отрицательную копию (возможно, преобразованную) значения своего операнда.

int i = 1024;

int k = -i;   // i равно -1024

bool b = true;

bool b2 = -b; // b2 равно true!

Перейти на страницу:

Похожие книги