Из Википедии, бесплатной энциклопедии
  (Перенаправлено от Оператора (программирование) )
Перейти к навигации Перейти к поиску

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

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

Синтаксис [ править ]

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

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

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

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

Семантика [ править ]

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

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

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

х  =  ++ а [ я ];

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

cout  <<  "Hello"  <<  ""  <<  "world!"  <<  endl ;

Пользовательские операторы [ править ]

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

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

Примеры [ править ]

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

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

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

  • Оператор-запятая :e, f
  • Оператор разыменования : *pи оператор адреса:&x
  • ?: или тернарный оператор:number = spell_out_numbers ? "forty-two" : 42
    • Оператор Элвиса :x ?: y
  • Нулевой оператор объединения :x ?? y
  • Оператор космического корабля (для трехстороннего сравнения ):x <=> y

Компиляция [ править ]

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

Перегрузка оператора [ править ]

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

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

Принуждение операнда [ править ]

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

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

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

Возможности оператора в языках программирования [ править ]

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

См. Также [ править ]

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

Заметки [ править ]

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

Ссылки [ править ]

  1. ^ «Формы ввода оператора - документация на языке Wolfram Language» . reference.wolfram.com .
  2. ^ «Руководство по Maxima 5.42.0: 7. Операторы» . maxima.sourceforge.net .
  3. ^ «Операторы префикса, постфикса и кружка» . Mythryl.org .
  4. ^ «Операторы» . doc.perl6.org .
  5. ^ "SWI-Prolog - op / 3" . www.swi-prolog.org .
  6. ^ «Объявить оператора» . seed7.sourceforge.net .
  7. ^ «Операторы» . docs.perl6.org .
  8. ^ «Функции» . docs.perl6.org .
  9. ^ «PHP: Операторы контроля ошибок - Руководство» . php.net .
  10. ^ Голдберг, Адель. «Smalltalk-80: язык и его реализация, стр. 27, ISBN 0-201-11371-6» (PDF) .