Referenz - Ausdrücke und Operatoren
Ausdrücke setzen sich aus Werten und Operatoren zusammen.
Ein Wert kann eine Zahl (z. B. 4), ein STRING (z. B. "hallo") oder eine Variable (z. B. x) sein. Ein Ausdruck kann aus einem einzelnen Wert oder aus mehreren, durch Operatoren verknüpften Werten bestehen (z. B. 4*x).
Ein Operator führt mathematische oder logische Operationen an den Werten aus (z. B. 4*x; 4 und x sind Werte, * ist der Operator für die Multiplikation). Operatoren werden für die meisten mathematischen Operationen, Vergleiche (z. B. x > 4), logische Tests (z. B. IF x > 4 AND x < 10 THEN, wobei AND ein logischer Operator ist) und Stringmanipulationen verwendet. Diese werden vor allem in Bedingungsstrukturen eingesetzt.
Die Operatoren lassen sich einteilen in:
- mathematische Operatoren
- Vergleichsoperatoren
- logische Operatoren
- Stringoperatoren
- Kurzformen (kombinierte Operatoren und Variablen-Initiatoren)
Mathematische Operatoren
Zu den mathematischen Operatoren zählen:
- Negierung (-)
- Potenzierung (^)
- Division und Integerdivision (/, \)
- Multiplikation (*)
- Bitverschiebung nach links/rechts (SHL, SHR)
- Addition und Subtraktion (+, -)
Vergleichsoperatoren
Vergleichsoperatoren geben abhängig von der gegebenen Bedingung true (-1) oder false (0) aus. Sie vergleichen zwei Ausdrücke. Geprüft kann werden, ob ein Ausdruck größer, kleiner, ungleich, gleich, größer/gleich oder kleiner/gleich einem anderen ist. Zu den Vergleichsoperatoren zählen:
- > größer als
- < kleiner als
- = gleich
- >= größer/gleich
- <= kleiner/gleich
- <> ungleich (größer oder kleiner)
Beispiel:
DIM money AS INTEGER
INPUT "Wieviel Geld haben Sie? ", money
IF money < 100 THEN
PRINT "Sie haben weniger als $100, lassen Sie mich"
PRINT "Ihnen weitere $100 geben."
money = money + 100
PRINT "Jetzt haben Sie $" & money
ELSE
PRINT "Sie haben genau oder mehr als $100. Das"
PRINT "reicht vorerst."
END IF
SLEEP
Logische Operatoren
Logische Operatoren helfen, Entscheidungen unter Berücksichtigung mehrerer Faktoren zu treffen. Beispiel:
Ich möchte Schuhe, die rot sind AND (und) weniger kosten als $100.
Die meisten Entscheidungen können mit AND (beide Bedingungen müssen wahr sein), OR (mindestens eine Bedingung muss erfüllt sein), NOT (die Bedingung darf nicht erfüllt sein) oder XOR (eine Bedingung muss erfüllt sein, die andere darf es nicht sein) getroffen werden. Es gibt aber auch noch weitere logische Operatoren:
- AND - Sind beide Bedingungen erfüllt?
- OR - Ist mindestens eine Bedingung erfüllt?
- NOT - Ist die Bedingung nicht erfüllt?
- XOR - Ist eine Bedingung erfüllt, aber die andere nicht?
- EQV - Sind beide Bedingunen gleich?
- IMP - Folgt die zweite Bedingung auf die ersten? a IMP b entspricht (NOT a) OR b
- ANDALSO - ähnlich wie AND, jedoch wird die zweite Bedingung nur ausgewertet, wenn nötig
- ORELSE - ähnlich wie OR, jedoch wird die zweite Bedingung nur ausgewertet, wenn nötig
Siehe dazu auch Bit-Operatoren.
Hierarchie der Operatoren
Mehrere Operatoren in einer Anweisung werden nach einer vordefinierten Reihenfolge abgearbeitet. Ein Operator mit höherer Hierarchie wird vor einem Operator abgearbeitet, der eine niedrigere Hierarchie besitzt. Haben zwei Operatoren die gleiche Hierarchie, werden sie in der Reihenfolge abgearbeitet, in der sie auftreten. Ist eine andere Reihenfolge bei der Abarbeitung gewünscht, kann diese durch eine Klammerung der Ausdrücke erreicht werden.
Die Abarbeitung von Operatoren der gleichen Hierarchie kann von links nach rechts oder aber von rechts nach links erfolgen. Z. B. ist a+b+c gleichbedeutend mit (a+b)+c, während **a gleichbedeutend mit *(*a) ist. Ein 'N/A' gibt an, dass aufgrund der Eigenschaften des Operators keine Richtung existiert.
Die folgende Tabelle enthält alle Operatoren absteigend nach ihrer Hierarchie:
Operator | Klassifizierung | Kardinalität | Bedeutung | Assoziativität |
19 | ||||
---|---|---|---|---|
CAST | Funktion | unär | Typumwandlung | N/A |
PROCPTR | Funktion | unär | Adressoperator | N/A |
STRPTR | Funktion | unär | Adressoperator | N/A |
VARPTR | Funktion | unär | Adressoperator | N/A |
18 | ||||
[] | Zugriffsoperator | / | String-/Pointerindex | von links |
() | Indizierung | / | Arrayindex | von links |
() | Auswertungsoperator | / | Funktionsaufruf | von links |
. | Zugriffsoperator | / | Strukturzugriff | von links |
-> | Zugriffsoperator | / | Indirektzugriff | von links |
17 | ||||
@ | Zugriffsoperator | unär | Adressoperator | von rechts |
* | Zugriffsoperator | unär | Dereferenzierung | von rechts |
NEW | Datenoperator | unär | Speicher alloziieren | von rechts |
DELETE | Datenoperator | unär | Speicher dealloziieren | von rechts |
16 | ||||
^ | Exponent | binär | Exponent | von links |
15 | ||||
- | Arithmetischer Operator | unär | Negativ | von rechts |
14 | ||||
* | Arithmetischer Operator | binär | Multiplizieren | von links |
/ | Arithmetischer Operator | binär | Dividieren | von links |
13 | ||||
\ | Arithmetischer Operator | binär | Integerdivision | von links |
12 | ||||
MOD | Arithmetischer Operator | binär | Modulo Division | von links |
11 | ||||
SHL | Bitoperator | binär | Bitverschiebung nach links | von links |
SHR | Bitoperator | binär | Bitverschiebung nach rechts | von links |
10 | ||||
+ | Arithmetischer Operator | binär | Addieren | von links |
- | Arithmetischer Operator | binär | Subtrahieren | von links |
9 | ||||
& | Verknüpfungsoperator | binär | Stringverkettung | von links |
8 | ||||
= | Vergleichsoperator | binär | Gleich | von links |
<> | Vergleichsoperator | binär | Ungleich | von links |
< | Vergleichsoperator | binär | Kleiner als | von links |
<= | Vergleichsoperator | binär | Kleiner oder gleich | von links |
>= | Vergleichsoperator | binär | Größer oder gleich | von links |
> | Vergleichsoperator | binär | Größer als | von links |
7 | ||||
NOT | Bitweiser Operator | unär | Verneinung | von rechts |
6 | ||||
AND | Bitweiser Operator | binär | Und | von links |
5 | ||||
OR | Bitweiser Operator | binär | Oder | von links |
4 | ||||
EQV | Bitweiser Operator | binär | Äquivalenz | von links |
IMP | Bitweiser Operator | binär | Implikat | von links |
XOR | Bitweiser Operator | binär | Exklusives Oder | von links |
3 | ||||
ANDALSO | Logischer Operator | binär | Verkürztes und | von links |
ORELSE | Logischer Operator | binär | Verkürztes oder | von links |
2 | ||||
= | Zuweisungsoperator | binär | Zuweisung | N/A |
&= | Zuweisungsoperator | binär | Verkettung + Zuweisung | N/A |
+= | Zuweisungsoperator | binär | Addition + Zuweisung | N/A |
-= | Zuweisungsoperator | binär | Subtraktion + Zuweisung | N/A |
*= | Zuweisungsoperator | binär | Multiplikation + Zuweisung | N/A |
/= | Zuweisungsoperator | binär | Division + Zuweisung | N/A |
\= | Zuweisungsoperator | binär | Integerdivision + Zuweisung | N/A |
^= | Zuweisungsoperator | binär | Exponent + Zuweisung | N/A |
MOD= | Zuweisungsoperator | binär | Modulo + Zuweisung | N/A |
AND= | Zuweisungsoperator | binär | Und + Zuweisung | N/A |
EQV= | Zuweisungsoperator | binär | Äquivalenz + Zuweisung | N/A |
IMP= | Zuweisungsoperator | binär | Implikat + Zuweisung | N/A |
OR= | Zuweisungsoperator | binär | Oder + Zuweisung | N/A |
XOR= | Zuweisungsoperator | binär | Exklusives oder + Zuweisung | N/A |
SHL= | Zuweisungsoperator | binär | Bitverschiebung nach links + Zuweisung | N/A |
SHR= | Zuweisungsoperator | binär | Bitverschiebung nach rechts + Zuweisung | N/A |
LET | Zuweisungsoperator | binär | Zuweisung | N/A |
1 | ||||
LET () | Zuweisungsoperator | binär | Zuweisung | N/A |
Stringoperatoren
Die folgenden Operatoren können bei STRINGs angewandt werden:
- Strings verketten (String1 & String2 oder auch String1 + String2)
- Symbole zu Strings umwandeln und verketten (Symbol1 & Symbol2)
- Prüfen, ob ein String alphabetisch vor einem anderen steht (String1 < String2)
- Prüfen, ob ein String alphabetisch hinter einem anderen steht (String1 > String2)
- Prüfen, ob zwei Strings gleich oder ungleich sind (String1 = String2, String1 <> String2)
Anmerkung: Die Beispiele in den Klammern sind unvollständig; um sie in einem Programm zu benutzen, müssen sie in eine Bedingungsabfrage eingebaut werden wie z. B.
IF String1 > String2 THEN ...
oder als Ausdruck behandelt werden, der einer anderen Variable zugewiesen wird, z. B.
a = (String1 = String2)
Bei Größenvergleichen werden zeichenweise die ASCII-Werte verglichen. Daher ist der String "B" (ASCII-Code 66) kleiner als der String "a" (ASCII-Code 97).
Kurzformen
Bestimmte Ausdrücke müssen relativ häufig eingegeben werden. Die dabei anfallende Tipparbeit ist relativ lästig, außerdem wird vom Compiler längst nicht immer die schnellste Methode gewählt. Um dem entgegenzuwirken, haben die Entwickler von FreeBASIC zwei Techniken eingeführt: zum einen die sogenannten kombinierten Operatoren, zum anderen die Variablen-Initiatoren.
Kombinierte Operatoren
Kombinierte Operatoren sind Kurzformen für Ausdrücke der Form
Variable = Variable Operator Ausdruck
Sie können verkürzt werden auf:
Variable Operator= Ausdruck
Beispiel:
DIM a AS INTEGER
' Beide Zeilen bewirken dasselbe:
a = a + 1
a += 1
Dies funktioniert mit allen Operatoren (+, -, *, /, \, ^, AND, OR, XOR, IMP, EQV, SHL, SHR) bei jedem Datentyp. Auch Arrays und UDTs (User defined Type, siehe TYPE) werden unterstützt (siehe dazu auch OPERATOR).
Beispiel:
TYPE myUDT
Int1 AS INTEGER
Int2 AS INTEGER
END TYPE
DIM AS INTEGER a, b, c(4)
DIM d AS myUDT
a = 5
b = 7
c(0) = 2
c(4) = -5
d.Int2 = 400
a += 5
b -= a * c(4)
c(0) *= a + b
d.Int2 /= c(0)
a OR= d.Int2 + b
Mit STRINGs funktioniert nur die Additions-Kurzform. Diese arbeitet übrigens schneller als die Form
String1 = String1 & String2
da kein temporärer String erstellt werden muss. Der Compiler übersetzt solche Stringverkettungen der Form
String1 = String2 & String3 & String4 & ...
allerdings automatisch in dieses Format:
String1 = String2 : String1 &= String3 : String1 &= String4 : String1 &= ...
Achtung: Wenn Sie Pointer mit der Addition bzw. Subtraktion benutzen, wird der hinzugezählte/abgezogene Wert mit der Länge des Pointer-Datentyps multipliziert, bevor die Berechnung durchgeführt wird. Aus
DIM a AS INTEGER PTR
a += 1
wird also beim Compilieren zu
DIM a AS INTEGER PTR
a += 1 * LEN(INTEGER)
Dies ist in den meisten Fällen von Vorteil, da die Berechnung nicht manuell eingegeben werden muss und dem Programmierer Tipparbeit erspart bleibt. Wenn tatsächlich eine Verschiebung um ein Byte nötig ist, kann dies mit CAST geschehen:
DIM a AS INTEGER PTR
DIM b AS BYTE PTR
a = ALLOCATE(10)
b = CAST(BYTE PTR, a)
b += 1
a = CAST(INTEGER PTR, b)
Variablen-Initiatoren
Variablen-Initiatoren ermöglichen es, einer Variablen bei ihrer Dimensionierung einen Wert zuzuweisen. Dies funktioniert sowohl für einfache Variablen als auch für Arrays. Die Syntax für einfache Variablen ist:
DIM Variable AS Typ = einfacherAusdruck
bzw.
DIM AS Typ Variable1 = Ausdruck [, Variable2 = Ausdruck ...]
Einige kompliziertere Ausdrücke sind bei Variablen-Initiatoren nicht erlaubt. Sollten Sie eine Fehlermeldung erhalten, dann versuchen Sie, die Dimensionierung und die Wertzuweisung in zwei einzelnen Befehlen durchzuführen.
Beispiel:
CONST drei = 3
DIM a AS INTEGER = 5
DIM b AS SINGLE = SIN(drei ^ 0.5) * a
Für Arrays gelten dieselben Regeln, jedoch eine andere Syntax:
DIM Array(Elemente) AS Typ => { Element1, Element2, Element3, ... }
(man beachte, dass {geschweifte} Klammern eingesetzt werden!)
Statt => könnte auch hier = verwendet werden.
Beispiel:
CONST drei = 3
DIM Array(2) AS INTEGER => {1, drei * 7}
Werden - wie hier - weniger Initiatoren als Feldelemente angegeben, befüllt FreeBASIC das Feld von vorne nach hinten (hier also von Index 0 nach Index 1) mit den vorgegebenen Werten, und weist den "überschüssigen" Elementen den Wert 0 zu (bzw. einen Nullstring, falls es sich um ein String-Array handelt). Werden mehr Initiatoren als Elemente angegeben, wird ein Fehler erzeugt und die Compilierung wird abgebrochen.
Bei mehrdimensionalen Arrays müssen innerhalb der Klammern noch einmal geschweifte Klammern gesetzt werden. Dabei zählt die Nummer der Klammer in der Liste wie der Index der ersten Dimension und die Nummer des Eintrags innerhalb der Klammer wie der Index der zweiten Dimension.
Beispiel:
DIM AS INTEGER a(1, 1) => {{1, 2}, {3, 4}}
PRINT a(0, 0) ' 1
PRINT a(0, 1) ' 2
PRINT a(1, 0) ' 3
PRINT a(1, 1) ' 4
SLEEP
Variablen-Initiatoren funktionieren auch mit UDT-Arrays. Siehe dazu die Datei var_initializers.bas im examples-Verzeichnis.
Zusätzliche Informationen und Funktionen | ||||
---|---|---|---|---|
|