Ausdrücke und Operatoren

FreeBASIC-Referenz » BASIC-Grundlagen » 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
Zu den mathematischen Operatoren zählen:

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:

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:

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 unä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:

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.