Освой самостоятельно С++ за 21 день.
Шрифт:
В простом выражении вариант использования не имеет большого значения, но в сложном при выполнении приращения одной переменной с последующим присваиванием результата другой переменной это весьма существенно. Префиксный оператор вычисляется до присваивания, а постфиксный — после.
Семантика префиксного оператора следующая: инкрементируем значение, а затем считываем его. Семантика постфиксного оператора иная: считываем значение, а затем декрементируем оригинал.
На первый взгляд это может выглядеть несколько запутанным, но примеры легко проясняют
int а = ++x;
то тем самым велели компилятору инкрементировать переменную x (сделав ее равной 6), а затем присвоить это значение переменной а. Следовательно, значение переменной а теперь равно 6 и значение переменной x тоже равно 6. Если же, после этого вы записали
int b = x++;
то тем самым велели компилятору присвоить переменной b текущее значение переменной x (6), а затем вернуться назад к переменной x и инкрементировать ее. В этом случае значение переменной b равно 6, но значение переменной x уже равно 7. В листинге 4.4 продемонстрировано использование обоих типов операторов инкремента и декремента.
Листинг 4.4. Примеры использования префиксных и постфиксных операторов
1: // Листинг 4.4. Демонстрирует использование
2: // префиксных и постфиксных операторов
3: // инкремента и декремента
4: #include <iostream.h>
5: int main
6: {
7: int myAge = 39; // инициализируем две целочисленные переменные
8: int yourAge = 39;
9: cout << "I am: " << myAge << " years old.\n";
10: cout << "You are: " << yourAge << " years old\n";
11: myAge++; // постфиксный инкремент
12: ++yourAge; // префиксный инкремент
13: cout << "One year passes...\n";
14: cout << "I am: " << myAge << " years old.\n";
15: cout << "You are: " << yourAge << " years old\n";
16: cout << "Another year passes\n";
17: cout << "I am: " << myAge++ << " years old.\n";
18: cout << "You are: " << ++yourAge << " years old\n";
19: cout << "Let's print it again.\n";
20: cout << "I am: " << myAge << " years old.\n";
21: cout << "You are: " << yourAge << " years old\n";
22: return 0;
23: }
Результат:
I am 39 years old
You are 39 years old
One year passes
I am 40 years old
You are 40 years old
Another year passes
I am 40 years old
You are 41 years old
Let's print it again
I am 41 years old
You are 41 years old
Анализ: В строках 7 и 8 объявляются две целочисленные переменные и каждая из них инициализируется значением 39. Значения этих переменных выводятся в строках 9 и 10.
В строке 11 инкрементируется переменная myAge с помощью постфиксного оператора инкремента, а в строке 12 инкрементируется переменная yourAge с помощью префиксного оператора инкремента. Результаты этих операций выводятся в строках 14 и 15; как видите, они идентичны (обоим участникам нашего эксперимента по 40 лет).
В строке 17 инкрементируется переменная myAge (также с помощью постфиксного оператора инкремента), являясь при этом частью выражения вывода на экран. Поскольку здесь используется постфиксная форма оператора, то инкремент выполняется после операции вывода, поэтому снова было выведено значение 40. Затем (для сравнения с постфиксным вариантом) в строке 18 инкрементируется переменная yourAge с использованием префиксного оператора инкремента. Эта операция выполняется перед выводом на экран, поэтому отображаемое значение равно числу 41.
Наконец, в строках 20 и 21 эти же значения выводятся снова. Поскольку приращения больше не выполнялись, значение переменной myAge сейчас равно 41, как и значение переменной yourAge (все правильно: стареем мы все с одинаковой скоростью!).
Приоритеты операторов
Какое действие — сложение или умножение — выполняется первым в сложном выражении, например в таком, как это:
X = 5 + 3 * 8;
Если первым выполняется сложение, то ответ равен 8 * 8, или 64. Если же первым выполняется умножение, то ответ равен 5 + 24, или 29.
Каждый оператор имеет значение приоритета (полный список этих значений приведен в приложении А). Умножение имеет более высокий приоритет, чем сложение, поэтому значение этого "спорного" выражения равно 29.
Если два математических оператора имеют один и тот же приоритет, то они выполняются в порядке следования слева направо. Значит, в выражении
X = 5 + 3 + 8 * 9 + 6 * 4;
сначала вычисляется умножение, причем слева направо: 8*9 = 72 и 6*4 = 24. Теперь то же выражение выглядит проще:
x = 5 + 3 + 72 + 24;
Затем выполняем сложение, тоже слева направо: 5 + 3 = 8; 8 + 72 = 80; 80 + 24 = 104. Однако будьте осторожны — не все операторы придерживаются этого порядка выполнения. Например, операторы присваивания вычисляются справа налево! Но что же делать, если установленный порядок приоритетов не отвечает вашим намерениям? Рассмотрим выражение:
TotalSeconds = NumMinutesToThink + NumMinutesToType * 60
Предположим, что в этом выражении вы не хотите умножать значение переменной NumMinutesToType на число 60, а затем складывать результат со значением переменной NumMinutesToThink. Вам нужно сначала сложить значения двух переменных, чтобы получить общее число минут, а затем умножить это число на 60, получив тем самым общее количество секунд.