Ausdrücke (Delphi)

Aus RAD Studio
Wechseln zu: Navigation, Suche

Nach oben zu Grundlegende syntaktische Elemente - Index


In diesem Thema werden die Syntaxregeln für Delphi-Ausdrücke beschrieben.

Folgende Bereiche werden behandelt:

  • Gültige Delphi-Ausdrücke
  • Operatoren
  • Funktionsaufrufe
  • Mengenkonstruktoren
  • Indizes
  • Typumwandlungen

Ausdrücke

Ein Ausdruck ist eine Konstruktion, die einen Wert zurückliefert. Die folgende Tabelle enthält Beispiele für Delphi-Ausdrücke:

X

Variable

@X

Adresse der Variable X

15

Integer-Konstante

InterestRate

Variable

Calc(X, Y)

Funktionsaufruf

X * Y

Produkt von X und Y

Z / (1 - Z)

Quotient von Z und (1 - Z)

X = 1.5

Boolescher Ausdruck

C in Range1

Boolescher Ausdruck

not Done

Negation eines Booleschen Ausdrucks

['a', 'b', 'c']

Menge

Char(48)

Wert einer Typumwandlung


Die einfachsten Ausdrücke sind Variablen und Konstanten (siehe Überblick über Datentypen (Delphi)). Komplexere Ausdrücke werden mithilfe von Operatoren, Funktionsaufrufen, Mengenkonstruktoren, Indizes und Typumwandlungen aus einfachen Ausdrücken gebildet.

Operatoren

Operatoren verhalten sich wie vordefinierte Funktionen, die Bestandteil der Sprache Delphi sind. So setzt sich beispielsweise der Ausdruck (X + Y) aus den Variablen X und Y (den so genannten Operanden) und dem Operator + zusammen. Wenn X und Y den Typ Integer oder Real haben, liefert der Ausdruck (X + Y) die Summe der beiden Werte. Operatoren sind @, not, ^, *, /, div, mod, and, shl, shr, as, +, -, or, xor, =, >, <, <>, <=, >=, in und is.

Die Operatoren @, not und ^ sind unäre Operatoren und haben nur einen Operanden. Alle anderen Operatoren sind binär und haben zwei Operanden. Eine Ausnahme bilden die Operatoren + und -, die entweder unär oder binär sein können. Ein unärer Operator steht immer vor seinem Operanden (z.B. -B). Eine Ausnahme von dieser Regel bildet der Operator ^, der auf seinen Operanden folgt (z.B. P^). Binäre Operatoren stehen immer zwischen ihren Operanden (z.B. A = 7).

Das Verhalten einiger Operatoren hängt von dem Datentyp ab, der an sie übergeben wird. Beispielsweise führt der Operator not eine bitweise Negation eines Integer-Operanden und eine logische Negation eines Booleschen Operanden aus. Solche Operatoren sind deshalb auch mehreren Kategorien zugeordnet.

Mit Ausnahme von ^, is und in können alle Operatoren Operanden vom Typ Variant akzeptieren. Weitere Informationen finden Sie unter Variante Typen.

Die Erläuterungen in den folgenden Abschnitten gehen davon aus, dass Sie mit den Datentypen von Delphi vertraut sind. Weitere Informationen finden Sie unter Überblick über Datentypen (Delphi).

Informationen zur Rangfolge der Operatoren in komplexen Ausdrücken finden Sie unter "Rangfolge von Operatoren" weiter unten.

Arithmetische Operatoren

Zu den arithmetischen Operatoren für Real- oder Integer-Operanden gehören die Operatoren +, -, *, /, div und mod.

Binäre arithmetische Operatoren:

Operator Operation Operandtyp Ergebnistyp Beispiel

+

Addition

Integer, Real

Integer, Real

X + Y

-

Subtraktion

Integer, Real

Integer, Real

Ergebnis -1

*

Multiplikation

Integer, Real

Integer, Real

P * InterestRate

/

Gleitkommadivision

Integer, Real

Real

X / 2

div

Ganzzahlige Division

Integer

Integer

Total div UnitSize

mod

Rest

Integer

Integer

Y mod 6


Unäre arithmetische Operatoren:

Operator Operation Operandtyp Ergebnistyp Beispiel

+

Positives Vorzeichen

Integer, Real

Integer, Real

+7

-

Negatives Vorzeichen

Integer, Real

Integer, Real

-X


Für arithmetische Operatoren gelten die folgenden Regeln:

  • Der Wert von x / y ist vom Typ Extended, unabhängig vom Typ von x und y. Bei allen anderen Operatoren ist das Ergebnis vom Typ Extended, wenn mindestens ein Operand den Typ Real hat. Ist das nicht der Fall, ist das Ergebnis vom Typ Int64, wenn mindestens ein Operand den Typ Int64 hat, ansonsten ist das Ergebnis vom Typ Integer. Wenn der Typ eines Operanden ein Unterbereich eines Integer-Typs ist, wird er wie ein Operand vom Typ Integer behandelt.
  • Der Wert von x div y entspricht dem Wert von x / y, abgerundet in Richtung Null bis zum nächsten Integer-Wert.
  • Der Operator mod liefert den Rest, der sich bei der Division seiner Operanden ergibt. Das bedeutet:
    x mod y = x - (x div y) * y.
  • Wenn y in einem Ausdruck der Form x / y, x div y oder x mod y den Wert Null hat, tritt ein Laufzeitfehler auf.

Boolesche Operatoren

Die Operanden der Booleschen Operatoren not, and, or und xor können einen beliebigen Booleschen Typ haben. Die Operatoren liefern einen Wert vom Typ Boolean zurück.

Boolesche Operatoren:

Operator Operation Operandtyp Ergebnistyp Beispiel

not

Negation

Boolean

Boolean

not (C in MySet)

and

Konjunktion

Boolean

Boolean

Done and (Total >0)

or

Disjunktion

Boolean

Boolean

A or B

xor

Exklusive Disjunktion

Boolean

Boolean

A xor B

Diese Operatoren folgen den Standardregeln der Booleschen Logik. Beispielsweise liefert ein Ausdruck der Form x and y nur dann den Wert True, wenn x und y den Wert True haben.

Vollständige Auswertung und Kurzschlussverfahren im Vergleich

Der Compiler unterstützt zwei Auswertungsmodi für die Operatoren and und or: die vollständige Auswertung und das Kurzschlussverfahren. Bei der vollständigen Auswertung werden alle Operanden eines and- oder or-Ausdrucks auch dann ausgewertet, wenn das Resultat des gesamten Ausdrucks bereits feststeht. Das Kurzschlussverfahren geht streng von links nach rechts vor und wird beendet, sobald das Ergebnis des gesamten Ausdrucks feststeht. Wenn beispielsweise der Ausdruck A and B im Kurzschlussverfahren ausgewertet wird und A den Wert False hat, wertet der Compiler B nicht mehr aus, da bereits feststeht, dass nach der Auswertung von A auch der gesamte Ausdruck den Wert False haben wird.

Das Kurzschlussverfahren ist normalerweise vorzuziehen, da es schneller ausgeführt wird und (in den meisten Fällen) einen geringeren Quelltextumfang erfordert. Die vollständige Auswertung ist von Nutzen, wenn ein Operand eine Funktion mit Nebeneffekten ist, die Änderungen in der Ausführung des Programms bewirken.

Das Kurzschlussverfahren ermöglicht auch Konstruktionen, die sonst zu unzulässigen Laufzeitoperationen führen würden. Die folgende Anweisung iteriert bis zum ersten Komma durch den String S:

while (I <= Length(S)) and (S[I] <> ',') do 
begin,
 ... 
 Inc(I); 
end;

Wenn S keine Kommas enthält, wird I bei der letzten Iteration auf einen Wert erhöht, der größer ist als S. Beim nachfolgenden Test der while-Bedingung wird bei einer vollständigen Auswertung versucht, S[I] zu lesen, was zu einem Laufzeitfehler führen kann. Beim Kurzschlussverfahren wird dagegen der zweite Teil der while-Bedingung (S[I] <> ',') nicht mehr ausgewertet, nachdem der erste Teil False ergibt.

Zur Steuerung des Auswertungsmodus dient die Compiler-Direktive $B. Voreingestellt ist der Status {$B} für das Kurzschlussverfahren. Um die vollständige Auswertung lokal zu aktivieren, fügen Sie die Direktive {$B+} in den Quelltext ein. Sie können auch auf Projektebene in diesen Status wechseln, indem Sie im Dialogfeld Projektoptionen die Option Boolesche Ausdrücke vollständig aktivieren (alle Quell-Units müssen erneut compiliert werden).

Hinweis: Wenn einer der Operanden vom Typ Variant ist, führt der Compiler immer eine vollständige Auswertung durch (auch im Status {$B}).

Logische (bitweise) Operatoren

Die folgenden logischen Operatoren bearbeiten Integer-Operanden bitweise. Wenn z. B. der in X (binär) gespeicherte Wert 001101 und der in Y gespeicherte Wert 100001 lautet, weist die Operation

Z := X or Y;

den Wert 101101 an Z zu.

Logische (bitweise) Operatoren:

Operator Operation Operandtyp Ergebnistyp Beispiel

not

Bitweise Negation

Integer

Integer

not X

and

Bitweises and

Integer

Integer

X and Y

or

Bitweises or

Integer

Integer

X or Y

xor

Bitweises xor

Integer

Integer

X xor Y

shl

Bitverschiebung nach links

Integer

Integer

X shl 2

shr

Bitverschiebung nach rechts

Integer

Integer

Y shr I

Für bitweise Operatoren gelten die folgenden Regeln:

  • Das Ergebnis einer not-Operation hat denselben Typ wie der Operand.
  • Wenn beide Operanden einer and-, or- oder xor-Operation Integer sind, hat das Ergebnis den vordefinierten Integer-Typ mit dem kleinsten Bereich, im dem alle für beide Typen möglichen Werte enthalten sind.
  • Die Operationen x shl y und x shr y verschieben den Wert von x um y Bits nach links oder rechts (falls es sich bei x um einen vorzeichenlosen Integer handelt). Dies entspricht der Multiplikation oder Division von x durch 2^y. Das Ergebnis hat denselben Typ wie x. Wenn beispielsweise in N der Wert 01101 (dezimal 13) gespeichert ist, gibt N shl 1 den Wert 11010 (dezimal 26) zurück. Beachten Sie, dass der Wert von y als Restwert der Größe von Typ x interpretiert wird. Wenn z.B. x ein Integer ist, wird x shl 40 als x shl 8 interpretiert, da ein Integer 32 Bit hat, und 40 minus 32 den Wert 8 ergibt.

Beispiel

Wenn x ein negativer Integer-Wert ist, werden die Operationen shl und shr folgendermaßen ausgedrückt:

var
  x: integer;
  y: string;

...
begin
  x := -20;
  x := x shr 1;
  //As the number is shifted to the right by 1 bit, the sign bit's value replaced is with 0 (all negative numbers have the sign bit set to 1). 
  y := IntToHex(x, 8);
  writeln(y);
  //Therefore, x is positive.
  //Decimal value: 2147483638
  //Hexadecimal value: 7FFFFFF6
  //Bunary value: 0111 1111 1111 1111 1111 1111 1111 0110
end.

String-Operatoren

Die relationalen Operatoren =, <>, <, >, <= und >= funktionieren auch mit String-Operanden (siehe "Relationale Operatoren" weiter unten in diesem Abschnitt). Der Operator + verkettet zwei Strings.

String-Operatoren:

Operator Operation Operandtyp Ergebnistyp Beispiel

+

Verkettung

String, gepackter String, Char

String

S + '.'


Für die Verkettung von Strings gelten folgende Regeln:

  • Die Operanden für + können Strings, gepackte Strings (gepackte Arrays vom Typ Char) oder Zeichen sein. Wenn jedoch ein Operand vom Typ WideChar ist, muss der andere Operand ein langer String (UnicodeString, AnsiString oder WideString) sein.
  • Das Ergebnis einer +-Operation ist mit allen String-Typen kompatibel. Wenn aber beide Operanden kurze Strings oder Zeichen sind und ihre gemeinsame Länge größer als 255 ist, wird das Ergebnis nach dem 255. Zeichen abgeschnitten.

Zeiger-Operatoren

Die relationalen Operatoren <, >, <= und >= können Operanden vom Typ PAnsiChar und PWideChar haben (siehe "Relationale Operatoren"). Bei den folgenden Operatoren können die Operanden auch Zeiger sein. Weitere Informationen über Zeiger finden Sie im Abschnitt Zeiger und Zeigertypen (Delphi) unter Überblick über Datentypen (Delphi).

Zeichenzeiger-Operatoren:

Operator Operation Operandtyp Ergebnistyp Beispiel

+

Zeigeraddition

Zeichenzeiger, Integer

Zeichenzeiger

P + I

-

Zeigersubtraktion

Zeichenzeiger, Integer

Zeichenzeiger, Integer

P - Q

^

Zeiger-Dereferenzierung

Zeiger

Basistyp von Zeiger

P^

=

Gleich

Zeiger

Boolescher Ausdruck

P = Q

<>

Ungleich

Zeiger

Boolescher Ausdruck

P <>Q


Der Operator ^ dereferenziert einen Zeiger. Sein Operand kann ein Zeiger auf einen beliebigen Typ mit Ausnahme des generischen Typs Pointer sein, der vor der Dereferenzierung umgewandelt werden muss.

P = Q ist nur dann True, wenn P und Q auf dieselbe Adresse zeigen. Andernfalls ergibt P <> Q True.

Mit den Operatoren + und - kann der Offset eines Zeichenzeigers erhöht oder erniedrigt werden. Mit dem Operator - können Sie außerdem den Unterschied zwischen den Offsets zweier Zeichenzeiger berechnen. Es gelten die folgenden Regeln:


  • Wenn I ein Integer und P ein Zeichenzeiger ist, addiert P + I den Wert I zu der von P angegebenen Adresse. Es wird also ein Zeiger auf die Adresse zurückgegeben, die I Zeichen hinter P liegt. (Der Ausdruck I + P entspricht P + I.) P - I subtrahiert I von der Adresse, die von P angegeben wird. Das Ergebnis ist ein Zeiger auf die Adresse, die I Zeichen vor P liegt. Dies gilt für PAnsiChar-Zeiger. Für PWideChar-Zeiger fügt P + I I * SizeOf(WideChar) zu P hinzu.
  • Wenn P und Q Zeichenzeiger sind, berechnet P - Q die Differenz zwischen der von P angegebenen (höheren) und der von Q angegebenen (niedrigeren) Adresse. Es wird also ein Integer-Wert für die Anzahl der Zeichen zwischen P und Q zurückgegeben.
Das Ergebnis von P + Q ist nicht definiert.

Mengenoperatoren

Die folgenden Operatoren haben eine Menge als Operanden.

Mengenoperatoren:

Operator Operation Operandtyp Ergebnistyp Beispiel

+

Union

Menge

Menge

Set1 + Set2

-

Differenz

Menge

Menge

S - T

*

Schnittmenge

Menge

Menge

S * T

<=

Untermenge

Menge

Boolescher Ausdruck

Q <= MySet

>=

Obermenge

Menge

Boolescher Ausdruck

S1 >= S2

=

Gleich

Menge

Boolescher Ausdruck

S2 = MySet

<>

Ungleich

Menge

Boolescher Ausdruck

MySet <> S1

in

Element einer Menge

Ordinalwert, Menge

Boolescher Ausdruck

A in Set1


Für +, - und * gelten die folgenden Regeln:

  • Der Ordinalwert O ist nur in X + Y enthalten, wenn O in X oder Y (oder beiden) enthalten ist. O ist nur in X - Y enthalten, wenn O in X, aber nicht in Y enthalten ist. O ist nur in X * Y enthalten, wenn O sowohl in X als auch in Y enthalten ist.

Für <=, >=, =, <> und in gelten folgende Regeln:

  • X <= Y ist True, wenn jedes Element von X ein Element von Y ist. Z >= W ist gleichbedeutend mit W <= Z. U = V ist nur dann True, wenn U und V genau dieselben Elemente enthalten. Andernfalls gilt U <> V ist True.
  • Für einen Ordinalwert O und eine Menge S ist O in S nur dann True, wenn O ein Element von S ist.

Relationale Operatoren

Relationale Operatoren dienen dem Vergleich zweier Operanden. Die Operatoren =, <>, <= und >= lassen sich auch auf Mengen anwenden.

Relationale Operatoren:

Operator Operation Operandtyp Ergebnistyp Beispiel

=

Gleich

Einfacher Typ, Klassen-, Klassenreferenz-, Interface-, String- und gepackter String-Typ

Boolescher Ausdruck

I = Max

<>

Ungleich

Einfacher Typ, Klassen-, Klassenreferenz-, Interface-, String- und gepackter String-Typ

Boolescher Ausdruck

X <> Y

<

Kleiner als

Einfacher Typ, String-, gepackter String und PChar-Typ

Boolescher Ausdruck

X < Y

>

Größer als

Einfacher Typ, String-, gepackter String und PChar-Typ

Boolescher Ausdruck

Len > 0

<=

Kleiner oder gleich

Einfacher Typ, String-, gepackter String und PChar-Typ

Boolescher Ausdruck

Cnt <= I

>=

Größer oder gleich

Einfacher Typ, String-, gepackter String und PChar-Typ

Boolescher Ausdruck

I >= 1


Bei den meisten einfachen Typen ist der Vergleich unkompliziert. I = J ist beispielsweise nur dann True, wenn I und J denselben Wert haben. Andernfalls ist I <> J True. Für relationale Operatoren gelten die folgenden Regeln:

  • Operanden müssen kompatible Typen haben, mit folgender Ausnahme: Reelle und Integer-Typen können miteinander verglichen werden.
  • Strings werden gemäß den ordinalen Werten verglichen, die die Zeichen ausmachen, aus denen wiederum der String besteht. Zeichen-Typen werden als Strings der Länge 1 behandelt.
  • Zwei gepackte Strings müssen beim Vergleich dieselbe Anzahl von Komponenten aufweisen. Wird ein gepackter String mit n Komponenten mit einem String verglichen, wird der gepackte String als String der Länge n behandelt.
  • Die Operatoren <, >, <= und >= werden nur dann für den Vergleich von PAnsiChar-Operanden (sowie PWideChar-Operanden) verwendet, wenn die beiden Zeiger auf Elemente in demselben Zeichen-Array zeigen.
  • Die Operatoren = und <> können Operanden von Klassen- und Klassenreferenztypen haben. Mit Operanden eines Klassentyps werden = und <> entsprechend den Regeln für Zeiger ausgewertet: C = D ist nur dann True, wenn C und D auf dasselbe Instanzobjekt zeigen. Ansonsten ist C <> D True. Mit Operanden eines Klassenreferenztyps ist C = D nur dann True, wenn C und D dieselbe Klasse bezeichnen. Andernfalls ist C <> D True. Dies ist nicht mit Daten zu vergleichen, die in Klassen gespeichert sind. Weitere Informationen zu Klassen finden Sie unter Klassen und Objekte.

Klassen- und Interface-Operatoren

Die Operatoren as und is übernehmen Klassen und Instanzobjekte als Operanden; as kann auch auf Interfaces angewendet werden. Weitere Informationen finden Sie unter Klassen und Objekte, Objekt-Interfaces und Interface-Referenzen.


Die relationalen Operatoren = und <> können auch auf Klassen angewendet werden.

Der Operator @

Der Operator @ liefert die Adresse einer Variablen, Funktion, Prozedur oder Methode, erzeugt also einen Zeiger auf seinen Operanden. Weitere Informationen über Zeiger finden Sie im Abschnitt "Zeiger und Zeigertypen" unter Überblick über Datentypen (Delphi). Für den Operator @ gelten folgende Regeln:

  • Ist X eine Variable, gibt @X die Adresse von X zurück. (Wenn X eine prozedurale Variable ist, gelten besondere Regeln; siehe "Prozedurale Typen in Anweisungen und Ausdrücken" unter Überblick über Datentypen (Delphi).) @X ist vom Typ Pointer, wenn die Standard-Compiler-Direktive {$T} aktiviert ist. Im Status {$T+} ist @X vom Typ ^T, wobei T denselben Typ wie X hat (dieser Unterschied ist für die Zuweisungskompatibilität wichtig; siehe "Zuweisungskompatibilität").
  • Wenn F eine Routine (eine Funktion oder Prozedur) ist, liefert @F den Eintrittspunkt von F. @F ist immer vom Typ Pointer.
  • Wenn @ auf eine in einer Klasse definierte Methode angewendet wird, muss der Methodenbezeichner mit dem Klassennamen qualifiziert werden. Ein Beispiel:
@TMyClass.DoSomething
Diese Anweisung zeigt auf die Methode DoSomething von TMyClass. Weitere Informationen zu Klassen und Methoden finden Sie unter Klassen und Objekte.
Hinweis: Bei Verwendung des Operators @ ist es nicht möglich, die Adresse einer Interface-Methode anzugeben, da die Adresse zur Compilierzeit nicht bekannt ist und zur Laufzeit nicht extrahiert werden kann.

Rangfolge von Operatoren

In komplexen Ausdrücken wird die Reihenfolge, in der Operationen ausgeführt werden, durch die Rangfolge der Operatoren festgelegt.

Rangfolge von Operatoren 
Operatoren Rangfolge

@
not

Erste (höchste)

*
/
div
mod
and
shl
shr
as

Zweite

+
-
or
xor

Dritte

=
<>
<
>
<=
>=
in
is

Vierte (niedrigste)


Ein Operator mit einer höheren Wertigkeit wird vor einem Operator mit einer niedrigeren Wertigkeit ausgewertet. Gleichrangige Operatoren werden von links nach rechts ausgewertet. Aus diesem Grund multipliziert der Ausdruck


X + Y * Z

zunächst Y mit Z und addiert dann X zum Ergebnis der Multiplikation. Die Operation * (Multiplikation) wird zuerst ausgeführt, weil dieser Operator höherwertig ist als der Operator +. Dagegen wird beim Ausdruck


X - Y + Z

zuerst Y von X subtrahiert und anschließend Z zum Ergebnis addiert. Die Operatoren - und + weisen dieselbe Wertigkeit auf. Aus diesem Grund wird die Operation auf der linken Seite zuerst ausgeführt.

Mithilfe von runden Klammern lassen sich die Rangfolgeregeln außer Kraft setzen. Ein Ausdruck in runden Klammern wird immer zuerst ausgewertet und danach wie ein einzelner Operand behandelt. Beispiel:

(X + Y) * Z

Dieser Ausdruck multipliziert Z mit der Summe von X und Y.

Manchmal sind Klammern in Situationen erforderlich, die dies auf den ersten Blick nicht vermuten lassen. Betrachten Sie den folgenden Ausdruck:

X = Y or X = Z

Die beabsichtigte Interpretation lautet offensichtlich:

(X = Y) or (X = Z)

Wenn keine Klammern gesetzt werden, hält sich der Compiler an die Regeln für die Rangfolge der Operatoren und interpretiert den Ausdruck folgendermaßen:

(X = (Y or X)) = Z

Wenn Z nicht vom Typ Boolean ist, führt dies zu einem Compilierungsfehler.

Runde Klammern erleichtern zwar häufig das Schreiben und Lesen des Quelltextes, sind aber streng genommen überflüssig. Das erste der obigen Beispiele könnte auch folgendermaßen formuliert werden:

X + (Y * Z)

Hier sind die Klammern (für den Compiler) unnötig, erleichtern aber dem Programmierer und dem Leser die Interpretation, weil die Rangfolge der Operatoren nicht berücksichtigt werden muss.

Funktionsaufrufe

Funktionsaufrufe sind Ausdrücke, da sie einen Wert zurückliefern. Wenn Sie beispielsweise eine Funktion mit dem Namen Calc definiert haben, die zwei Integer-Argumente übernimmt und einen Integer-Wert zurückgibt, stellt der Funktionsaufruf Calc(24,47) einen Integer-Ausdruck dar. Sind I und J Integer-Variablen, ist I + Calc(J,8) ebenfalls ein Integer-Ausdruck. Hier einige Beispiele für Funktionsaufrufe:

Sum(A, 63)
Maximum(147, J)
Sin(X + Y)
Eof(F)
Volume(Radius, Height)
GetValue
TSomeObject.SomeMethod(I,J);

Weitere Informationen zu Funktionen finden Sie unter Prozeduren und Funktionen.

Mengenkonstruktoren

Ein Mengenkonstruktor bezeichnet einen Wert eines Mengentyps. Beispiel:

[5, 6, 7, 8]

Dieser Mengenkonstruktor bezeichnet eine Menge mit den Ziffern 5, 6, 7 und 8. Dieselbe Menge könnte auch mit dem Mengenkonstruktor

[ 5..8 ]

bezeichnet werden.

Die Syntax für einen Mengenkonstruktor lautet:

[ Element1, ..., Elementn ]

Hierbei kann Element ein Ausdruck sein, der einen Ordinalwert des Basistyps der Menge bezeichnet, oder ein Paar solcher Ausdrücke, die durch zwei Punkte (..) miteinander verbunden sind. Hat Element die Form x..y, bezeichnet es alle Ordinalwerte von x bis einschließlich y. Ist x jedoch größer als y, repräsentiert x..y keine Elemente, und [x..y] steht für eine leere Menge. Der Mengenkonstruktor [ ] bezeichnet die leere Menge, während [x] eine Menge repräsentiert, deren einziges Element der Wert x ist.


Hier einige Beispiele für Mengenkonstruktoren:


[red, green, MyColor]
[1, 5, 10..K mod 12, 23]
['A'..'Z', 'a'..'z', Chr(Digit + 48)]

Weitere Informationen zu Mengen finden Sie im Abschnitt Strukturierte Typen unter Überblick über Datentypen (Delphi).


Indizes

Strings, Arrays, Array-Eigenschaften und Zeiger auf Strings oder Arrays können indiziert werden. Beispielsweise liefert der Ausdruck Dateiname[3] für die String-Variable Dateiname den dritten Buchstaben in dem durch Dateiname bezeichneten String. Dagegen gibt Dateiname[I + 1] das Zeichen zurück, das unmittelbar auf das mit I indizierte Zeichen folgt. Weitere Informationen zu Strings finden Sie unter Datentypen, Variablen und Konstanten. Informationen zu Arrays und Array-Eigenschaften finden Sie im Abschnitt Array-Typen unter Datentypen, Variablen und Konstanten und im Abschnitt "Array-Eigenschaften" unter Eigenschaften.

Typumwandlungen

In bestimmten Situationen ist es erforderlich, den Typ eines Ausdrucks zu ändern. Durch eine Typumwandlung kann einem Ausdruck vorübergehend ein anderer Typ zugeordnet werden. Beispielsweise konvertiert die Anweisung Integer('A') den Buchstaben A in einen Integer.

Die Syntax für eine Typumwandlung lautet:

Typbezeichner(Ausdruck)

Handelt es sich bei dem Ausdruck um eine Variable, spricht man von einer Variablenumwandlung, andernfalls von einer Wertumwandlung. Obwohl die Syntax einer Wertumwandlung mit derjenigen einer Variablenumwandlung identisch ist, gelten für die beiden Umwandlungsarten unterschiedliche Regeln.

Wertumwandlungen

Bei einer Wertumwandlung müssen sowohl der Typbezeichner als auch der umzuwandelnde Ausdruck entweder ein ordinaler Typ oder ein Zeigertyp sein. Hier einige Beispiele für Wertumwandlungen:


Integer('A')
Char(48)
Boolean(0)
Color(2)
Longint(@Buffer)

Der resultierende Wert ergibt sich aus der Umwandlung des Ausdrucks in Klammern. Dabei wird der ursprüngliche Wert möglicherweise abgeschnitten oder erweitert, wenn die Größe des neuen Typs sich vom Typ des Ausdrucks unterscheidet. Das Vorzeichen des Ausdrucks bleibt aber in jedem Fall erhalten.


Die Anweisung

I := Integer('A');

weist der Variablen I den Wert von Integer('A') zu (also 65).

Auf eine Wertumwandlung dürfen keine Qualifizierer folgen. Außerdem sind Wertumwandlungen nur auf der rechten Seite einer Zuweisung erlaubt.

Variablenumwandlungen

Variablen können in jeden beliebigen Typ umgewandelt werden. Dabei muss allerdings die Größe gleich bleiben, und Integer-Typen dürfen nicht mit Real-Typen vermischt werden (verwenden Sie zur Umwandlung numerischer Typen Standardfunktionen wie Int und Trunc). Hier einige Beispiele für Variablenumwandlungen:

Char(I)
Boolean(Count)
TSomeDefinedType(MyVariable)

Variablenumwandlungen sind auf beiden Seiten einer Zuweisung erlaubt. Dazu ein Beispiel:

var MyChar: char;
  ...
  Shortint(MyChar) := 122;

Bei dieser Umwandlung wird MyChar das Zeichen z (ASCII 122) zugewiesen.

Variablen können in prozedurale Typen umgewandelt werden. Ausgehend von den Deklarationen

type Func = function(X: Integer): Integer;
var
  F: Func;
  P: Pointer;
  N: Integer;

sind z.B. folgende Zuweisungen möglich:

F := Func(P);     { Prozeduralen Wert in P an F zuweisen } 
Func(P) := F;     { Prozeduralen Wert in F an P zuweisen } 
@F := P;          { Zeigerwert in P an F zuweisen } 
P := @F;          { Zeigerwert in F an P zuweisen } 
N := F(N);        { Funktion über F aufrufen } 
N := Func(P)(N);  { Funktion über P aufrufen }

Wie das folgende Beispiel zeigt, dürfen auf Variablenumwandlungen auch Qualifizierer folgen:

type
  TByteRec = record
     Lo, Hi: Byte;
  end;
  TWordRec = record
     Low, High: Word;
  end;
  PByte = ^Byte;   

var
  B: Byte;
  W: Word;
  L: Longint;
  P: Pointer;

begin
  W := $1234;
  B := TByteRec(W).Lo;
  TByteRec(W).Hi := 0;
  L := $1234567;
  W := TWordRec(L).Low;
  B := TByteRec(TWordRec(L).Low).Hi;
  B := PByte(L)^;
end;

In diesem Beispiel wird mit TByteRec auf das niedrigst- und höchstwertige Byte eines Word zugegriffen. Über TWordRec erfolgt ein Zugriff auf das niedrigst- und höchstwertige Word eines Longint. Zu diesem Zweck könnten auch die vordefinierten Funktionen Lo und Hi verwendet werden. Die Variablenumwandlung bietet aber den Vorteil, dass sie auf der linken Seite einer Zuweisung stehen kann.

Weitere Informationen über die Typumwandlung von Zeigern finden Sie unter Zeiger und Zeigertypen (Delphi). Ausführliche Informationen zur Umwandlung von Klassen- und Interface-Typen finden Sie im Abschnitt "Der Operator as" unter Klassenreferenzen und Interface-Referenzen.

Siehe auch