Унарные операторы что это

Унарные операторы в Java

Уже завтра в OTUS скоро стартует новая профессиональная программа по подготовке к сертификации Oracle Java Programmer (OCAJP). Предлагаем вам посмотреть запись бесплатного Demo-урока «Типы данных Java: Идентификаторы и примитивы» и продолжаем публиковать серию статей Владислава Родина — руководителя группы разработки, преподавателя в МФТИ и foxminded.

Введение

Приоритет операторов

Оператор принимает на вход аргументы и возвращает некоторые значения. Выделяют унарные, бинарные и тернарные операторы. Например, !false — унарный, a + b — бинарный, а? : — является единственным оператором, принимающим на вход три аргумента.

Первое, что необходимо помнить, это приоритет выполнения операторов:

Работа с унарными операторами

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

Операторы смены знака и логической инверсии

Оператор логической инверсии ! применяется только к переменным типа boolean и превращает значение из true в false и наоборот. Например:

Оператор смены знака применяется только к числам и меняет знак на противоположный:

Java в отличии от того же C четко разделяет целочисленные типы данных и boolean, в связи с чем применение оператора смены знака к boolean либо же применение оператора логической инверсии приводят к ошибкам компиляции:

Операторы инкремента и декремента

Операторы инкремента ++ и декремента применяются к целочисленным переменным и обладают двумя вариациям: post-инкремент (декремент) и pre-инкремент (декремент), в коде i++ (i—) и ++i (—i) соответственно. Разница между вариациями в том, что ++i увеличивает переменную и возвращает новое значение, а i++ возвращает старое значение, а только затем увеличивает переменную. Разницу более наглядно можно увидеть в таком куске кода:

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

Что будет выведено в результате выполнения данной программы?

Проблема заключается в том, что x меняется несколько раз в одной строке.

Для решения таких задач можно разбирать выражение слева направо, подставляя в выражение то, что возвращают операторы, и фиксируя отдельно значение изменяемой переменной. Например, вот так:

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

Источник

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

Эта глава описывает выражения и операторы языка JavaScript, такие как операторы присваивания, сравнения, арифметические, битовые, логические, строчные, и различные специальные операторы.

Полный и детальный список операторов и выражений также доступен в этом руководстве.

Операторы

В JavaScript есть следующие типы операторов. Данный подраздел описывает каждый тип и содержит информацию об их приоритетах друг над другом.

В свою очередь унарная операция использует один операнд, перед или после оператора:

Операторы присваивания

Существуют также составные операторы присваивания, которые используются для сокращённого представления операций, описанных в следующей таблице:

Деструктуризация

Операторы сравнения

Замечание: (=>) не оператор, а нотация Стрелочных функций.

Арифметические операторы

Арифметические операторы (en-US) используют в качестве своих операндов числа (также литералы или переменные) и в качестве результата возвращают одно числовое значение. Стандартными арифметическими операторами являются сложение (+), вычитание (-), умножение (*), и деление (/). При работе с числами с плавающей точкой эти операторы работают аналогично их работе в большинстве других языках программирования (обратите внимание, что деление на ноль возвращает бесконечность Infinity ). Например:

Кроме того, JavaScript позволяет использовать следующие арифметические операторы, представленные в таблице:

Битовые (поразрядные) операторы

Битовые операторы (en-US) обрабатывают свои операнды как последовательности из 32 бит (нулей и единиц), а не как десятичные, шестнадцатеричные или восьмеричные числа. Например, десятичное число 9 имеет двоичное представление 1001. Битовые операторы выполняют операции над таким двоичным представлением, но результат возвращают как обычное числовое значение JavaScript.

Следующая таблица обобщает битовые операторы JavaScript.

Битовые операторы

a

ОператорИспользованиеОписание
Побитовое И (en-US)a & bВозвращает единицу в каждой битовой позиции, для которой соответствующие биты обеих операндов являются единицами.
Побитовое ИЛИ (en-US)a | bВозвращает единицу в каждой битовой позиции, для которой один из соответствующих битов или оба бита операндов являются единицами.
Исключающее ИЛИ (en-US)a ^ bВозвращает единицу в каждой битовой позиции, для которой только один из соответствующих битов операндов является единицей.
Побитовое НЕ (en-US)Заменяет биты операнда на противоположные.
Сдвиг влево (en-US)aСдвигает a в двоичном представлении на b бит влево, добавляя справа нули.
Сдвиг вправо с переносом знака (en-US)a >> bСдвигает a в двоичном представлении на b бит вправо, отбрасывая сдвигаемые биты.
Сдвиг вправо с заполнением нулями (en-US)a >>> bСдвигает a в двоичном представлении на b бит вправо, отбрасывая сдвигаемые биты и добавляя слева нули.

Битовые логические операторы

Основной смысл работы битовых логических операторов состоит в следующем:

Примеры работы битовых операторов

Обратите внимание, что все 32 бита преобразуются с использованием битового оператора НЕ, и что величины с наиболее значимым (самым левым) битом равным 1 представляют собой отрицательные числа (в представлении дополнения до двух).

Битовые операторы сдвига

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

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

Операторы сдвига перечислены в следующей таблице.

Логические операторы

Логические операторы (en-US) обычно используются с булевыми (логическими) значениями; при этом возвращаемое ими значение также является булевым. Однако операторы && и || фактически возвращают значение одного из операндов, поэтому, если эти операторы используются с небулевыми величинами, то возвращаемая ими величина также может быть не булевой. Логические операторы описаны в следующей таблице.

Примерами выражений, которые могут быть преобразованы в false являются: null, 0, NaN, пустая строка («») или undefined.

Следующий код демонстрирует примеры использования оператора && (логическое И).

Следующий код демонстрирует примеры использования оператора || (логическое ИЛИ).

Сокращённая оценка

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

Правила логики гарантируют, что данные вычисления всегда корректны. Обратите внимание, что часть «anything» представленных выше выражений не вычисляется, таким образом удаётся избежать любых побочных эффектов вычисления данной части.

Строковые операторы

В дополнение к операторам сравнения, которые могут использоваться со строковыми значениями, оператор (+) позволяет объединить две строки, возвращая при этом третью строку, которая представляет собой объединение двух строк-операндов:

Сокращённый оператор присваивания += также может быть использован для объединения (конкатенации) строк:

Условный (тернарный) оператор

Условный оператор является единственным оператором JavaScript, который использует три операнда. Оператор принимает одно из двух значений в зависимости от заданного условия. Синтаксис оператора:

val1 и val2 обязательно должны что-то возвращать, поэтому в этой конструкции нельзя использовать continue или break

Оператор запятая

Например, если a является двумерным массивом, каждая строка которого содержит 10 элементов, то следующий код с использованием оператора запятая позволяет выполнять одновременное приращение двух переменных. Данный код выводит на экран значения диагональных элементов массива:

Унарные операторы

delete

Оператор delete выполняет удаление объекта, свойства объекта, или элемента массива с заданным индексом. Синтаксис оператора:

Удаление элементов массива

Оператор typeof

Оператор typeof используется одним из следующих способов:

Оператор typeof возвращает строку обозначающую тип невычисленного операнда. Значение operand может быть строкой, переменной, дескриптором, или объектом, тип которого следует определить. Скобки вокруг операнда необязательны.

Предположим, вы определяете следующие переменные:

Оператор typeof возвращает следующие результаты для этих переменных:

Для дескрипторов true и null оператор typeof возвращает следующие результаты:

Для чисел и строк оператор typeof возвращает следующие результаты:

Для свойств оператор typeof возвращает тип значения данного свойства:

Для методов и функций оператор typeof возвращает следующие результаты:

Для встроенных объектов оператор typeof возвращает следующие результаты:

Оператор void

Оператор void используется любым из следующих способов:

Вы можете использовать оператор void для указания на то, что операнд-выражение является гипертекстовой ссылкой. При этом выражение обрабатывается, но не загружается в текущий документ.

Приведённый ниже код создаёт гипертекстовую ссылку, которая подтверждает отправку формы при клике на ней пользователем:

Операторы отношения

Оператор отношения сравнивает свои операнды и возвращает результат сравнения в виде булева значения.

Оператор in

Оператор in возвращает true, если указанный объект имеет указанное свойство. Синтаксис оператора:

Некоторые примеры способов использования оператора in :

Оператор instanceof

Оператор instanceof возвращает true, если заданный объект является объектом указанного типа. Его синтаксис:

Приоритет операторов

Приоритет операторов определяет порядок их выполнения при вычислении выражения. Вы можете влиять на приоритет операторов с помощью скобок.

Приведённая ниже таблица описывает приоритет операторов от наивысшего до низшего.

ВыражениеРезультатДвоичное описание
15 & 991111 & 1001 = 1001
15 | 9151111 | 1001 = 1111
15 ^ 961111 ^ 1001 = 0110
Таблица 3.7 Приоритет операторов

Тип оператораОператоры
свойство объекта. []
вызов, создание экземпляра объекта() new
отрицание, инкремент!

Более подробная версия данной таблицы, содержащая ссылки и дополнительную информацию по каждому оператору, находится в справочнике JavaScript.

Выражения

Выражением является любой корректный блок кода, который возвращает значение.

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

Код 3 + 4 является примером выражения второго типа. Данное выражение использует оператор «+» для сложения чисел 3 и 4 без присваивания переменной полученного результата 7.

Все выражения в JavaScript делятся на следующие категории:

Основные выражения

Базовые ключевые слова и основные выражения в JavaScript.

Оператор this

Используйте ключевое слово this для указания на текущий объект. В общем случае this указывает на вызываемый объект, которому принадлежит данный метод. Используйте this следующим образом:

Предположим, функция validate выполняет проверку свойства value некоторого объекта; задан объект, а также верхняя и нижняя граница величины данного свойства:

Вы можете вызвать функцию validate для обработчика события onChange для каждого элемента формы, используя this для указания на элемент формы, как это показано в следующем примере:

Оператор группировки

Упрощённый синтаксис создания массивов и генераторов

[for (x of y) x] Упрощённый синтаксис для массивов. (for (x of y) y) Упрощённый синтаксис для генераторов.

Упрощённые синтаксисы существуют во многих языках программирования и позволяют вам быстро собирать новый массив, основанный на существующем. Например:

Левосторонние выражения

Значениям слева назначаются значения справа.

Вы можете использовать оператор new для создания экземпляра объекта пользовательского типа или одного из встроенных объектов. Используйте оператор new следующим образом:

super

Ключевое слово используется, чтобы вызывать функции родительского объекта. Это полезно и с классами для вызова конструктора родителя, например.

Оператор расширения

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

Похожим образом оператор работает с вызовами функций:

Источник

Базовые операторы, математика

В этой главе мы начнём с простых операторов, а потом сконцентрируемся на специфических для JavaScript аспектах, которые не проходят в школьном курсе арифметики.

Термины: «унарный», «бинарный», «операнд»

Прежде, чем мы двинемся дальше, давайте разберёмся с терминологией.

Унарным называется оператор, который применяется к одному операнду. Например, оператор унарный минус «-» меняет знак числа на противоположный:

Бинарным называется оператор, который применяется к двум операндам. Тот же минус существует и в бинарной форме:

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

Математика

Поддерживаются следующие математические операторы:

Первые четыре оператора очевидны, а про % и ** стоит сказать несколько слов.

Взятие остатка %

Возведение в степень **

В выражении a ** b оператор возведения в степень умножает a на само себя b раз.

Математически, оператор работает и для нецелых чисел. Например, квадратный корень является возведением в степень 1/2 :

Сложение строк при помощи бинарного +

Давайте рассмотрим специальные возможности операторов JavaScript, которые выходят за рамки школьной арифметики.

Обычно при помощи плюса ‘+’ складывают числа.

Но если бинарный оператор ‘+’ применить к строкам, то он их объединяет в одну:

Обратите внимание, если хотя бы один операнд является строкой, то второй будет также преобразован в строку.

Как видите, не важно, первый или второй операнд является строкой.

Вот пример посложнее:

Например, вычитание и деление:

Приведение к числу, унарный +

Плюс + существует в двух формах: бинарной, которую мы использовали выше, и унарной.

Унарный, то есть применённый к одному значению, плюс + ничего не делает с числами. Но если операнд не число, унарный плюс преобразует его в число.

Необходимость преобразовывать строки в числа возникает очень часто. Например, обычно значения полей HTML-формы — это строки. А что, если их нужно, к примеру, сложить?

Бинарный плюс сложит их как строки:

Поэтому используем унарный плюс, чтобы преобразовать к числу:

С точки зрения математика, такое изобилие плюсов выглядит странным. Но с точки зрения программиста тут нет ничего особенного: сначала выполнятся унарные плюсы, которые приведут строки к числам, а затем бинарный ‘+’ их сложит.

Почему унарные плюсы выполнились до бинарного сложения? Как мы сейчас увидим, дело в их приоритете.

Приоритет операторов

В том случае, если в выражении есть несколько операторов – порядок их выполнения определяется приоритетом, или, другими словами, существует определённый порядок выполнения операторов.

Из школы мы знаем, что умножение в выражении 1 + 2 * 2 выполнится раньше сложения. Это как раз и есть «приоритет». Говорят, что умножение имеет более высокий приоритет, чем сложение.

В JavaScript много операторов. Каждый оператор имеет соответствующий номер приоритета. Тот, у кого это число больше, – выполнится раньше. Если приоритет одинаковый, то порядок выполнения – слева направо.

Отрывок из таблицы приоритетов (нет необходимости всё запоминать, обратите внимание, что приоритет унарных операторов выше, чем соответствующих бинарных):

ПриоритетНазваниеОбозначение
17унарный плюс+
17унарный минус
16возведение в степень**
15умножение*
15деление/
13сложение+
13вычитание
3присваивание=

Присваивание

Присваивание = возвращает значение

Тот факт, что = является оператором, а не «магической» конструкцией языка, имеет интересные последствия.

Вызов x = value записывает value в x и возвращает его.

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

В примере выше результатом (a = b + 1) будет значение, которое присваивается переменной a (то есть 3 ). Потом оно используется для дальнейших вычислений.

Забавное применение присваивания, не так ли? Нам нужно понимать, как это работает, потому что иногда это можно увидеть в JavaScript-библиотеках.

Однако писать самим в таком стиле не рекомендуется. Такие трюки не сделают ваш код более понятным или читабельным.

Присваивание по цепочке

Рассмотрим ещё одну интересную возможность: цепочку присваиваний.

Опять-таки, чтобы код читался легче, лучше разделять подобные конструкции на несколько строчек:

Польза от такого стиля особенно ощущается при быстром просмотре кода.

Сокращённая арифметика с присваиванием

Часто нужно применить оператор к переменной и сохранить результат в ней же.

Эту запись можно укоротить при помощи совмещённых операторов += и *= :

Источник

5.2 – Арифметические операторы

Унарные арифметические операторы

В C++ есть два унарных арифметических оператора, плюс (+) и минус (-). Напоминаем, что унарные операторы – это операторы, которые принимают только один операнд.

Унарные арифметические операторы

ОператорОбозначениеПример использованияОперация
Унарный плюс++xЗначение x
Унарный минус-xОтрицательное значение x

Бинарные арифметические операторы

В C++ есть 5 бинарных арифметических операторов. Бинарные операторы – это операторы, которые принимают левый и правый операнды.

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

Деление и остаток от деления требуют дополнительных пояснений. О делении мы поговорим ниже, а об остатке от деления – в следующем уроке.

Целочисленное деление и деление с плавающей запятой

Проще всего представить себе, что оператор деления имеет два разных «режима».

Предупреждение

Использование static_cast<> для деления с плавающей точкой с целочисленными значениями

Сказанное выше поднимает вопрос: если у нас есть два целых числа и мы хотим разделить их без потери дробной части, как нам это сделать?

В уроке «4.11 – Символы» мы показали, как можно использовать оператор static_cast<> для преобразования значения char в целочисленный тип, чтобы оно печаталось как целое число, а не как символ.

Аналогичным образом мы можем использовать static_cast<> для преобразования значения целочисленного типа в число с плавающей точкой, чтобы мы, вместо целочисленного деления, смогли выполнить деление с плавающей точкой. Рассмотрим следующий код:

Эта программа дает следующий результат:

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

Деление на ноль

Попытка разделить на 0 (или 0.0) обычно приводит к сбою программы, так как результаты математически не определены!

Если вы запустите показанную выше программу и введете 0, ваша программа завершится со сбоем. Попробуйте, это не повредит вашему компьютеру.

Арифметические операторы присваивания

До этого момента, когда вам нужно было добавить 4 к переменной, вы, вероятно, делали следующее:

Это работает, но немного неудобно и требует для выполнения двух операторов ( operator+ и operator= ).

Таким образом, приведенную выше строку можно переписать так:

Источник

Сюрпризы унарного минуса

Унарные операторы что это

Унарные операторы что это

Унарные операторы что это

Другие статьи из серии «Конспекты начинающего программиста»:

Небольшая предыстория

При изучении темы «Операторы» унарные операторы обычно рассматриваются в начале или где-то бегло по ходу, поскольку они вроде простые и излагать там особо нечего. В данном же случае обнаружились некоторые сюрпризы, о которых не говорится в учебнике по Swift. Поэтому представляется удобным выделить их в отдельный текст.

Всё началось с того, что захотелось вживую в XCode прописать примеры из учебника. И вот что из этого вышло.

Что такое унарный минус?

Пример 1: Каждый раз новые константы

И далее в учебнике даётся следующий пример, который цитируется во многих других текстах:

Пример 2: Меняем знак на одной и той же переменной

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

Пока всё идёт в штатном режиме. Но если попробуем пойти дальше и ещё раз сменим знак, то получим сюрприз:

Почему это происходит?

Гипотез было несколько. Первая уже названа: что в первом примере на каждое применение унарного минуса создавалась новая константа, а во втором примере унарный минус использовался на одной и той же переменной. Но что потом делать с этой гипотезой не понятно, потому что она просто закрывает все дальнейшие вопросы, ничего не объясняя.

Вторая гипотеза: унарный минус действует только один раз, а второе его применение использует значение не из предыдущей строки, а из строки, где переменная объявляется. Кстати, если продолжать ставить минусы, то значение не меняется, везде будет минус 1. Это тоже такая гипотеза методом «научного тыка»: а вдруг что-то произойдет, если ставить минусы дальше? Не происходит!

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

И снова сюрприз: мы-то ожидали, что значение переменной изменилось во 2-й строке (а потом и в 3-й, и в 4-й), что оно теперь минус один, а на самом деле оно просто один, без минуса! И опять непонятно почему это происходит?

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

Следующее предположение: а что если нужно поставить второй минус? Может один минус это просто повторение операции смены положительного числа на отрицательное, а чтобы сменить отрицательное на положительное надо ещё один минус? По ходу вспоминается, что где-то упоминались двойные операторы, типа два плюса или два минуса, но сейчас пока не до них, просто пробуем:

Бинго!

Мы своего добились! Применили два минуса и на выходе получили плюс! На всякий случай для страховки проверяем, т.е. указываем просто переменную a:

Отлично! Всё сохраняется, значение нашей переменной снова положительное. Вопросы конечно оставались: почему унарный минус так себя ведёт? Единственное объяснение: он почему-то действует только тогда, когда применяется, но само изменённое значение дальше не сохраняется.

Пример 3. Гештальт

И вот, как это часто бывает, долгие раздумья над каким-то вопросом вдруг приводят к новому повороту. Как говорится, гештальт созрел. Сначала была мысль, что один и тот же знак, минус, используется и как унарный оператор, и как бинарный арифметический. Разница только в синтаксисе: бинарному нужны 2 операнда и он пишется с пробелами, унарному нужен только один операнд и он пишется без пробела от операнда.

Затем настойчивые мысли о том, почему значение не сохраняется, вывели на оператор присвоения. Т.е. унарный минус значение меняет, но оно не сохраняется, т.е. оно НЕ ПРИСВАИВАЕТСЯ переменной! Отсюда логично напрашивается использовать оператор присвоения.

Делаем простой развёрнутый пример со сменой знака и сразу же проверяем текущее значение переменной (9-я и 10-я строки):

Ура ещё раз!

Значение переменной изменилось в 9-й строке, а в 10-й видно, что оно сохранилось! Т.е. впервые, когда мы просто указываем название переменной, её значение в строке 10 отличается от значения в первой строке!

И кстати, с этой точки зрения можно заметить, что в 8-й строке мы не можем утверждать, что новое значение переменной сохранилось, как мы радовались этому немного ранее. Скорее всего в этой строке показывалось не изменённое с плюса на минус и потом с минуса на плюс значение переменной, а всё то же значение из первой строки. Т.е. все предыдущие изменения знака в переменной не сохранялись, потому что не использовался оператор присвоения. И только когда мы используем оператор присвоения, только тогда изменённое значение сохраняется и число в переменной остаётся с другим знаком.

Резюме по унарному минусу

В ходе своего учебного расследования 🙂 мы выяснили как минимум 3 вещи:

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

Если же нам нужно сохранить измененное значение, тогда следует использовать ещё и оператор присвоения. Т.е. изменить знак числа и присвоить это измененное число переменной.

Это можно сделать либо способом, где изменённое значение присваивается той же переменной:

либо так, как показано в учебнике, т.е. присваивая изменённые значения новым переменным / константам:

Пару слов об унарном плюсе

Об унарном плюсе говорить действительно почти нечего. Он просто возвращает исходное значение без изменений. Например:

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

Унарный логический оператор

Его действие: он изменяет, инвертирует значение логической переменной с true на false или с false на true.

Синтаксис: унарный логической оператор также как и унарный минус ставится перед названием переменной без пробела.

И далее, также как в случае с унарным минусом, новое значение логической переменной не сохраняется и действует только в момент использования унарного логического оператора. Т.е. если мы попытаемся ещё раз изменить значение переменной с false на true, то у нас ничего не получится.

Чтобы поменять значение переменной второй раз, т.е. от false перейти к true, нужно использовать круглые скобки:

А если мы хотим не только изменить значение логической переменной на противоположное, но ещё и сохранить его, то нам нужно изменённое значение присвоить или той же переменной, или новой (см. строки с 5-ой по 8-ю):

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

В принципе всё логично, постфиксные операторы как-то выбивались из общего строя. Теперь без них будет проще: есть префиксные и всё понятно и единообразно. А вы как считаете?

Унарные операторы что это

Другие статьи из серии «Конспекты начинающего программиста»:

Небольшая предыстория

При изучении темы «Операторы» унарные операторы обычно рассматриваются в начале или где-то бегло по ходу, поскольку они вроде простые и излагать там особо нечего. В данном же случае обнаружились некоторые сюрпризы, о которых не говорится в учебнике по Swift. Поэтому представляется удобным выделить их в отдельный текст.

Всё началось с того, что захотелось вживую в XCode прописать примеры из учебника. И вот что из этого вышло.

Что такое унарный минус?

Пример 1: Каждый раз новые константы

И далее в учебнике даётся следующий пример, который цитируется во многих других текстах:

Пример 2: Меняем знак на одной и той же переменной

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

Пока всё идёт в штатном режиме. Но если попробуем пойти дальше и ещё раз сменим знак, то получим сюрприз:

Почему это происходит?

Гипотез было несколько. Первая уже названа: что в первом примере на каждое применение унарного минуса создавалась новая константа, а во втором примере унарный минус использовался на одной и той же переменной. Но что потом делать с этой гипотезой не понятно, потому что она просто закрывает все дальнейшие вопросы, ничего не объясняя.

Вторая гипотеза: унарный минус действует только один раз, а второе его применение использует значение не из предыдущей строки, а из строки, где переменная объявляется. Кстати, если продолжать ставить минусы, то значение не меняется, везде будет минус 1. Это тоже такая гипотеза методом «научного тыка»: а вдруг что-то произойдет, если ставить минусы дальше? Не происходит!

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

И снова сюрприз: мы-то ожидали, что значение переменной изменилось во 2-й строке (а потом и в 3-й, и в 4-й), что оно теперь минус один, а на самом деле оно просто один, без минуса! И опять непонятно почему это происходит?

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

Следующее предположение: а что если нужно поставить второй минус? Может один минус это просто повторение операции смены положительного числа на отрицательное, а чтобы сменить отрицательное на положительное надо ещё один минус? По ходу вспоминается, что где-то упоминались двойные операторы, типа два плюса или два минуса, но сейчас пока не до них, просто пробуем:

Бинго!

Мы своего добились! Применили два минуса и на выходе получили плюс! На всякий случай для страховки проверяем, т.е. указываем просто переменную a:

Отлично! Всё сохраняется, значение нашей переменной снова положительное. Вопросы конечно оставались: почему унарный минус так себя ведёт? Единственное объяснение: он почему-то действует только тогда, когда применяется, но само изменённое значение дальше не сохраняется.

Пример 3. Гештальт

И вот, как это часто бывает, долгие раздумья над каким-то вопросом вдруг приводят к новому повороту. Как говорится, гештальт созрел. Сначала была мысль, что один и тот же знак, минус, используется и как унарный оператор, и как бинарный арифметический. Разница только в синтаксисе: бинарному нужны 2 операнда и он пишется с пробелами, унарному нужен только один операнд и он пишется без пробела от операнда.

Затем настойчивые мысли о том, почему значение не сохраняется, вывели на оператор присвоения. Т.е. унарный минус значение меняет, но оно не сохраняется, т.е. оно НЕ ПРИСВАИВАЕТСЯ переменной! Отсюда логично напрашивается использовать оператор присвоения.

Делаем простой развёрнутый пример со сменой знака и сразу же проверяем текущее значение переменной (9-я и 10-я строки):

Ура ещё раз!

Значение переменной изменилось в 9-й строке, а в 10-й видно, что оно сохранилось! Т.е. впервые, когда мы просто указываем название переменной, её значение в строке 10 отличается от значения в первой строке!

И кстати, с этой точки зрения можно заметить, что в 8-й строке мы не можем утверждать, что новое значение переменной сохранилось, как мы радовались этому немного ранее. Скорее всего в этой строке показывалось не изменённое с плюса на минус и потом с минуса на плюс значение переменной, а всё то же значение из первой строки. Т.е. все предыдущие изменения знака в переменной не сохранялись, потому что не использовался оператор присвоения. И только когда мы используем оператор присвоения, только тогда изменённое значение сохраняется и число в переменной остаётся с другим знаком.

Резюме по унарному минусу

В ходе своего учебного расследования 🙂 мы выяснили как минимум 3 вещи:

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

Если же нам нужно сохранить измененное значение, тогда следует использовать ещё и оператор присвоения. Т.е. изменить знак числа и присвоить это измененное число переменной.

Это можно сделать либо способом, где изменённое значение присваивается той же переменной:

либо так, как показано в учебнике, т.е. присваивая изменённые значения новым переменным / константам:

Пару слов об унарном плюсе

Об унарном плюсе говорить действительно почти нечего. Он просто возвращает исходное значение без изменений. Например:

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

Унарный логический оператор

Его действие: он изменяет, инвертирует значение логической переменной с true на false или с false на true.

Синтаксис: унарный логической оператор также как и унарный минус ставится перед названием переменной без пробела.

И далее, также как в случае с унарным минусом, новое значение логической переменной не сохраняется и действует только в момент использования унарного логического оператора. Т.е. если мы попытаемся ещё раз изменить значение переменной с false на true, то у нас ничего не получится.

Чтобы поменять значение переменной второй раз, т.е. от false перейти к true, нужно использовать круглые скобки:

А если мы хотим не только изменить значение логической переменной на противоположное, но ещё и сохранить его, то нам нужно изменённое значение присвоить или той же переменной, или новой (см. строки с 5-ой по 8-ю):

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

В принципе всё логично, постфиксные операторы как-то выбивались из общего строя. Теперь без них будет проще: есть префиксные и всё понятно и единообразно. А вы как считаете?

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *