Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ТП лекции Раздел 4.doc
Скачиваний:
16
Добавлен:
28.09.2019
Размер:
2.56 Mб
Скачать

4.3.4. Выражения и операции.

Язык C++ сохраняет богатый набор операций языка С, из которых наибольший интерес представляют необычные операции присваивания: ++, +=, *=, /=, %=, <<=, >>=, &=, !=, ^=. Операции +, *, / одинаковы почти во всех языках программирования, поэтому не нуждаются в пояснениях. Вам, наверное, извест­но назначение логических операций. Для них в языке С используются следую­щие символы:

• || — логическое ИЛИ (OR);

• && — логическое И (AND);

• ! — логическое НЕ (NOT).

Операции ++ и -- являются унарными (применяются к одному операнду) Все остальные из перечисленных — бинарные (требуют двух операндов). Смысл введения этих операций состоит в сокращении записи, оптимизации исполняемого кода и, что очень важно, повышении надежности. Операторы i++; и ++i; по смыслу (но не по реализации) эквивалентны оператору i=i+l;. Оператор i--; (так же, как и --i;) эквивалентен оператору i=i-l;. Различают две модификации операции приращения (increment) ++ и операции уменьшения (decrement) --. Например, рассмотрим фрагмент программы: int i=0, j=0; j=i++; i=++j:. Чему будут равны значения переменных i, j в конце фрагмента? Так как в выражении i++ использована постфиксная модификация операции, то сначала произойдет присвоение значения 1 (то есть нуля) переменной j, потом приращение нере­менной i, значение которой увеличится и станет равным 1. В следующем опера­торе фрагмента (i=++j;) использована префиксная модификация операции. По­этому сначала произойдет приращение значения j, которое станет 1, затем присвоение этого значения переменной i. Если выражение, содержащее опера­цию ++ или --, сложное, то результат может быть неожиданным.

Оператор i+=6; эквивалентен оператору i=i+6;. Аналогичные соответствия справедливы для всех остальных перечисленных бинарных операций. Рассмот­рим оператор a[j]*=c[j]*y[i];. Oн равносилен a[j]=a[j]*c[j]*y[i];, и это не про­сто проявление лаконичности, характерной для языка С. Здесь демонстрируется средство повышения надежности кода, так как исключается сама возможность совершить трудно обнаруживаемую ошибку вида a[j] = а[i] + c[j] * у[i];. Часто идентификаторы i и j имеют сходный смысл, кроме того, они похожи по написанию и их легко спутать. Кроме повышения надежности наблюдается су­щественная экономия усилий при использовании длинных идентификаторов (которые, как нас убеждают специалисты, следует использовать), Например, при вводе выражения:

PersonalIncomelncreaseRate +=

SummuryIncrease(Income)/Persons;

Операция % позволяет вычислить остаток от деления. Например, результа­том выражения 8%3 будет 2, выражение -8%3 даст -2, выражение 8%-3 даст 2, а -8%-3==-2.

Операция == означает логическую операцию проверки равенства, а не операцию присвоения. Проверяется равенство левого операнда правому. Результатом этой операции будет либо целая единица (аналог true), если операнды равны, либо целый ноль (false), если операнды различны. Другие операции отношения — это: <= («мень­ше или равно»), >= («больше или равно»), != («не равно»). Если равенство ис­тинно, то значение всего выражения (8%З==2) есть единица, если нет, то ноль. Рассмотрим операторы int а=8;, а%=2;. Они эквивалентны int a=8;, а=а%2;. После выполнения содержимое переменной а будет равно 0. Другой пример — после­довательность операторов int i=31;, while(i%=2): задает бесконечный цикл, так как условие продолжения цикла (и значение 1 после первого захода в цикл и далее) всегда равно единице.

Операции << и >> означают сдвиг влево и вправо на указанное во втором операнде число разрядов. Например, int i=64; i>>=4; эквивалентно по результа­ту Int i=64; i/=16;. После выполнения любого из этих фрагментов переменная 1 будет содержать число 4. Реализация первого фрагмента работает быстрее. По­этому профессионалы часто заменяют деление целых чисел сдвигами. Следует запомнить, что сдвиг влево переменной var одного из целых типов устанавлива­ет правые освобождающиеся биты в ноль, сдвиг вправо устанавливает левые биты либо и ноль, либо в единицу. Если сдвигается переменная типа unsigned, то — в ноль, если int, то левые биты заполняются копией знакового разряда, то есть единицей при var<0 или нулем при var>=0. Если второй операнд операции сдви­га отрицателен, то результат не определен.

Операции &, |, ^ являются поразрядными, побитовыми (bitwise) и носят на­звания: И, ИЛИ, исключающее ИЛИ (XOR, сложение по модулю 2)