Bediener (Computerprogrammierung)

Im Computerprogrammierung, Betreiber sind Konstrukte innerhalb Programmiersprachen die sich allgemein verhalten Funktionen, aber was unterscheidet sich syntaktisch oder semantisch.

Häufige einfache Beispiele sind Arithmetik (z. B. Addition mit), Vergleich (z. B. "größer als" mit >), und logisch Operationen (z. UND, auch geschrieben && in einigen Sprachen). Weitere Beispiele sind Abtretung (normalerweise = oder : =), aufstellen Zugriff in einem Datensatz oder Objekt (normalerweise .), und die Bereichsauflösungsoperator (häufig :: oder .). Sprachen definieren normalerweise eine Reihe integrierter Betreiber, und in einigen Fällen können Benutzer vorhandenen Betreibern neue Bedeutungen hinzufügen oder sogar völlig neue Betreiber definieren.

Syntax

Syntaktisch Bediener im Gegensatz zu im Gegensatz zu Funktionen. In den meisten Sprachen können Funktionen als spezielle Form des Präfixbetreibers mit festgelegt angesehen werden Vorrang Niveau und Assoziativität, oft mit obligatorischer Verpflichtung Klammern z.B. Func (a) (oder (Func a) in Lispeln). Die meisten Sprachen unterstützen Programmierer-definierte Funktionen, können jedoch nicht wirklich behaupten, Programmierer-definierte Operatoren zu unterstützen, es sei denn, sie haben mehr als nur eine Präfixnotation und mehr als eine einzige Vorrangstufe. Semantisch Operatoren können als spezielle Funktionsform mit unterschiedlichen Aufrufnotation und einer begrenzten Anzahl von Parametern (normalerweise 1 oder 2) angesehen werden.

Die Position des Bedieners in Bezug auf seine Operanden kann sein Präfix, Infix oder Postfixund die Syntax von einem Ausdruck Die Einbeziehung eines Bedieners hängt von seiner ab Arity (Anzahl der Operanden), Vorrang und (falls zutreffend), Assoziativität. Die meisten Programmiersprachen unterstützen Binärbetreiber und ein paar Unary Operatoren, mit ein paar Unterstützung mehr Operanden, wie die ?: Bediener in C, das ternär ist. Es gibt Präfix -Unary -Operatoren, wie Unary Minus -xund postfix unary operatoren wie z. Nach der Inkremente x ++; und binäre Operationen sind Infix, wie z. x + y oder x = y. Infix -Operationen mit höherer Arität erfordern zusätzliche Symbole wie die ternärer Operator?: in c, geschrieben als a ? B: c - In der Tat, da dies das einzige gemeinsame Beispiel ist, wird es oft als als bezeichnet das ternärer Operator. Präfix- und Postfix -Operationen können jedoch alle gewünschten Arity unterstützen, wie z. 1 2 3 4 +.

Gelegentlich[1][2] Teile einer Sprache können als "Matchfix" oder "Circumfix" beschrieben werden[3][4] Operatoren, entweder um die Beschreibung oder Implementierung der Sprache zu vereinfachen. Ein Zirkumfixbetreiber besteht aus zwei oder mehr Teilen, die seine Operanden einschließen. Die Operatoren des Zirkumfixes haben die höchste Vorrang, wobei der Inhalt bewertet wird und der resultierende Wert im umgebenden Ausdruck verwendet wird. Der bekannteste Zirkumfixoperator sind die oben genannten Klammern, die angeben, welche Teile eines Ausdrucks vor anderen bewertet werden sollen. Ein weiteres Beispiel aus der Physik ist das Innenprodukt Notation von Dirac's Bra -Ket -Notation. Die Operatoren für Zirkumfix sind besonders nützlich, um Operationen zu bezeichnen, die viele oder unterschiedliche Operanden betreffen.

Die Spezifikation einer Sprache gibt die Syntax an, die sie unterstützt, während Sprachen wie z. Prolog Diese Unterstützungsprogrammierer-definierter Operatoren erfordern, dass die Syntax vom Programmierer definiert wird.

Semantik

Die Semantik der Operatoren hängt insbesondere von Wert, Bewertungsstrategie und Argument-Passingmodus (wie dem booleschen Kurzschluss) ab. Einfach ein Ausdruck Die Einbeziehung eines Operators wird in irgendeiner Weise und der resultierenden bewertet Wert Kann nur ein Wert (ein R-Wert) oder ein Objekt sein, das Zuordnung (ein L-Wert) zulässt.

In einfachen Fällen ist dies mit den üblichen Funktionsaufrufen identisch. Zum Beispiel Addition x + y ist im Allgemeinen einem Funktionsaufruf äquivalent add (x, y) und weniger als Vergleich x <y zu lt (x, y)Dies bedeutet, dass die Argumente auf ihre übliche Weise bewertet werden, dann wird einige Funktionen bewertet und das Ergebnis als Wert zurückgegeben. Die Semantik kann jedoch erheblich unterschiedlich sein. Zum Beispiel in der Zuordnung a = b das Ziel a wird nicht bewertet, sondern statt Lage (Adresse) wird verwendet, um den Wert von zu speichern b - korrespondierend zu Call-by-Reference Semantik. Darüber hinaus kann eine Zuordnung eine Anweisung (kein Wert) oder ein Ausdruck (Wert) sein, wobei der Wert selbst entweder ein R-Wert (nur ein Wert) oder ein L-Wert (in der Lage ist, zugewiesen zu werden). Als ein weiteres Beispiel die Bereichsauflösungsoperator:: und der Element Access Operator. (wie in Foo :: Bar oder A.B.) arbeiten nicht auf Werten, sondern auf Namen, im Wesentlichen Call-by-Namen Semantik, und ihr Wert ist ein Name.

Die Verwendung von L-Werten als Bedieneroperanden ist in Unary besonders bemerkenswert Inkrement- und Decrement -Operatoren. In C ist beispielsweise die folgende Erklärung legal und gut definiert und hängt davon ab, dass die Array-Indexierung einen L-Wert zurückgibt:

x = ++a[i]; 

Eine wichtige Verwendung ist, wenn ein links-assoziativer Binäroperator sein linke Argument modifiziert (oder einen Nebeneffekt erzeugt) und dann dieses Argument als L-Wert bewertet.[a] Dies ermöglicht eine Folge von Operatoren, die alle das ursprüngliche Argument beeinflussen, und ermöglicht a fließende Schnittstelle, ähnlich zu Methode Kaskadierung. Ein häufiges Beispiel ist das << Operator im C ++ iostream Bibliothek, die eine fließende Ausgabe ermöglicht, wie folgt:

Cout << "Hallo" << "" " << "Welt!" << Endl; 

Benutzerdefinierte Bediener

Eine Sprache kann eine feste Anzahl integrierter Operatoren enthalten (z. +, -, *, <, <=,!, =usw. in C und C ++, Php) oder es kann die Erstellung von Programmierern definierten Operatoren ermöglichen (z. Prolog,[5] Samen7,[6] F#, Ocaml, Haskell). Einige Programmiersprachen beschränken den Bedienungssymbolen auf Sonderzeichen wie + oder : = Während andere auch Namen wie zulassen div (z.B. Pascal).

Die meisten Sprachen haben eine integrierte Reihe von Betreibern, erlauben jedoch keine benutzerdefinierten Operatoren, da dies die Parsen erheblich kompliziert.[b] Mit vielen Sprachen können Bediener nur für integrierte Typen verwendet werden, andere ermöglichen es vorhandenen Betreibern jedoch für benutzerdefinierte Typen. Dies ist bekannt als als Bedienerüberlastung. Einige Sprachen ermöglichen es jedoch, dass neue Operatoren definiert werden, entweder zum Kompilieren oder zur Laufzeit. Dies kann eine Metaprogrammierung (Angabe der Operatoren in einer separaten Sprache) oder innerhalb der Sprache selbst beinhalten. Die Definition neuer Operatoren, insbesondere der Laufzeitdefinition, macht häufig korrekt Statische Analyse von Programmen unmöglich, da die Syntax der Sprache möglicherweise abgeschlossen sein kann, erfordert auch das Erstellen des Syntaxbaums möglicherweise das Lösen des Anstill-Problems, was unmöglich ist. Dies geschieht für PerlZum Beispiel und einige Dialekte von Lispeln.

Beispiele

Häufige Beispiele, die syntaktisch unterscheiden, sind mathematisch Rechenoperationen, z.B. ">" für "größer als", mit Namen, die oft außerhalb der Sprache der Sprache von Kennungen Für Funktionen und mit einer anderen Syntax von der Syntax der Sprache für Anruffunktionen aufgerufen. Als Funktion würde "größer als" im Allgemeinen von einer Kennung benannt, wie z. gt oder größer als und als Funktion aufgerufen, als gt (x, y). Stattdessen verwendet die Operation das spezielle Charakter > (was während während dessen separat tokenisiert wird lexikalische Analyse) und Infixnotation als x> y.

Häufige Beispiele, die sich semantisch unterscheiden (im Argument -Passing -Modus) Kurzschlussbewertung: z.B. Eine Kurzschlusskonjunktion (x und y), die nur spätere Argumente bewertet, wenn frühere in einer Sprache mit strengen Call-by-Wert-Funktionen nicht falsch sind. Dies verhält sich stattdessen ähnlich wie if/dann/sonst.

Zu den weniger häufigen Betreibern gehören:

Zusammenstellung

Ein Compiler kann Betreiber und Funktionen mit implementieren Unterroutine -Anrufe oder mit Inline -Code. Einige integrierte Operatoren, die von einer Sprache unterstützt werden Anweisungen häufig gefunden auf Zentrale Verarbeitungseinheitenobwohl andere (z.B. '+' verwendet zum Ausdruck String-Verkettung) kann komplizierte Implementierungen haben.

Bedienerüberlastung

In einigen Programmiersprachen kann ein Bediener sein ad hoc polymorphdas heißt, haben Definitionen für mehr als eine Art von Daten (wie in Java bei dem die + Der Bediener wird sowohl für die Zugabe von Zahlen als auch für die Verkettung von Saiten verwendet. Ein solcher Betreiber soll sein überladen. In Sprachen, die die Überlastung des Operators durch den Programmierer unterstützen (wie z. C ++.

Im Beispiel Wenn order_date> "12.12.2011" und order_date <"01/01/2013", fahren Sie sonst weiter an., Die Operatoren sind: ">" (größer als) "und" und "<" (weniger als).

Operand Zwang

Einige Sprachen ermöglichen es auch, dass die Operanden eines Operators implizit konvertiert werden oder gezwungen, zu geeigneten Datentypen für den Vorgang. Zum Beispiel in Perl Zwangsregeln führen zu 12 + "3.14" Erzeugung des Ergebniss von 15.14. Der Text "3.14" wird in die Nummer 3.14 umgewandelt, bevor Addition stattfinden kann. Des Weiteren, 12 ist eine Ganzzahl und 3.14 ist entweder eine schwebende oder feste Punktzahl (eine Zahl, die eine Dezimalstelle enthält), sodass die Ganzzahl dann in einen schwimmenden Punkt bzw. feste Punktzahl umgewandelt wird.

JavaScript Befolgt entgegengesetzten Regeln - erstellt den gleichen Ausdruck oben und wandelt die Ganzzahl um 12 in eine Zeichenfolge "12"und dann die beiden Operanden zu formen, um zu bilden "123.14".

In Gegenwart von Zwang in einer Sprache muss sich der Programmierer über die spezifischen Regeln für Operand -Typen und den Betriebsergebnis -Typ bewusst sein, um subtile Programmierfehler zu vermeiden.

Bedienerfunktionen in Programmiersprachen

Die folgende Tabelle zeigt die Bedienerfunktionen in mehreren Programmiersprachen:

Programmiersprache Nicht -Alphanumeric -Operator -Symbole Alphanumeric Operator Symbole Präfix Infix Postfix Vorrang Assoziativität Überlastung Programmierer-definierte Überlastung Programmierer-definierte Operatorsymbole
Algol 68 +**** /%*%× - +<=> => = /= & -: = +: =*: = /: =%: =%*: = +=: =:: / =:

(Alle Betreiber haben Fett gedruckt Alphanumerische Äquivalente, C.F. Nächste Spalte. Einige haben nicht ASCII Äquivalente, C.F. unter.)¬ +× ⊥ ↑ ↓ ⌊ ⌈ × ÷ ÷ × ÷* □ ≤ ≥ ≠ ∧ ∨ ×: = ÷: = ÷ ×: = ÷*: =%×: =: ≠:

nicht Abs arg Behälter vorhanden Leng eben seltsam reprieren runden verkürzen i Shl Shr hoch Nieder LWB UPB lt Le Ge gt Gl ne und oder Über Mod Elem minusab Plusab Timesab Divab Überab Modab Plusto ist nicht Ja Ja Nein Ja (Präfixbetreiber haben immer Priorität 10) Infix -Operatoren sind links assoziativ, Präfixbetreiber sind rechts assoziativ Ja Ja Ja
Apl + - × ÷ ⌈ ⌊ * ⍟ | ! ○ ~ ∨ ∧ ⍱ ⍲ <≤ = ≥> ≠. @ ≡ ≢ ⍴, ⍪ ⍳ ⍳ ↑ ↓? ⍒ ⍋ ⍉ ⌽ ∊ ⊥ ⊤ ⍎ ⍕ ⍕ ⊂ ⊃ ∪ ∩ ⌷ ⌷ ∘ → ← / ⌿ \ ⍀ ⍣ & ⍨ ⊆ ⊆ ⊣ ⊢ ⍠ ⍤ ⌸ ⌺ ⍸ ⍸ Alphanumerische Symbole benötigen ein ⎕ vor dem Schlüsselwort Ja (Nur Funktionen erster Ordnung) Ja Ja (Nur höhere Funktionen) Funktionen höherer Ordnung gehen Funktionen erster Ordnung voraus Funktionen höherer Ordnung sind links assoziative Funktionen erster Ordnung sind rechts assoziativ Ja Ja Ja (nur alphanumerisch)
C () [] ->. ! ~ ++ - + - * & /% << >> <= >> = ==! = ^ | && || ?: = += -= *= /=%= & = ^= Größe von Ja Ja Ja Ja Ja Ja Nein Nein
C ++ (mehr)) Größe von Typid Neu löschen Wurf deklart static_cast Dynamische Besetzung neu interpret_cast const_cast Ja Ja Ja Ja Ja Ja Ja Nein
C# (mehr)) Gleich wie C/C ++ zusammen mit ?.? [] ??? = Größe von Name von neuem Stackalloc erwartet Wurf Unkontrolliert überprüft ist wie Delegierter Standard TRUE FALSE
Linq: von ausgewählten wo Gruppe ... von Gruppe ... von ... in join ... in ... on ... Gärte Join ... in ... Equals ... in OrderBy OrderBy. ..absteigend
Roslyn-nur: __makeref __refValue __reftype
Ja Ja Ja Ja Ja Ja Ja Nein
Java Gleich wie C/C ++ Neu Wurf Instanz Ja Ja Ja Ja Ja Ja Nein Nein
Eiffel [] + - * / // = / = nicht und oder impliziert "und dann" oder sonst " Ja Ja Nein Ja Ja Nein Ja Ja
Haskell + - * / ^ ^^ ** ​​== / => <> = <= && || >> = >> $! . ++ !! : Viele mehr in gemeinsamen Bibliotheken Der Name der Funktion muss in Backticks gesteckt werden Ja Ja Nein Ja Ja Ja, verwenden Geben Sie Klassen ein Ja
Pascal * / + - = <> <> <=> =: = nicht div Mod und oder in Ja Ja Nein Ja Ja Ja Nein Nein
Perl -> ++ -**! ~ \ + -. = ~! ~ * /% <> <=> = ==! = <=> ~~ & | ^ && || '' Drucken sortieren chmod chdir rand und oder nicht xor lt gt le ge eq ne cmp x Ja Ja Ja Ja Ja Ja Ja Nein
Php [] ** ++ - ~ @![7] * /% + -. << >> <= >> = ==! ===! == <> <=> & ^ | && || ? ?: = += -= *= ** = /=. =%= & = | = ^= << = >> = Klon neues nicht fester Druck -Echo -Emission Instanz und oder xor Ja Ja Ja Ja Ja Nein Nein Nein
Pl/i () -> + - * / **> ¬ >> = = ¬ = <= <¬ <¬ & | || Ja Ja Nein Ja Ja Nein Nein Nein
Prolog :-?-; . = .. = \ = <= <> => == \ == - + / * Spion Nospy nicht ist mod Ja Ja Ja Ja Ja Nein Nein Ja
Raku ++ - **! ~ ~~ * / + -. <> <=> = ==! = <=> & | ^ && || // [8] Drucken sortieren chmod chdir rand und oder nicht xor lt gt le ge eq ne leg cmp x xx Ja Ja Ja Ja Ja Ja Ja Ja[9]
Samen7 {} [] -> **! + - * / << >> &> <| = <>>> = <= <&: = +: = -: = *: = /: = <<: = >>: = &: = @: =: = Varconv analysieren Konj div Rem MDIV Mod mal multin nicht und oder Ziffern LPAD RPAD LPAD0 Ja Ja Ja Ja Ja Ja Ja Ja
Smalltalk (Ja - bis zu zwei Zeichen[10])) Alphanumerische Symbole benötigen einen Dickdarm nach dem Schlüsselwort Nein Ja Ja Nein Nein Ja Ja Ja
Schnell Jede Unicode -Symbol -Zeichenfolge außer ., einschließlich ! ~+-* /% =+ =- =* = / =% &+ &- &* = &+ = &- = &* && || << >> & | ^ ==! = <= >> = ?? ... .. < in der Standardbibliothek ist wie wie? Ja Ja Ja Ja (definiert als Teilreihenfolge in Vorranggruppen) Ja (definiert als Teil der Vorranggruppen) Ja Ja Ja
Visual Basic .net (). ! ? ()?. ?! + - * / \ & << >> <= >> = ^ <> = + = - = * = / = \ = & = ^ = << = >> = Neu wartete mod wie ist nicht und andalso oder Orelse xor if (..., ...) if (..., ..., ...) getXmlnameSpace (...) Gettype (...) Nameof ( ...) typeof ... is typeof ... isnot directcast (..., ...) trycast (..., ...) ctype (..., ...) cbool (...) CByte (...) cchar (...) CDate (...) CDEC (...) CDBL (...) cint (...) clng (...) cobj (...) csbyte ( ...) cshort (...) csng (...) cstr (...) cuint (...) Culng (...) Cushort (...)
Linq: Von Aggregat ... in ausgewählte Unterscheidung wo ...[Ascending|Descending] Nehmen Überspringen Lassen Sie Gruppe ... von ... in Join ... on <Group Join ... on ... in>
Ja Ja Ja Ja Ja Ja Ja Nein

Siehe auch

Anmerkungen

  1. ^ Umgekehrt ein rechter Assoziativbetreiber mit seinem richtigen Argument, obwohl dies seltener ist.
  2. ^ Die Einführung eines neuen Operators ändert die lexikalische Spezifikation der Sprache, die die verändert lexikalische Analyse. Die Arität und Vorrang des Operators ist dann Teil der Phrase-Syntax der Sprache, die die Analyse der Phrase-Ebene ändert. Zum Beispiel einen Bediener hinzufügen @ Erfordert Lexing und Token dieses Charakters, und die Phrasenstruktur (Syntaxbaum) hängt von der Arität und Vorrang dieses Operators ab.

Verweise

  1. ^ "Operator -Eingangsformulare - Wolfram -Sprachdokumentation". reference.wolfram.com.
  2. ^ "Maxima 5.42.0 Handbuch: 7. Operatoren". maxima.sourceforge.net.
  3. ^ "Präfix-, Postfix- und Zirkumfix -Operatoren". Mythryl.org.
  4. ^ "Operatoren". doc.perl6.org.
  5. ^ "Swi-prolog-op/3". www.swi-prolog.org.
  6. ^ "Einen Betreiber deklarieren". Seed7.SourceForge.net.
  7. ^ "PHP: Fehlersteuerungsoperatoren - Handbuch". php.net.
  8. ^ "Operatoren". docs.perl6.org.
  9. ^ "Funktionen". docs.perl6.org.
  10. ^ Goldberg, Adele. "SmallTalk-80: Die Sprache und ihre Implementierung, S. 27, ISBN 0-201-11371-6" (PDF).