Шрифт:
Отличное от void выражение любого типа, которое идентифицирует объект данных, называется lvalue (1-значением). Если ему может быть присвоено зна-чение, оно называется модифицируемым (изменяемым) lvalue.
Модифицируемые lvalue-выражения обязательны в определенных местах. Выражение в левой части оператора присваивания должно быть модифициру-емым lvalue. Унарный адресный оператор можно применить только к модифицируемом lvalue или к имени функции. И, наконец, операторы наращивания и уменьшения на 1 (инкремента и декремента) можно применять только к модифицируемым lvalue-выражениям. Сводка операторов Objective-C
В таблице В.4 приводится сводка различных операторов языка Objcctivc-C. Эти операторы приводятся в порядке убывания старшинства, и операторы, сгруп-пированные вместе, имеют одинаковый уровень старшинства.
Рассмотрим на следующем примере, как использовать таблицу В.4. b | с & d * е
Оператор умножения имеет более высокий приоритет, чем побитовые операторы OR (|) и AND (&), поскольку он находится выше обоих операторов в таблице В.4. Аналогичным образом, побитовый оператор AND имеет более высокий приоритет, чем побитовый оператор OR, поскольку первый находится в этой т аблице выше, чем второй. Поэтому данное выражение вычисляется в следующем порядке. b | ( с & ( d * е ))
Теперь рассмотрим следующее выражение, b % с * d
Табл. В.4. Сводка операторов Objective-C Оператор Описание Ассоциативность 0 Вызов функции Слева направо [] Ссылка на элемент массива или выражение с сообщением - || - -> Указатель ссылки на компонент структуры - || - . Ссылка на компонент структуры или вызов метода - || - - Унарный минус Справа налево + Унарный плюс - || - ++ Оператор инкремента - || - -- Оператор декремента - || - ! Логическое отрицание - || - ~ Дополнение до нуля - || - * Ссылка на указатель (косвенным образом) - || - & Адрес - || - sizeof Размер объекта - || - (тип) Приведение типа (преобразование) - || - * Умножение Слева направо / Деление - || - % Взятие по модулю - || - + Сложение - || - - Вычитание - || - << Левый сдвиг - || - >> Правый сдвиг - || - < Меньше - || - <= Меньше или равно - || - > Больше - || - >= Больше или равно - || - == Равенство - || - != Неравенство - || - & Побитовый AND - || - ^ Побитовый XOR - || - | Побитовый OR - || - && Логический AND - || - || Логический OR - || - ?: Условный Справа налево = *= /= %= += -= & = ^= |= <<= >>= Операторы присваивания - || - , Оператор «запятая» - || -
Поскольку операторы взятия по модулю и умножения включены в одну группу таблицы В.4, они имеют одинаковый уровень старшинства. Эти операторы выполняются слева направо. Следующее выражение будет вычисляться как ( b % с ) * d
В следующем примере выражение ++а->b
будет вычисляться как ++(а->b)
поскольку оператор -> имеет более высокий приоритет, чем оператор ++.
И, наконец, поскольку операторы присваивания группируются справа на-лево, оператор а = b = 0;
будет вычисляться как а = (Ь = 0);
в результате чего переменным а и b будет присвоено значение 0. В случае выра-жения x[i] + ++i
не определено, в каком порядке компилятор будет выполнять оценку, — начиная с левой части оператора «плюс» или начиная с правой части. В данном случае порядок вычислений влияет на результат, поскольку значение i может быть увеличено до того, как будет вычисляться x[i],
В этом выражении порядок вычислений также не определен: x[i] = ++i
В этой ситуации не определено, когда значение i будет использовано как индекс для х, — до приращения i или после приращения.
Порядок вычисления аргументов функции или метода тоже не определен. Поэтому при вызове функции f(i, ++i);
или в выражении с сообщением [myFract setTo: i over: ++i];
возможно, что сначала будет выполнено приращение i, в результате чего функ-ции или методу будут переданы два одинаковых значения.
Язык Objectivc-C гарантирует, что операторы && и || будут вычисляться слева направо. Поэтому в случае && гарантируется, что второй операнд нс будет оцениваться, если первый равен 0; в случае || гарантируется, что второй операнд не будет оцениваться, если первый не равен 0. Этот факт необходимо учитывать при формировании таких выражений, как if ( dataFlag || [myData checkData])
поскольку в этом случае checkData вызывается, только если значение dataFlag равно 0. Еще один пример. Если в определении объект-массив а содержит п элементов, то оператор, который начинается с if (index >= 0 && index < n && ([a objectAtlndex: index] == 0))
является ссылкой на элемент этого массива, только если index является допустимым индексом в этом массиве. Константные выражения
Константное выражение — это выражение, каждый из членов которого является константным значением. Константные выражения необходимы в следующих ситуациях.
Как значение после case в операторе switch.
Для указания размера массива.
Чтобы присвоить значение идентификатору перечисления.
Чтобы указать размер битового поля в определении структуры.
Чтобы присвоить начальные значения внешним или статическим переменным.
Чтобы задать начальные значения для глобальных переменных.
Как выражение после #if в препроцессорном операторе #if. В первых четырех случаях константное выражение должно состоять из це-лых констант, символьных констант, перечисляемых констант и выражений sizeof. Могут использоваться только арифметические операторы, побитовые операторы, операторы отношения, оператор с условным выражением и опера-тор приведения тина (cast).