Операторы
Одним из ключевых понятий любого языка программирования является понятие "оператор". Без овладения этим понятием в полной мере написание программ не представляется возможным. От того, насколько быстро и правильно программист усвоит, что такое операторы и как они применяются в программе, зависит, как скоро он начнёт писать программы.
Оператор — это составная часть программы, фраза алгоритмического языка, предписывающая определённый порядок преобразования информации.
Любая программа содержит операторы. Наиболее близкой аналогией оператору является предложение. Операторы образуют программу так же, как обычные предложения образуют текст рассказа или повести.
Свойства операторов
Различаются два вида свойств операторов — общeе и собственные.
Общее свойство операторов
Все операторы имеют одно общее свойство — они исполняются.
Можно сказать, что оператор — это инструкция, содержащая руководство к действию (описание приказа). Для компьютера выполнять запущенную на нём программу означает (последовательно переходя от одного оператора к другому) выполнять предписания (инструкции, приказы), содержащиеся в операторах.
Собственно оператор — это только запись, некоторая последовательность символов. В операторе нет рычажков, проводов или ячеек памяти. Поэтому, когда компьютер выполняет программу, в самих операторах ничего не происходит, они продолжают оставаться в программе в том виде, в котором их составил программист. Но преобразования происходят в компьютере, имеющем ячейки памяти и каналы связи между ними. Если компьютер исполнил некоторое преобразование информации в соответствии с содержащимся в операторе предписанием, то говорят, что оператор исполнился.
Собственные свойства операторов
Существует несколько различных видов операторов. Каждый вид оператора обладает собственным свойством. Например, свойством оператора присваивания является способность присвоения указанной переменной некоторого значения, свойством оператора цикла является его многократное исполнение. Собственные свойства операторов подробно рассматриваются в соответствующих разделах главы Операторы. Здесь укажем только, что все виды операторов имеют собственные свойства, присущие только их виду и не повторяющиеся в других видах.
Типы операторов
Различают два типа операторов — простые и составные.
Простые операторы
Простые операторы в языке MQL4 заканчиваются знаком ";" (точка с запятой). С помощью этого разделителя компьютер может определить, где заканчивается один и начинается другой оператор. Знак ";" (точка с запятой) так же необходим в программе, как "." (обычная точка) необходима в обычном тексте для разделения предложений. Один оператор может располагаться в нескольких строках, несколько операторов можно располагать в одной строке.
Каждый простой оператор заканчивается знаком ";" (точка с запятой). |
Примеры простых операторов:
Составные операторы
Составной оператор состоит из нескольких простых, разделенных знаком ";", и оформляется фигурными скобками. Чтобы можно было использовать несколько операторов там, где ожидается присутствие только одного, предусматривается составной оператор (который также называют "блоком"). Список операторов в составном операторе выделяется фигурными скобками, а свидетельством окончания составного оператора является наличие закрывающей фигурной скобки.
Пример использования составного оператора в условном операторе. Сначала идет условный оператор if(выражение), за ним следует составной оператор. Составной оператор содержит список исполняемых операторов. |
Рис. 17. Составной оператор.
Тело составного оператора заключено в фигурные скобки. Каждый составной оператор заканчивается закрывающей фигурной скобкой. |
Примеры составных операторов:
Тело составного оператора всегда заключено в фигурные скобки и может состоять из нуля, одного или нескольких операторов. |
Примеры использования простых операторов:
Несколько простых операторов могут быть объединены в составной оператор без строгой необходимости. |
Это — редко встречающаяся, но вполне допустимая конструкция. В этом случае операторы, заключённые в фигурные скобки, называют блоком операторов. Такое использование допустимо. Обрамление фигурными скобками делается по воле программиста для удобства представления кода. Пример блока операторов:
Требования к операторам
Операторы должны быть записаны в текст программы в соответствии с правилами форматирования (представления в программе). Ни один оператор не может быть составлен вне этих правил. Если же программа содержит оператор, составленный вопреки правилам форматирования, то при компиляции программы редактор MetaEditor выдаст сообщение об ошибке. Это значит, что в таком виде программа (содержащая ошибочный оператор) не может использоваться.
Выражение "Формат оператора" следует понимать как набор правил форматирования, присущих виду оператора. Каждый вид оператора имеет свой формат. Форматы операторов подробно рассматриваются в соответствующих разделах главы Операторы.
Порядок исполнения операторов
Важной характеристикой любой программы является порядок исполнения операторов. Операторы не могут исполняться просто так, без всякой системы. В языке MQL4 принято следующее правило исполнения операторов:
Операторы исполняются в том порядке, в котором они встречаются в программе. Направлением последовательности исполнения операторов принято направление слева направо и сверху вниз. |
Это значит, что и простые и составные операторы исполняются просто подряд, один за другим (подобно тому, как мы читаем строки стихов — сначала верхнюю строку, потом следующую ниже, следующую и т.д.). Если в одной строке находится несколько операторов, то они исполняются последовательно один за другим слева направо, после чего исполняются операторы в следующей строке, расположенной ниже.
Операторы, входящие в составной оператор, исполняются точно так же: любой оператор блока начинает исполняться после того, как исполнится предыдущий.
Пример написания и исполнения операторов
По внешнему виду текст программы (содержащий операторы) напоминает обычный текст или записи математических уравнений. Однако это сходство — только внешнее. В обычном тексте допускается произвольная последовательность записей, в то время как в программе необходимо соблюдение строго определённого порядка.
В качестве примера рассмотрим, как работает оператор присваивания. Для этого возьмём решение простой системы линейных уравнений и сравним, как некоторые математические вычисления отражаются в обычном тексте и как — в тексте программы, в операторах.
Задача 7. Дана система уравнений: Y = 5 Y — X = 2 Требуется найти численное значение переменной Х. |
Вариант 1. Текст составлен обычным способом на листе бумаги.
Вариант 2. Текст программы.
И в первом, и во втором варианте записи (строки) содержат законченный смысл. Тем не менее, строки из первого варианта не могут в таком виде использоваться в программе, потому что их вид не соответствует формату оператора присваивания.
Записи в первом варианте представляют отображение на бумаге некоторых зависимостей. Они могут использоваться лишь для того, чтобы сообщить программисту, в каком отношении находятся между собой переменные. Программные операторы имеют другое назначение — они сообщают компьютеру, какие операции и в какой последовательности необходимо исполнить. Все без исключения операторы представляют собой точную, не допускающую неоднозначности инструкцию.
Оба оператора в Варианте 2 являются операторами присваивания. Любой оператор присваивания отдаёт компьютеру буквально следующий приказ:
Вычислить значение выражения справа от знака равенства и присвоить полученное значение переменной слева от знака равенства. |
По этой причине в операторе присваивания слева от знака равенства не может находиться ничего, кроме переменной. Например, запись 5 — Х = 2, используемая в первом варианте, содержит ошибку, потому что набор символов 5 — Х не является переменной. Поэтому не существует и ячейки памяти, в которую должно быть помещено численное значение выражения, вычисленного справа от знака равенства.
Проследим, что будет делать компьютер, выполняя операторы второго варианта.
1. Переход к оператору (строка 1).
2. Обращение к правой части оператора (правая часть находится между знаком равенства и точкой с запятой).
3. Компьютер обнаружил, что правая часть оператора содержит численное значение.
4. Запись численного значения (5) в ячейку памяти переменной Y.
5. Переход к следующему оператору (строка 2).
6. Обращение к правой части оператора.
7. Компьютер обнаружил, что правая часть оператора содержит выражение.
8. Вычисление численного значения правой части оператора (5 — 2).
9. Запись численного значения (3) в ячейку памяти этой переменной Х.
Выполнение компьютером действий 1 — 4 есть исполнение первого оператора (строка 1). Выполнение компьютером действий 5 — 9 есть исполнение второго оператора (строка 2).
Для того чтобы составить работающую программу, программист должен хорошо представлять себе, что и в какой последовательности в этой программе будет выполняться. В частности, в программу заносятся не все математические вычисления, нередко возникает необходимость предварительной подготовки операторов.
Например, при решении математических задач производится немало промежуточных вычислений. Они могут помочь математику найти правильное решение, но оказываются бесполезными с точки зрения программирования. В качестве операторов в программу необходимо вносить только содержательные вычисления: например, исходные значения одних переменных или формулы для вычислений других. В предыдущем примере первый оператор несёт информацию о численном значении переменной Y, а второй оператор — формулу для вычисления интересующей нас переменной X.
В любой работающей программе есть выражения, имеющие привычный вид, но найдутся и такие, которые можно понять, только оценивая их в качестве программных операторов. Например, запись
с точки зрения математической логики и здравого смысла кажется ошибочной. Но она вполне приемлема, если воспринимать её как оператор (кстати, именно этот оператор имеет широкое применение).
В этом операторе вычисляется новое значение переменной Х: выполняя оператор присваивания (то есть вычисляя значение правой части оператора), компьютер обратится к ячейке памяти, несущей численное значение переменной Х (например, в момент обращения оно окажется равным 3), вычислит выражение в правой части оператора присваивания (3 + 1) и полученное значение (4) запишет в ячейку памяти переменной Х. В результате исполнения этого оператора присваивания переменная Х получит новое значение — (4). Компьютер будет удерживать это значение переменной Х до тех пор, пока переменная Х не встретится в левой части от знака равенства в каком-нибудь другом операторе присваивания. В этом случае будет вычислено новое значение этой переменной, которое она будет удерживать до следующего возможного изменения.
Оператор (математика)
Термин оператор встречается в разных разделах математики, его точное значение зависит от раздела. Как правило, под операторами понимают какие-то особые (для данной области математики) отображения, например в функциональном анализе под операторами понимают отображение ставящее в соответствие функции другую функцию («оператор на пространстве функций» звучит лучше, чем «функция от функции»).
Наиболее часто встречающиеся операторы:
-
: Операторы на пространствах функций (дифференцирование, интегрирование, свертка с ядром, преобразование Фурье). : Отображения (в особенности линейные) векторных пространств (проекторы, повороты координат, гомотетии, умножения вектора на матрицу).
Содержание
Основная терминология [ ]
- Оператор может быть не всюду определен; тогда говорят о его области определения D A = D ( A ) <\displaystyle D_=D(A)> .
- Для x ∈ X <\displaystyle x\in X>результат применения оператора A <\displaystyle A>к x <\displaystyle x>обозначают A ( x ) <\displaystyle A(x)>или A x <\displaystyle Ax>.
- Если X <\displaystyle X>и Y <\displaystyle Y>— векторные пространства, то в множестве всех операторов из X <\displaystyle X>в Y <\displaystyle Y>можно выделить класс линейных операторов.
- Если X <\displaystyle X>и Y <\displaystyle Y>— векторные топологические пространства , то в множестве операторов из X <\displaystyle X>в Y <\displaystyle Y>естественно выделяется класс компактных операторов (наз. также вполне непрерывными).
Простые примеры [ ]
Оператор, действующий над пространствами функций — это правило, согласно которому одна функция преобразуется в другую. Преобразование функции x(t) согласно правилу A в другую функцию y(t) выглядит: y(t) = A<x(t)> или, проще, y = Ax. Примерами подобных преобразований могут быть, например, домножение на число: y(t) = cx(t), дифференцирование: y(t) = d x ( t ) d t <\displaystyle
Определяя оператор, мы рассматривали только преобразование функции x(t) в другую функцию y того же аргумента t. Такое сохранение аргумента при определении оператора вовсе не является обязательным: оператор может преобразовывать функцию одного аргумента в функцию другого аргумента, например:
или Преобразование Фурье из временной в частотную область:
Отличие оператора от простой суперпозиции функций в данном случае заключается в том, что значение функции y, вообще говоря, в каждой точке t зависит не только от x(t), а от значений функции x во всех точках t. Поясним на примере преобразования Фурье. Значение этого преобразования (спектр функции) в точке ω <\displaystyle \omega >меняется при изменении исходной функции в любой точке t <\displaystyle t>.
Изучением общих свойств операторов и применением их к решению различных задач занимается теория операторов. Например, оказывается, что у оператора умножения вектора на матрицу и оператора свертки функции с весом есть много общих свойств.
Фундаментальным для практики является класс так называемых линейных операторов. Он также является наиболее исследованным.
Линейные операторы [ ]
Оператор L (действующий из векторного пространства в векторное же) называется линейным однородным (или просто линейным), если он обладает следующими свойствами:
1) может применяться почленно к сумме аргументов:
2) скаляр (постоянную величину) с можно выносить за знак оператора:
Из 2) следует, что для линейного однородного оператора справедливо свойство L(0) = 0.
Примеры линейных однородных операторов:
- оператор дифференцирования: L ( x ( ⋅ ) ) <\displaystyle L(x(\cdot ))>= y(t) = d x ( t ) d t <\displaystyle
> ; - оператор интегрирования: y(t) = ∫ 0 t x ( τ ) d τ <\displaystyle \int _<0>^
x(\tau )\,d<\tau >> ; - оператор умножения на определённую функцию φ(t): y(t) = φ(t)x(t);
- оператор интегрирования с заданным «весом» φ(t): y(t) = ∫ 0 t x ( τ ) ϕ ( τ ) d τ <\displaystyle \int _<0>^
x(\tau )<\phi >(\tau )\,d<\tau >> - оператор взятия значения функции f <\displaystyle f>в конкретной точке x 0 <\displaystyle x_<0>> : L ( f ) = f ( x 0 ) <\displaystyle L(f)=f(x_<0>)> ;
- оператор умножения вектора на матрицу: b = A x <\displaystyle b=Ax>.
Оператор L называется линейным неоднородным, если он состоит из линейного однородного оператора с прибавлением некоторого фиксированного элемента:
где L0 — линейный однородный оператор. Примеры линейных неоднородных операторов:
- Любое аффинное преобразование;
- y(t) = d x ( t ) d t <\displaystyle
> + φ(t); - y(t) = ∫ 0 t x ( τ ) d τ <\displaystyle \int _<0>^
x(\tau )\,d<\tau >> + φ(t); - y(t) = φ1(t)x(t) + φ2(t);
где φ(t), φ1(t), φ2(t) — вполне определённые функции, а x(t) — преобразуемая оператором функция.
В случае преобразования дискретных функций (последовательностей, векторов) линейные операторы характеризуются тем, что для них yk являются линейными функциями от xk:
Коэффициенты Tkl образуют матрицу. Если <yk> рассматривают как векторы, то оператор называется тензором. В этом случае пишут b = T a <\displaystyle <\mathfrak >=<\mathfrak
В более общем случае непрерывных функций двумерная матрица весов принимает вид функции двух переменных K(t, ω), и называется ∫ V K ( t , ω ) f ( ω ) d ω <\displaystyle \int _
Функция-операнд f(ω) в данном случае называется ∑ i = 1 n T i ( t ) w i <\displaystyle \sum _^
Единичный оператор [ ]
Частный случай линейного оператора, возвращающий операнд в неизменном виде:
Ea = a,
то есть как матричный оператор определяется равенством
и как интегральный оператор — равенством
Запись [ ]
В математике и технике широко применяется условная форма записи операторов, аналогичная алгебраической символике. Такая символика в ряде случаев позволяет избежать сложных преобразований и записывать формулы в простой и удобной форме. Аргументы оператора называются F < f ( t ) ><\displaystyle <\mathcal
Оператор в программировании
Оператор в программировании — это команда, обозначающая определенное математическое или логическое действие, выполняемое с данными (операндами). Является минимальным автономным элементом компьютерной программы. По сути любая компьютерная программа представляет собой последовательность операторов. Близким аналогом операторов в естественных языках являются фразы или предложения, из которых состоит текст.
«IT-специалист с нуля» наш лучший курс для старта в IT
Каждый оператор имеет свое написание (синтаксис) и семантику (содержание, смысл). В зависимости от конкретного языка синтаксис оператора может существенно различаться, хотя в целом для обозначения той или иной операции используются символы, имеющие аналогичное или похожее значение в математике или формальной логике.
Попробуйте 9 профессий за 2 месяца и выберите подходящую вам
Зачем нужны операторы в программировании?
Компьютерная программа представляет собой алгоритм, то есть последовательность определенных действий с данными. Ее создает человек, но исполняет компьютер, поэтому она должна быть понятна им обоим. Поэтому просто описать определенную операцию, скажем, присваивания значения переменной обычным (естественным) языком, хоть и теоретически возможно, на практике очень неудобно. Для человека такой код будет очень громоздким и сложно воспринимаемым настолько, что написание сколько-нибудь большой программы станет невозможным. А чтобы код воспринимался компьютером, придется разработать сложный компилятор для его перевода на машинный язык.
Поэтому для обозначения операций в программировании были взяты символы, используемые в аналогичных языках в математических выражениях и формальной логике. Именно они стали основой для синтаксиса операторов в абсолютном большинстве современных ЯП. Таким образом, операторы в программировании выполняют следующие функции:
- упрощают и сокращают код, делают его более понятным человеческому восприятию;
- обозначают определенную операцию с данными таким образом, чтобы ее можно было легко перевести на машинный код.
Среди дополнительных преимуществ использования операторов можно выделить простое восприятие программы человеком независимо от того, носителем какого естественного языка он является. Это достигается за счет универсальности математических и логических символов.
Общее свойство операторов
Все операторы в программировании имеют одно общее свойство — они исполняются. То есть по своей сути они являются инструкциями, которым должен следовать компьютер, чтобы определенным образом обработать данные и выполнить программу. При этом сам оператор является чистой математической или логической абстракцией, под ним не подразумевается каких-либо конкретных объектов вроде ячеек памяти. На протяжении всего исполнения программы он остается в неизменном виде — зато изменяются данные, содержащиеся в памяти компьютера. Иными словами, эти изменения информации и являются исполнением команды, обозначенной оператором.
Виды операторов в программировании
В различных языках программирования имеются свои системы операторов и операций. Но в целом их можно классифицировать, разделив на несколько основных типов.
Оператор присваивания. Он используется в том случае, когда необходимо присвоить определенное значение переменной. То есть показать программе, что в данной ячейке памяти, обозначенной именем, лежат конкретные данные, которые нужно будет использовать в процессе исполнения кода. В большинстве языков программирования алгоритм присваивания использует знак равенства. Например, на языке Python данная операция выглядит следующим образом:
х = 365, где х — это имя переменной, 365 — ее значение, а «=» — знак присваивания.
Курс для новичков «IT-специалист
с нуля» – разберемся, какая профессия вам подходит, и поможем вам ее освоить
Арифметические операторы. Это группа операторов, обозначающих математические действия с данными. В большинстве языков программирования они обозначаются символами, использующимися в том же значении в обычных арифметических управлениях, хотя некоторые из них могут иметь собственное обозначение — например:
- «-» — вычитание;
- «+» — сложение;
- «*» — умножение;
- «/» — деление без остатка;
- «—» — уменьшение;
- «++» — увеличение.
Два последних оператора из этого списка используются в языке С и обозначают уменьшение или увеличение операнды на 1. В других ЯП эта операция записывается, например, следующим образом: х = х + 1 или х = х – 1.
Логические операторы. Они помогают установить отношения между различными данными и/или обозначить условия, при которых будут выполняться какие-либо действия. Ключевой концепцией для их понимания является соотношение «правда/ложь» (true/false). Логические операторы по своей семантике и синтаксису базируются на формальной логике. В различных языках программирования их обозначение бывает разным, причем не только символьным, но и буквенным — например:
- Оператор «И» сравнивает несколько значений друг с другом и выдает результат «истина/ложь», от которого зависит дальнейшее выполнение программы. Результат «истина» возможен только в том случае, когда все значения истинны. Обозначается словом «and» или знаками &, &&.
- Оператор «ИЛИ» также сравнивает несколько значений друг с другом. Отличается от предыдущего тем, что выдает результат «ложь» только в том случае, когда все сравниваемые значения ложные. Обозначается словом «or», знаком ||.
- Оператор «НЕ» предназначен для замены значения на противоположное, то есть «истина» на «ложь» и наоборот. В программировании обозначается восклицательным знаком «!».
Операторы сравнения. Они часто используются в связке с логическими операторами для сравнения различных значений друг с другом, результатом чего является результат «истина/ложь». Например, в языке С они обозначаются следующими символами:
- «>» — больше;
- «<» — меньше;
- «>=» — больше или равно;
- «<=» — меньше или равно;
- «==» — равно;
- «!=» — не равно.
Помимо этих основных операторов в программировании используются и другие, причем в зависимости от языка их набор может существенно различаться, что влияет на возможности ЯП и гибкость написанного на нем кода. Часто в одном и том же языке сосуществуют операторы, обозначаемые словом или символом. Например, в языке Pascal наряду с символьным оператором присваивания «:=» присутствует оператор безусловного перехода «goto», записанный буквами латинского алфавита.
Все указанные выше команды являются простыми, то есть обозначающими одну конкретную операцию с данными. Помимо них в программировании используются составные операторы, то есть состоящие из нескольких простых. Соответственно, они имеют специальные обозначения для корректного написания в программе:
- Границы составного оператора могут обозначаться в различных языках фигурными скобками (в С или С++), словами «begin» и «end».
- Разделителем, отделяющим друг от друга простые операторы, входящие в состав сложного.
Составные операторы впервые появились в языке Алгол, из которого были унаследованы многими другими ЯП, такими как Pascal, C, C++ и т. д. Они позволяют использовать несколько операторов там, где ожидается применение одного — например, в операциях ветвления. Составные операторы позволяют упростить программный код и упорядочить его исполнение. Пример написания составного условного оператора «switch» (заменяющего множество простых операторов «if» на языке С:
switch(ii)
<
case 1: Buf_1[Pok-f+i]= Prognoz; break;
case 2: Buf_2[Pok-f+i]= Prognoz; break;
case 3: Buf_3[Pok-f+i]= Prognoz; break;
>
По своему назначению в структуре программы операторы можно разделить на следующие основные типы:
Операторы выбора. Они используются в тех случаях, когда программа подразумевает выбор из некоторого числа значений, в зависимости от которых происходит ее дальнейшее исполнение или неисполнение. Иными словами, они обозначают ветвление алгоритма. Типичным примером является оператор «if» в языке С, который разделяет программу на два сценария в зависимости от того, исполняется или нет указанное в нем условие.
Операторы цикла. С помощью таких операторов в программе обозначаются операции, выполняемые многократно (циклы). Они тоже содержат условия или параметры, при соблюдении которых цикл повторяется. В языке Pascal таким оператором является «while». Например, конструкция «while B do S» в переводе на естественный язык означает, что пока значение логического выражения (условия) B истинно, программа будет исполнять цикл S до тех пор пока B не станет ложным. В зависимости от того, как используется условие, операторы цикла можно разделить на 3 группы:
- с предусловием — то есть условием, соблюдение которого необходимо для осуществления цикла;
- В операторе с постусловием ситуация обратная — при выполнении условия цикл завершится;
- В операторе с параметром (переменной) вводится изменяемое значение, которое определяет конечное количество повторений цикла.
Операторы вызова процедуры. Под процедурами в программировании подразумевается подпрограмма (функциональный блок, входящий в основную программу). Фактически оператор вызова процедуры инициирует ее начало и определяет завершение по достижении нужных результатов. Таким образом, он позволяет сделать программу более понятной, а ее исполнение — последовательным и безошибочным.
Операторы перехода. Они перенаправляют исполнение программы к определенному фрагменту кода, помеченному специальной меткой. Операторы перехода позволяют создавать работающие алгоритмы со сложной структурой. Типичным примером такого оператора в языке Pascal является безусловный оператор «goto». Помимо него есть также оператор прерывания цикла «break» или досрочного завершения его текущей операции «continue», прерывания всей программы «exit» и т. д. Подобные операторы присутствуют и в других языках программирования, таких как С, С++, Java и т. д.
Порядок исполнения операторов
Для правильного использования операторов в программировании важно правильно задать последовательность их исполнения. Стандартным является вариант, когда простые и сложные операторы исполняются последовательно сверху вниз (если они расположены на разных строках) и справа налево (в одной строке). Так они и должны быть отражены в коде программы. Простые операторы, входящие в состав сложного (множественного), исполняются по тому же принципу. Однако такой принцип последовательности не единственный: в некоторых языках программирования есть возможность настроить его более гибко. Это зачастую ведет к усложнению структуры программы.
Таким образом, операторы в программировании являются одной из важнейших составляющих кода, минимальной функциональной единицей, без которой невозможно исполнение даже самой простой программы. Для их эффективного применения необходимо четко соблюдать правила синтаксиса, предусмотренные в конкретном языке, понимать смысл выполняемых операций и правильно задавать последовательность их исполнения.
Наш лучший курс для старта в IT. За 2 месяца вы пробуете себя в девяти разных профессиях: мобильной и веб-разработке, тестировании, аналитике и даже Data Science — выберите подходящую и сразу освойте ее.
Операторы в Java: для чего нужны и какие бывают
Знакомимся с основными инструментами языка и учимся работать с ними на практике.
Иллюстрация: Оля Ежак для Skillbox Media
Все мы со школы знакомы с математическими знаками + (плюс), – (минус), = (равно) и так далее. В Java и других языках программирования эти символы называются операторами. Они нужны для того, чтобы сообщить компилятору, какое действие совершать с операндами — числами, строками, объектами и другими значениями по обе стороны оператора.
Например, на картинке выше оператор + говорит компилятору: «Сложи два числа». Но на практике чисел в выражении может быть разное количество — и одно, и два, и три. В этих случаях и операторы будут называться по-разному: унарные — что-то делают с одним операндом, бинарные — с двумя, и тернарные — с тремя.
В этой статье рассмотрим не только эти, но все основные виды операторов в Java:
Ещё поговорим о приоритетах операторов — разберёмся, в каком порядке они выполняются. Если вы хотите просто освежить в памяти суть работы разных операторов, можете сразу перейти к шпаргалке в конце статьи.
Оператор присваивания в Java
Оператор присваивания в Java — это знак = (равно). Его задача — переложить значение переменной справа в переменную слева:
Вот как это выглядит в коде (в комментариях — разбор синтаксиса):
Что происходит: значение true присваивается переменной b. В свою очередь, значение переменной b присваивается переменной a.
Арифметические операторы в Java
Эти операторы выполняют простые арифметические действия: сложение, вычитание, умножение, деление и деление с остатком. Все арифметические операторы являются бинарными — то есть работают только с двумя значениями.
Плюс: +
Что делает: складывает два операнда.
Ещё этот оператор применяется при соединении двух строк в одну. Например, в Java можно выполнить выражение «Я люблю» + «Москву» и получить «Я люблю Москву». Такая операция в программировании называется конкатенацией.
В Java типы данных char, byte и short при вычислениях неявно приводятся к типу int (целое число), поэтому с ними можно работать как с обычными числами. При этом тип данных char в Java отвечает за символы Unicode — каждый символ обозначает какое-то число. Например, символ a равен числу 97, а b — 98, поэтому в нашем примере и получилось значение 195.
Минус: −
Что делает: вычитает из левого операнда правый.
Умножение: *
Что делает: возвращает произведение операндов.
Деление: /
Что делает: делит левый операнд на правый.
А вот что будет, если попробовать поделить на ноль в Java:
Делить число на ноль нельзя! Программа завершится, выбросив исключение. Но если привести выражение к типу ‘double’ (число с плавающей запятой), то вы получите «бесконечность»:
Деление с остатком (деление по модулю): %
Что делает: возвращает остаток от деления.
Унарные операторы в Java
Эти операторы в Java тоже можно отнести к арифметическим, но есть нюанс — они работают только с одним операндом. Поэтому их и называют унарными.
Унарные плюс и минус: + и −
Что делают: меняют значение числа на положительное или отрицательное.
Инкремент и декремент: ++ и −−
Что делают: инкремент — увеличивает значение переменной на единицу, а декремент — уменьшает.
В свою очередь, у декремента и инкремента есть две формы: префиксная и постфиксная. Звучит сложно, но на деле всё просто:
- Префиксные операторы (++x) сразу меняют значение переменной и подставляют его в выражение.
- Постфиксные операторы (x++) делают наоборот — сначала используют старое значение переменной и только потом подставляют новое.
Инкременты и декременты часто используют в циклах в качестве счётчика, когда нужно по очереди вывести все числа в каком-то диапазоне:
Подробнее о декрементах и инкрементах можно почитать в нашей статье — рассказываем, как решать сложные выражения с этими операторами.
В Java есть ещё два унарных оператора: ! — логическое отрицание, и
— побитовое отрицание, но их мы рассмотрим чуть позже, когда будем разбираться с логическими и побитовыми операторами.
Операторы сравнения в Java
Что делают: сравнивают два операнда и выясняют отношения между ними — что больше, что меньше, что чему равняется. При вычислении такие операторы возвращают значение типа boolean:
- true (правда);
- false (ложь).
Всего в Java шесть операторов сравнения:
Оператор | Что означает |
---|---|
== | Равно |
> | Больше, чем |
< | Меньше, чем |
>= | Больше или равно |
<= | Меньше или равно |
!= | Не равно |
Давайте посмотрим, как выглядят операторы сравнения в коде — попробуем сравнить два целых числа и вывести результаты на экран:
Ещё операторы сравнения часто используют в условных конструкциях. Это когда, в зависимости от условий, выполняется какой-то один блок кода. В этом случае, помимо операторов сравнения, нам понадобятся операторы ветвления: if-else, switch и так далее. Например, здесь мы просим Java напечатать слово true, если 1 не равно 0:
Подробнее об операторах сравнения и условных конструкциях можно почитать в этой статье.
Логические операторы в Java: Boolean
Что делают: комбинируют логические значения типа true и false.
В отличие от операторов сравнения, логические операторы работают не с отдельными числами, а с результатами выражений. Их часто используют в условных конструкциях — например, можно поставить рядом два выражения и выполнить какой-то блок кода, если одно из них возвращает true.
Всего в Java шесть логических операторов, но чаще всего используют эти четыре:
Символ | Логический оператор | Что означает |
---|---|---|
&& | И (AND) | Возвращает true, когда оба операнда true. |
|| | ИЛИ (OR) | Возвращает true, когда хотя бы один операнд — true. |
^ | ИСКЛЮЧАЮЩЕЕ ИЛИ (XOR) | Возвращает true, когда один операнд true, а второй — false. |
! | НЕ (NOT) | Инвертирует true в false и наоборот. Это унарный оператор — он работает только с каким-то одним выражением. |
В качестве примера сравним несколько выражений:
Как это работает. Допустим, у нас есть конструкция (6 > 5) && (7 > 4). Когда мы начнём её выполнять, компилятор сначала проверит условия первого выражения, затем — второго. При этом оператор && устроен так, что если оба выражения истинны, то он и сам вернёт true. А это как раз наш случай, потому что и 6 больше 5, и 7 больше 4.
Тернарный оператор в Java: можно, только осторожно
Что делает: сокращает условную конструкцию if-else до одной строчки.
Тернарный оператор (от латинского слова ternarius — «тройной») — это языковая конструкция, которая состоит из трёх операндов: логического условия и двух выражений. Если результат логического условия будет true, выполнится первое выражение, если false — второе. Записываются тернарные операторы так:
Фишка в том, что таким образом мы можем записать конструкцию if-else всего одной строчкой. Допустим, нам нужно проверить булеву переменную condition — если она возвращает true, то переменная a = 100, а если false, то a = 200. Посмотрите, как легко это можно сделать с помощью тернарного оператора:
Кажется, что эти if-else теперь вообще больше не нужны. Мол, ставь везде тернарные операторы, и дело с концом. Однако в больших программах со сложной логикой это может повредить читаемости кода. Это в нашем примере выражение простое — а представьте, если в каждое выражение положить ещё по одному оператору. Получится неопрятно. Другому разработчику, который будет читать наш код, разобраться будет сложно.
Поэтому тернарные операторы рекомендуют использовать в тех случаях, когда условие простое и легко проверяется. А во всех остальных случаях прибегать к привычным «ифам» и «элсам».
Подробно о том, как работать с тернарными операторами, мы рассказывали в статье: «Тип Boolean и операторы сравнения в Java».
Оператор instanceof в Java
Что делает: проверяет, принадлежит ли объект к какому-то классу или интерфейсу, и возвращает булево значение — то есть true или false.
Использование instanceof актуально, когда нужно проверить родителя объекта прямо во время выполнения программы. Например, если объекты приходят в ваш код из базы данных или другого потока выполнения и вам нужно убедиться, что к ним можно применять методы какого-то класса. Записывается instanceof так:
Побитовые операторы в Java и смещение битов
Зачем нужны: чтобы писать алгоритмы, работающие с битами, — например, это полезно в криптографии и шифровании данных.
В Java существует семь побитовых операторов. Четыре из них отвечают за побитовые вычисления. Они похожи на логические операции, только вместо true и false вы имеете дело с нулями и единицами в двоичной системе счисления. Каждый разряд вычисляется поочерёдно — но в отличие от математики, когда складываются две единицы, результат не переносится на старший разряд и ответом будет 1. Это как если бы мы считали столбиком, а всё, что «в уме», — выкидывали.
Побитовые операторы вычисления бывают следующими:
Чтобы посмотреть, как работают побитовые вычисления в Java, переведём несколько десятичных чисел в двоичную систему счисления:
Теперь попробуем выполнить с ними логические операции:
В последнем примере мы видим, что при побитовом отрицании числа 0, почему-то получается -1. Тут есть два нюанса:
- 0 в нашем примере имеет тип int и занимает в памяти 4 байта — то есть 32 бита.
- Самый старший бит переменной (первый слева) является знаковым. Если он равен 0, то число будет положительным, а если 1 — отрицательным.
Если разобраться в концепции старшего бита, можно без труда освоить три оставшихся побитовых оператора, которые называются операторами смещения битов:
Символ | Что означает |
---|---|
<< | Сдвиг битов влево |
>> | Сдвиг битов вправо |
>>> | Беззнаковый сдвиг битов вправо |
Операторы сдвига смещают все биты в левую или правую сторону, но делают это по-разному:
- >> не трогает старший бит, оставляя число с тем же знаком (отрицательным или положительным). Ячейки отрицательных чисел при >> заполняются единицами.
- >>> и << — затрагивают все биты. Освободившиеся ячейки справа заполняются нулями. Наполнение ячеек слева зависит от знака и оператора.
Звучит сложно, на деле — тоже сложно. Но попробуем разобраться на примере — разложим какое-то десятичное число на биты и посмотрим, как работает смещение битов.
В Java есть метод toBinaryString(), который показывает, как выглядят десятичные числа в двоичной системе. Но двоичные числа — это ещё не биты. Например, число 2 занимает 32 бита, но если обработать его методом toBinaryString(), на экране появятся только два из них: 1 и 0. Оставшиеся 30 нулей просто «обрезаются». Это происходит по той же причине, по которой мы, например, не пишем десятичное число 9 как 009.
Поэтому, чтобы лучше разобраться в работе побитовых операторов, лучше использовать модифицированный метод BinaryString, который раскладывает на биты уже так, как надо:
Сдвинув биты числа 1 два раза влево, мы получаем 4. А если потом сдвинуть их ещё 29 раз, получится минимальное значение типа int: –2 147 483 648.
Теперь попробуем сдвинуть наши биты уже в обратную сторону. Обратите внимание, как различается работа >> и >>>. В первом случае всё заполнится единицами и вы получите минусовое значение, а во втором на выходе будут просто нули.
Как это работает. С помощью операторов >> и >>> мы сдвигаем все биты числа вправо. Но при обычном сдвиге (>>) отрицательное число остаётся отрицательным, потому что мы не трогаем старший бит. При беззнаковом сдвиге (>>>) наоборот — отрицательное станет положительным, потому что мы затронем эту значимую единицу.
Составные операторы присваивания в Java
Зачем нужны: чтобы записывать выражения короче и автоматически приводить операнды к единому типу.
В Java есть сокращённые формы операторов присваивания — составные. Такие операторы выполняют действие между x и y, а получившееся значение помещают в x. Выглядят составные операторы так:
Плюс составных операторов в том, что они записываются короче и неявно приводят переменные к одному типу, если эти типы различаются. Например, в сокращённом варианте можно сложить дроби и числа без приведения, и нам за это ничего не будет. А в полной записи будет ошибка:
Приоритеты операторов Java
У каждого оператора Java есть свой приоритет. Чем он выше, тем раньше оператор выполнится в выражении. Бинарные и тернарный операторы (кроме присваивания) выполняются слева направо, а остальные (унарные и присваивания) — справа налево.
Резюме: что нужно запомнить
Мы рассмотрели все основные операторы в Java и их работу на примерах. Попробуем кратко резюмировать, что нужно вынести из этой статьи:
- Оператор — это языковая конструкция, которая выполняет действие над операндом.
- Операнд— это число, переменная, объект и так далее, с которыми оператор совершает какие-то действия (например, арифметическое и логическое).
- Операторы бывают унарные, бинарные и тернарные — это зависит от того, сколько операндов они обрабатывают.
- Арифметические операторы нужны для простых математических действий: сложения, вычитания, умножения, деления и деления с остатком.
- Унарные операторы работают только с одним операндом. Это унарные минус и плюс, инкремент, декремент, логическое и побитовое отрицание.
- Операторы сравнения сопоставляют значения двух операторов и возвращают ответ — true или false.
- Логические операторы заточены уже не на числа, а на целые выражения — и на их основе создают сложные условия, например, для работы в циклах.
- Тернарный оператор умеет работать сразу с тремя операндами: условием и двумя выражениями. То есть им вполне можно заменить ветвления типа if-else.
- Операторinstanceof определяет принадлежность объекта к классу.
- Побитовые операторы нужны для проведения операций с битами — если упростить, то с нулями и единицами в двоичной системе счисления.
- Составные операторы неявно приводят типы данных, если они разные.
- У каждого оператора есть свой приоритет.
Для более глубокого понимания темы можно почитать другие наши статьи: «Тип Boolean и операторы сравнения в Java» и «Логические операторы в Java». А если хотите совсем хорошо разобраться, почитайте официальную документацию Java — это вообще лучший способ освоить язык со всеми его тонкостями.