Введение

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

В компьютерном программировании операторы — это конструкции, определенные в языках программирования, которые обычно ведут себя как функции, но отличаются синтаксически или семантически. Распространенные простые примеры включают арифметические операции (например, сложение с помощью +), операции сравнения (например, "больше", чем с помощью >) и логические операции (например, И, также записываемое как && в некоторых языках). Более сложные примеры включают присваивание (обычно = или :=), доступ к полям записи или объекта (обычно .) и оператор разрешения области видимости (часто :: или .). Языки программирования обычно определяют набор встроенных операторов, а в некоторых случаях позволяют пользователям добавлять новые значения существующим операторам или даже определять совершенно новые операторы.

Синтаксис

Синтаксически операторы обычно противопоставляются функциям. В большинстве языков функции можно рассматривать как особую форму префиксного оператора с фиксированным уровнем приоритета и ассоциативностью, часто с обязательными скобками, например, Func(a) (или (Func a) в Lisp). Большинство языков поддерживают функции, определенные программистом, но не могут утверждать, что поддерживают операторы, определенные программистом, если они не имеют нотации, отличной от префиксной, и более одного уровня приоритета. Семантически операторы можно рассматривать как специальную форму функции с различной нотацией вызова и ограниченным числом параметров (обычно 1 или 2). Положение оператора относительно его операндов может быть префиксным, инфиксным или постфиксным, а синтаксис выражения, включающего оператор, зависит от его аритета (числа операндов), приоритета и (если применимо) ассоциативности. Большинство языков программирования поддерживают бинарные операторы и несколько унарных операторов, при этом некоторые поддерживают больше операндов, например, оператор `? :` в C, который является тернарным. Существуют префиксные унарные операторы, такие как унарный минус `-x`, и постфиксные унарные операторы, такие как постфиксный инкремент `x++`; а бинарные операции обычно инфиксные, такие как `x + y` или `x = y`. Инфиксные операции с более высокой аритетой требуют дополнительных символов, например, тернарный оператор `? :` в C, записываемый как `a ? b : c` – и, поскольку это единственный распространенный пример, его часто называют тернарным оператором. Префиксные и постфиксные операции могут поддерживать любую желаемую аритету, например, `1 2 3 4 +`. Иногда части языка могут быть описаны как операторы "matchfix" или "circumfix", либо для упрощения описания языка, либо для его реализации. Circumfix-оператор состоит из двух или более частей, которые заключают в себя его операнды. Circumfix-операторы имеют наивысший приоритет, их содержимое вычисляется, а полученное значение используется в окружающем выражении. Наиболее распространенным примером circumfix-оператора являются вышеупомянутые скобки, используемые для указания того, какие части выражения должны быть вычислены раньше других. Другой пример из физики – обозначение внутреннего произведения в нотации Дирака (bra-ket). Circumfix-операторы особенно полезны для обозначения операций, которые включают в себя много или переменное количество операндов. Спецификация языка определяет синтаксис поддерживаемых им операторов, в то время как языки, такие как Prolog, поддерживающие операторы, определенные программистом, требуют, чтобы синтаксис определялся программистом.

Определенные пользователем операторы

Язык может содержать фиксированное количество встроенных операторов (например, в C и C++, PHP), или он может позволять создание операторов, определяемых программистом (например, Prolog, Seed7, F#, OCaml, Haskell). Некоторые языки программирования ограничивают символы операторов специальными символами, такими как или , в то время как другие допускают также имена, такие как div (например, Pascal). Большинство языков имеют встроенный набор операторов, но не разрешают определение пользовательских операторов, поскольку это значительно усложняет разбор. Многие языки позволяют использовать операторы только для встроенных типов, но другие позволяют использовать существующие операторы для пользовательских типов; это известно как перегрузка операторов. Некоторые языки позволяют определять новые операторы либо во время компиляции, либо во время выполнения. Это может включать метапрограммирование (определение операторов на отдельном языке) или непосредственно в языке. Определение новых операторов, особенно во время выполнения, часто делает невозможным корректный статический анализ программ, поскольку синтаксис языка может быть Тьюринг-полным, и даже построение синтаксического дерева может потребовать решения проблемы останова, что невозможно. Это справедливо, например, для Perl и некоторых диалектов Lisp.

Сборник

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

Перегрузка оператора

В некоторых языках программирования оператор может быть ad hoc полиморфным, то есть иметь определения для более чем одного типа данных (например, в Java, где оператор используется как для сложения чисел, так и для конкатенации строк). Такой оператор называется перегруженным. В языках, поддерживающих перегрузку операторов программистом (например, C++), но имеющих ограниченный набор операторов, перегрузка операторов часто используется для определения специализированного поведения операторов. В примере операторами являются: > (больше чем) и < (меньше чем).

Операция и принуждение

Некоторые языки также позволяют неявно преобразовывать, или приводить, операнды оператора к подходящим типам данных для выполнения операции. Например, в Perl правила приведения приводят к тому, что 12 + "3,14" дает результат 15,14. Текст "3,14" преобразуется в число 3,14 перед выполнением сложения. Более того, 12 является целым числом, а 3,14 – числом с плавающей или фиксированной точкой (число, содержащее десятичную часть), поэтому целое число затем преобразуется соответственно в число с плавающей или фиксированной точкой. JavaScript следует противоположным правилам: при вычислении того же выражения он преобразует целое число 12 в строку "12", а затем объединяет два операнда, формируя строку "123,14". При наличии приведения типов в языке программист должен учитывать конкретные правила, касающиеся типов операндов и типа результата операции, чтобы избежать скрытых ошибок в программе.