stringtranslate.com

Оператор (компьютерное программирование)

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

Обычные простые примеры включают арифметические (например, сложение с +), сравнение (например, « больше чем » с >) и логические операции (например AND, также написанные &&в некоторых языках). Более сложные примеры включают присваивание (обычно =или :=), доступ к полю в записи или объекте (обычно .) и оператор разрешения области действия (часто ::или .). Языки обычно определяют набор встроенных операторов и в некоторых случаях позволяют пользователям добавлять новые значения к существующим операторам или даже определять совершенно новые операторы.

Синтаксис

Синтаксически операторы обычно противопоставляются функциям . В большинстве языков функции можно рассматривать как особую форму префиксного оператора с фиксированным уровнем приоритета и ассоциативностью, часто с обязательными скобками , например Func(a)(или (Func a)в Lisp ). Большинство языков поддерживают функции, определяемые программистом, но не могут по-настоящему заявлять о поддержке операторов, определяемых программистом, если только они не имеют более чем префиксной нотации и более чем одного уровня приоритета. Семантически операторы можно рассматривать как особую форму функции с другой нотацией вызова и ограниченным числом параметров (обычно 1 или 2).

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

Иногда [1] [2] части языка могут быть описаны как операторы « matchfix » или « circumfix » [3] [4] , либо для упрощения описания языка, либо для его реализации. Оператор circumfix состоит из двух или более частей, которые заключают в себе его операнды. Операторы circumfix имеют наивысший приоритет, их содержимое оценивается, а полученное значение используется в окружающем выражении. Наиболее известным оператором circumfix являются упомянутые выше скобки, используемые для указания того, какие части выражения должны быть оценены раньше других. Другим примером из физики является запись внутреннего произведения нотации Dirac's bra–ket . Операторы circumfix особенно полезны для обозначения операций, в которых задействовано много или разное количество операндов.

Спецификация языка определяет синтаксис поддерживаемых им операторов, в то время как языки, такие как Prolog , которые поддерживают операторы, определяемые программистом, требуют, чтобы синтаксис был определен программистом.

Семантика

Семантика операторов в частности зависит от значения, стратегии оценки и режима передачи аргумента (например, логического короткого замыкания). Проще говоря, выражение, включающее оператор, оценивается каким-то образом, и результирующее значение может быть просто значением (r-значением) или может быть объектом, допускающим присваивание (l-значением).

В простых случаях это идентично обычным вызовам функций; например, сложение x + yобычно эквивалентно вызову функции add(x, y), а сравнение «меньше» — x < y, lt(x, y)что означает, что аргументы оцениваются обычным способом, затем оценивается некоторая функция и результат возвращается как значение. Однако семантика может существенно отличаться. Например, при присваивании a = bцель aне оценивается, но вместо этого ее местоположение (адрес) используется для хранения значения b– в соответствии с семантикой вызова по ссылке . Кроме того, присваивание может быть оператором (без значения) или выражением (значением), причем само значение может быть либо r-значением (просто значением), либо l-значением (которому можно присвоить значение). В качестве другого примера можно привести оператор разрешения области действия  :: и оператор доступа к элементу . (как в Foo::Baror a.b) оперируют не значениями, а именами , по сути семантикой вызова по имени , и их значением является имя.

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

х = ++ а [ я ];  

Важное применение — когда левоассоциативный бинарный оператор изменяет свой левый аргумент (или производит побочный эффект ), а затем оценивает этот аргумент как l-значение. [a] Это позволяет последовательности операторов, все из которых влияют на исходный аргумент, позволяя текучий интерфейс , аналогичный каскадированию методов . Типичным примером является <<оператор в библиотеке C++ iostream, который позволяет текучий вывод, как показано ниже:

cout << "Привет" << " " << "мир!" << endl ;        

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

Язык может содержать фиксированное количество встроенных операторов (например , +, -, *, <, <=, !, = и т. д. в C и C++ , PHP ), или он может позволять создавать операторы, определяемые программистом (например, Prolog , [5] Seed7 , [6] F# , OCaml , Haskell ). Некоторые языки программирования ограничивают символы операторов специальными символами, такими как + или := , в то время как другие также допускают имена, такие как (например, Pascal ).div

Большинство языков имеют встроенный набор операторов, но не допускают определяемых пользователем операторов, поскольку это значительно усложняет синтаксический анализ. [b] Многие языки позволяют использовать операторы только для встроенных типов, но другие позволяют использовать существующие операторы для определяемых пользователем типов; это известно как перегрузка операторов . Некоторые языки позволяют определять новые операторы, однако, либо во время компиляции, либо во время выполнения. Это может включать метапрограммирование (указание операторов на отдельном языке) или внутри самого языка. Определение новых операторов, особенно определение во время выполнения, часто делает невозможным правильный статический анализ программ, поскольку синтаксис языка может быть полным по Тьюрингу, поэтому даже построение синтаксического дерева может потребовать решения проблемы остановки, что невозможно. Это происходит , например, для Perl и некоторых диалектов Lisp .

Примеры

Распространенными примерами, которые синтаксически отличаются от функций, являются реляционные операторы , например, ">" для " больше чем ", имена которых часто выходят за рамки набора идентификаторов языка для функций и вызываются с помощью синтаксиса, отличного от синтаксиса языка для вызова функций. Как функция, "больше чем" обычно именуется идентификатором, например, gtили greater_thanи вызывается как функция, как gt(x, y). Вместо этого операция использует специальный символ >(который разбивается на отдельные символы во время лексического анализа ) и инфиксную нотацию, как x > y.

Обычными примерами, которые отличаются семантически (режимом передачи аргументов), являются булевы операции, которые часто содержат оценку с коротким замыканием : например, конъюнкция с коротким замыканием (X AND Y), которая оценивает только последующие аргументы, если предыдущие не являются ложными, в языке со строгими функциями вызова по значению. Это ведет себя аналогично if/then/else.

Менее распространённые операторы включают в себя:

Компиляция

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

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

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

В примере используются операторы: (больше чем) и (меньше чем).IF ORDER_DATE > "12/31/2011" AND ORDER_DATE < "01/01/2013" THEN CONTINUE ELSE STOP>AND<

Принудительное приведение операнда

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

JavaScript следует противоположным правилам — найдя то же самое выражение выше, он преобразует целое число 12в строку "12", а затем объединяет два операнда для формирования "123.14".

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

Функции операторов в языках программирования

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

Смотрите также

Примечания

  1. ^ Наоборот, правоассоциативный оператор с правым аргументом, хотя это встречается реже.
  2. ^ Введение нового оператора изменяет лексическую спецификацию языка, что изменяет лексический анализ . Арность и приоритет оператора затем являются частью синтаксиса фразы языка, что изменяет анализ на уровне фразы. Например, добавление оператора @требует лексического разбора и токенизации этого символа, а структура фразы (синтаксическое дерево) зависит от арности и приоритета этого оператора.

Ссылки

  1. ^ «Формы ввода оператора — Документация по языку Wolfram». reference.wolfram.com .
  2. ^ "Руководство Maxima 5.42.0: 7. Операторы". maxima.sourceforge.net .
  3. ^ «Операторы префикса, постфикса и циркумфикса». mythryl.org .
  4. ^ "Операторы". doc.perl6.org .
  5. ^ "SWI-Пролог -- op/3" . www.swi-prolog.org .
  6. ^ "Объявите оператор". seed7.sourceforge.net .
  7. ^ «УЧЕБНОЕ ВВЕДЕНИЕ В ЯЗЫК B».
  8. ^ "PHP: Операторы контроля ошибок - Руководство". php.net .
  9. ^ "Операторы". docs.perl6.org .
  10. ^ "Функции". docs.perl6.org .
  11. ^ Голдберг, Адель. «Smalltalk-80: Язык и его реализация», стр. 27, ISBN 0-201-11371-6 (PDF) .