Опубликован: 10.10.2006 | Доступ: свободный | Студентов: 6440 / 527 | Оценка: 4.26 / 3.88 | Длительность: 31:30:00
Лекция 3:

Выражения и операторы

3.2 Сводка операций

Здесь приводится краткая сводка операций и несколько примеров. Каждая операция сопровождается одним или несколькими характерными для нее именами и примером ее использования. В этих примерах class_name обозначает имя класса, member - имя члена, object - выражение, задающее объект класса, pointer - выражение, задающее указатель, expr - просто выражение, а lvalue (адрес) - выражение, обозначающее не являющийся константой объект. Обозначение (type) задает имя типа в общем виде (с возможным добавлением *, () и т.д.). Если оно указано без скобок, существуют ограничения.

Порядок применения унарных операций и операций присваивания "справа налево", а всех остальных операций - "слева направо". То есть, a=b=c означает a=(b=c), a+b+c означает (a+b)+c, и *p++ означает *(p++), а не (*p)++.

____________________________________________________________
   Операции С++
============================================================
::    Разрешение области видимости   class_name :: member
::    Глобальное  :: name
____________________________________________________________
.Выбор члена object . member
-> Выбор членаpointer -> member
[] Индексирование pointer [ expr ]
() Вызов функции expr ( expr_list )
() Структурное значениеtype ( expr_list )
sizeof   Размер объекта sizeof expr
sizeof   Размер типа sizeof ( type )
____________________________________________________________
++ Постфиксный инкремент  lvalue ++
++ Префиксный инкремент++ lvalue
-- Постфиксный декремент  lvalue --
-- Префиксный декремент-- lvalue
~Дополнение  ~ expr
!Логическое НЕ ! expr
-Унарный минус - expr
+Унарный плюс+ expr
&Взятие адреса & lvalue
*Косвенность * expr
newСоздание (размещение)  new type
delete   Уничтожение (освобождение)     delete pointer
delete[] Уничтожение массива delete[] pointer
() Приведение(преобразование)типа ( type ) expr
____________________________________________________________
. *Выбор члена косвенный  object . pointer-to-member
->*Выбор члена косвенный  pointer -> pointer-to-member
____________________________________________________________
*Умножениеexpr * expr
/Деление  expr / expr
%Остаток  от деления expr % expr
____________________________________________________________
+Сложение (плюс)     expr + expr
-Вычитание (минус)   expr - expr
____________________________________________________________

Все операции таблицы, находящиеся между двумя ближайшими друг к другу горизонтальными чертами, имеют одинаковый приоритет. Приоритет операций уменьшается при движении "сверху вниз". Например, a+b*c означает a+(b*c), так как * имеет приоритет выше, чем +; а выражение a+b-c означает (a+b)-c, поскольку + и - имеют одинаковый приоритет, и операции + и - применяются "слева направо".

____________________________________________________________
 Операции  С++ (продолжение)
============================================================
<< Сдвиг влево  expr << expr
>> Сдвиг вправо expr >> expr
____________________________________________________________
<Меньше    expr < expr
<= Меньше или равно     expr <= expr
>Больше    expr > expr
>= Больше или равно     expr >= expr
____________________________________________________________
== Равно     expr == expr
!= Не равно  expr != expr
____________________________________________________________
&Поразрядное Иexpr & expr
____________________________________________________________
^Поразрядное исключающее ИЛИ     expr ^ expr
____________________________________________________________
|Поразрядное включающее ИЛИexpr | expr
____________________________________________________________
&& Логическое И expr && expr
____________________________________________________________
|| Логическое ИЛИ expr || expr
____________________________________________________________
? :Операция условия     expr? expr : expr
____________________________________________________________
=Простое присваивание lvalue = expr
*= Присваивание с умножением lvalue *= expr
/= Присваивание с делением lvalue /= expr
%= Присваивание с взятием  lvalue %= expr
 остатка от деления
+= Присваивание со сложением lvalue += expr
-= Присваивание с вычитанием lvalue -= expr
<<=Присваивание со сдвигом влево   lvalue <<= expr
>>=Присваивание со сдвигом вправо  lvalue >>= expr
&= Присваивание с поразрядным И    lvalue &= expr
|= Присваивание с поразряднымlvalue |= expr
 включающим ИЛИ
^= Присваивание с поразряднымlvalue ^= expr
 исключающим ИЛИ
____________________________________________________________
 Запятая (последовательность)     expr , expr
____________________________________________________________

3.2.1 Скобки

Синтаксис языка С++ перегружен скобками, и разнообразие их применений способно сбить с толку. Они выделяют фактические параметры при вызове функций, имена типов, задающих функции, а также служат для разрешения конфликтов между операциями с одинаковым приоритетом. К счастью, последнее встречается не слишком часто, поскольку приоритеты и порядок применения операций определены так, чтобы выражения вычислялись "естественным образом" (т.е. наиболее распространенным образом). Например, выражение

if (i<=0 || max<i)   // ...

означает следующее: "Если i меньше или равно нулю, или если max меньше i". То есть, оно эквивалентно

if ( (i<=0) || (max<i) )    // ...

но не эквивалентно допустимому, хотя и бессмысленному выражению

if (i <= (0||max) < i)    // ...

Тем не менее, если программист не уверен в указанных правилах, следует использовать скобки, причем некоторые предпочитают для надежности писать более длинные и менее элегантные выражения, как:

if ( (i<=0) || (max<i) )   // ...

При усложнении подвыражений скобки используются чаще. Не надо, однако, забывать, что сложные выражения являются источником ошибок. Поэтому, если у вас появится ощущение, что в этом выражении нужны скобки, лучше разбейте его на части и введите дополнительную переменную. Бывают случаи, когда приоритеты операций не приводят к "естественному" порядку вычислений. Например, в выражении

if (i&mask == 0)    // ловушка! & применяется после ==

не происходит маскирование i (i&mask), а затем проверка результата на 0. Поскольку у == приоритет выше, чем у &, это выражение эквивалентно i&(mask==0). В этом случае скобки играют важную роль:

if ((i&mask) == 0) // ...

Имеет смысл привести еще одно выражение, которое вычисляется совсем не так, как мог бы ожидать неискушенный пользователь:

if (0 <= a <= 99) // ...

Оно допустимо, но интерпретируется как (0<=a)<=99, и результат первого сравнения равен или 0, или 1, но не значению a (если, конечно, a не есть 1). Проверить, попадает ли a в диапазон 0...99, можно так:

if (0<=a && a<=99) // ...

Среди новичков распространена ошибка, когда в условии вместо == (равно) используют = (присвоить):

if (a = 7)   // ошибка: присваивание константы в условии
 // ...

Она вполне объяснима, поскольку в большинстве языков "=" означает "равно". Для транслятора не составит труда сообщать об ошибках подобного рода.

Федор Антонов
Федор Антонов

Здравствуйте!

Записался на ваш курс, но не понимаю как произвести оплату.

Надо ли писать заявление и, если да, то куда отправлять?

как я получу диплом о профессиональной переподготовке?

Илья Ардов
Илья Ардов

Добрый день!

Я записан на программу. Куда высылать договор и диплом?