Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
A.doc
Скачиваний:
36
Добавлен:
09.04.2015
Размер:
5.6 Mб
Скачать

70 Глава 2

Операции инкремента и декремента

Теперь я представлю несколько необычные арифметические операции, называе- мые операциями инкремента и декремента, и уверен, что вы сочтете их весьма по- лезными по мере серьезного применения С++. Это унарные операции, которые слу- жат для увеличения или уменьшения значения, хранимого в переменной целого типа. Например, если предположить, что переменная count имеет тип int, то следующие три оператора дадут один и тот же эффект:

Каждый из них увеличивает переменную count на 1. Последняя форма, использу- ющая операцию инкремента — вне всяких сомнений, самая краткая.

Операция инкремента не только изменяет значение переменной, к которой он применен, но также сама возвращает значение. Таким образом, используя операцию инкремента для увеличения значения переменной, ее также можно сделать частью более сложного выражения. Если увеличивать переменную, используя операцию ++, как в ++count, в составе другого выражения, то действие операции будет заключать- ся в том, что сначала увеличится значение переменной, а затем это новое значение бу- дет использовано в выражении. Например, предположим, что count имеет значение 5, и вы определили переменную total типа int. Предположим, что вы записываете следующий оператор:

В результате это увеличит count до б, и к этому значению будет прибавлено 6, по- этому total получит значение 12.

До сих пор мы помещали операцию инкремента ++ перед переменной, к которой она применялся. Это называется префиксной формой операции инкремента. Однако эта операция также имеет постфиксную форму, когда операция ставится после пере- менной, к которой она применяется. В результате получается несколько другой эффект. Переменная, к которой применена операция, увеличивается только после того, как ее значение будет использовано в объемлющем контексте. Например, сбросьте значение count снова до 5 и перепишите предыдущий оператор следующим образом:

В результате total получит значение 11, потому что начальное значение count используется для вычисления всего выражения до того, как count увеличится на 1 операцией инкремента. Этот оператор эквивалентен следующим двум:

Но когда у вас есть такое выражение, как а+++b, или даже а+++b, то не совсем очевидно, что это должно означать, и что будет делать компилятор. На самом деле это одно и то же, но во втором случае вы на самом деле могли иметь в виду а + ++Ь, что не одно и то же.

Точно те же правила, о которых я рассказал относительно операции инкремента, применимы к операции декремента —. Например, если count имеет начальное зна- чение 5, то оператор:

в результате присвоит total значение 10, в то время как:

Данные, переменные и вычисления 71

установит в total значение 11. Обе операции обычно применяются к целым, в част- ности, в контексте циклов, как будет показано в главе 3. Позже в других главах вы узнаете, что они также могут применяться и к другим типам данных С++, например, к переменным, хранящим адреса памяти.

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

Описание полученных результатов

Если вы скомпилируете и запустите эту программу, то получите следующий вы- вод:

Это не требует пояснений. Переменная num4 принимает значение последнего из трех присваиваний, а присваиваемым значением является значение, которое полу- чает его левая часть. Скобки в присваивании num4 важны. Вы можете попробовать выполнить этот пример без них, чтобы увидеть, что получится. Без скобок первое выражение, отделенное запятыми, станет таким:

То есть, num4 будет присвоено значение 10.

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

Эффект от этого оператора присваивания будет выражен в увеличении значений переменных numl, num2 и num3 на 1, а также в присваивании num4 значения послед- него выражения, которое в данном случае будет равно 101. Этот пример нацелен на то, чтобы проиллюстрировать эффект от операции запятой, но не является приме- ром того, как следует писать хороший код.

Последовательность вычислений

До сих пор я не говорил о том, как повлиять на последовательность вычислений, участвующих в выражении. В основном это согласуется с тем, что вы изучали в шко- ле, когда знакомились с основными арифметическими операциями, но в С++ присут- ствует множество других операций. Чтобы понять, что произойдет с ними, нужно рассмотреть механизм, используемый С++ для определения этой последовательности. Это то, что называется приоритетом операций.

Порядок выполнения операций

Порядок выполнения операций упорядочивает операции в порядке приоритетов. В любом выражении операции с более высоким приоритетом всегда выполняются первыми, за ними выполняются операции со следующим по возрастанию приорите- том и так далее, вплоть до тех, чей приоритет самый низкий. Порядок выполнения операций С++ представлен в табл. 2.4.

Данные, переменные и вычисления 73

Операции с наивысшим приоритетом находятся в верхней части таблицы. Все операции, которые указаны в одной ячейке таблицы, имеют одинаковый приори- тет. Если в выражении нет скобок, операции с равным приоритетом выполняются в последовательности, определяемой их ассоциативностью. То есть, если ассоци- ативность "левая", то самая левая операция в выражении выполняется первой, за- тем последовательно выполняются операции всего выражения — слева направо. Это значит, что выражение вродевыполняется, как записано, то есть как

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

Вы всегда можете изменить приоритеты операций в выражении с помощью скобок. Пос- кольку в С++ очень много операций, иногда бывает затруднительно понять, каким должен порядок вычисления сложного выражения. Поэтому хорошей идеей будет применять скоб- ки, чтобы обрести уверенность. Дополнительная выгода от них проявляется в том, что это часто облегчает чтение кода.

Типы переменных и приведения

Вычисления в С++ могут выполняться только между однотипными значениями. Когда вы пишете выражение, включающее переменные или константы разных типов, то для каждой выполняемой операции компилятор должен выполнить преобразова- ние типа одного операнда к типу другого. Процесс преобразования типов называется приведением. Например, если вы хотите прибавить значение типа double к значе- нию целочисленного типа, то целочисленное значение сначала преобразовывается в double, после чего выполняется сложение. Конечно, сама переменная, содержащая исходное значение, не изменяется. Компилятор сохраняет преобразованное значе- ние во временной памяти, которая теряется по завершении вычислений.

Выбор операнда, подлежащего преобразованию в любой операции, регулируется строгими правилами. Любое выражение, которое должно быть вычислено, разбива- ется на серии операций с двумя операндами. Например, выражение 2*3-4+5 состоит из следующих серий: 2 * 3 в результате дает б, затем 6-4, которая в ре- зультате дает 2 и, наконец, 2 + 5, результат которого — 7. Таким образом, правила приведения операндов необходимы только для принятия решений относительно пар операндов. Поэтому для любой пары операндов разного типа проверяются описан- ные ниже правила, в том порядке, как они записаны. Если правило применимо к кон- кретной паре, оно используется.

Правила приведения операндов

  1. Если любой из операндов имеет тип long double, то второй преобразуется в тип long double.

  2. Если любой из операндов имеет тип double, то второй преобразуется в тип double.

  3. Если любой из операндов имеет тип float, то второй преобразуется в тип float.