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 имеют наивысший приоритет: их содержимое оценивается, а полученное значение используется в окружающем выражении. Наиболее знакомым оператором циркумфикса являются упомянутые выше круглые скобки, которые используются для указания того, какие части выражения должны оцениваться раньше других. Другим примером из физики является обозначение внутреннего произведения нотации Дирака . Операторы циркумфикса особенно полезны для обозначения операций, которые включают в себя множество или различное количество операндов.

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

Семантика

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

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

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

х = ++ а [ я ];  

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

cout << "Привет" << " " << "мир!" << конец ;        

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

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

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

Примеры

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

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

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

Сборник

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

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

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