Einfache Typen (Object Pascal)

Aus Appmethod Topics
Wechseln zu: Navigation, Suche

Nach oben zu Datentypen, Variablen und Konstanten - Index



Einfache Typen, zu denen die ordinalen und reellen Typen gehören, definieren eine Menge von Werten mit eindeutiger Reihenfolge.

Ordinale Typen

Zu den ordinalen Typen gehören Integer-, Zeichen-, boolesche, Aufzählungs- und Teilbereichstypen. Ein ordinaler Typ definiert eine Menge von Werten mit eindeutiger Reihenfolge, in der jeder Wert mit Ausnahme des ersten einen eindeutigen Vorgänger und mit Ausnahme des letzten einen eindeutigen Nachfolger hat. Die Reihenfolge der Werte wird durch deren Ordinalposition festgelegt. In den meisten Fällen hat ein Wert mit der Ordinalposition n einen Vorgänger mit der Ordinalposition n-1 und einen Nachfolger mit der Ordinalposition n+1.

Bei Integertypen ist die Ordinalposition mit dem Wert selbst identisch. Teilbereichstypen übernehmen die Ordinalposition von ihrem Basistyp. Bei allen anderen ordinalen Typen hat der erste Wert standardmäßig die Ordinalposition 0, der nächste die Ordinalposition 1 usw. In der Deklaration eines Aufzählungstyps kann diese Vorgabe überschrieben werden.

Einige vordefinierte Funktionen operieren mit ordinalen Werten und Typbezeichnern. Die wichtigsten dieser Funktionen sind in der folgenden Tabelle zusammengefasst.

Funktion Parameter Rückgabewert Bemerkungen

Ord

Ordinaler Ausdruck

Ordinalposition des Ausdruckswertes

Akzeptiert keine Int64-Argumente.

Pred

Ordinaler Ausdruck

Vorgänger des Ausdruckswertes

Succ

Ordinaler Ausdruck

Nachfolger des Ausdruckswertes

High

Ordinaler Typbezeichner oder Variable mit ordinalem Typ

Höchster Wert des Typs

Arbeitet auch mit kurzen String-Typen und Arrays.

Low

Ordinaler Typbezeichner oder Variable mit ordinalem Typ

Niedrigster Wert des Typs

Arbeitet auch mit kurzen String-Typen und Arrays.


Beispielsweise gibt High(Byte) den Wert 255 zurück, weil 255 der höchste Wert des Typs Byte ist. Succ(2) gibt 3 zurück, weil 3 der Nachfolger von 2 ist.

Die Standardprozeduren Inc und Dec erhöhen bzw. verringern den Wert einer ordinalen Variable. Beispielsweise ist Inc(I) identisch mit I := Succ(I) oder mit I := I + 1, wenn I eine Integer-Variable ist.

Integertypen

Ein Integertyp repräsentiert eine Untermenge der integralen Zahlen.

Integertypen können plattformabhängig und plattformunabhängig sein.

Plattformabhängige Integertypen

Die plattformabhängigen Integertypen werden konvertiert, damit sie zu der Bitgröße der aktuellen Compiler-Plattform passen. Plattformabhängige Integertypen sind NativeInt, NativeUInt, LongInt und LongWord. Verwenden Sie nach Möglichkeit diese Typen, da sie zu der besten Leistung für die zugrunde liegende CPU und das Betriebssystem führen. Die folgende Tabelle enthält die Bereiche und Speicherformate für den Object Pascal-Compiler.

Plattformabhängige Integertypen

Typ Bereich Format Alias

NativeInt

-2147483648..2147483647
-2^63..2^63-1

32 Bit auf 32-Bit-Plattformen mit Vorzeichen oder
64 Bit auf 64-Bit-Plattformen mit Vorzeichen

Integer
Int64

NativeUInt

0..4294967295
0..2^64-1

32 Bit auf 32-Bit-Plattformen ohne Vorzeichen oder
64 Bit auf 64-Bit-Plattformen ohne Vorzeichen

Cardinal
UInt64

LongInt

-2147483648..2147483647
-263..263-1

32-Bit-Plattformen und 64-Bit-Windows-Plattformen
64-Bit-iOS-Plattformen

Integer
Int64

LongWord

0..4294967295
0..264-1

32-Bit-Plattformen und 64-Bit-Windows-Plattformen
64-Bit-iOS-Plattformen

Cardinal
UInt64

Hinweis:

Zu 32-Bit-Plattformen zählen 32-Bit-Windows, OSX32, 32-Bit-iOS und Android.

Plattformunabhängige Integertypen

Plattformunabhängige Integertypen haben auf jeder verwendeten Plattform immer dieselbe Größe. Zu den plattformunabhängigen Integertypen gehören ShortInt, SmallInt, LongInt, Integer, Int64, Byte, Word, LongWord, Cardinal und UInt64.

Plattformunabhängige Integertypen

Typ Bereich Format Alias

ShortInt

-128..127

8 Bit mit Vorzeichen

Int8

SmallInt

-32768..32767

16 Bit mit Vorzeichen

Int16

FixedInt

-2147483648..2147483647

32 Bit mit Vorzeichen

Int32

Integer

-2147483648..2147483647

32 Bit mit Vorzeichen

Int32

Int64

-2^63..2^63-1

64 Bit mit Vorzeichen

Byte

0..255

8 Bit ohne Vorzeichen

UInt8

Word

0..65535

16 Bit ohne Vorzeichen

UInt16

FixedUInt

0..4294967295

32 Bit ohne Vorzeichen

UInt32

Cardinal

0..4294967295

32 Bit ohne Vorzeichen

UInt32

UInt64

0..2^64-1

64 Bit ohne Vorzeichen


Generell gilt, dass arithmetische Operationen mit Integer-Werten einen Wert mit dem Typ Integer zurückliefern, der in der aktuellen Implementierung mit dem 32-Bit-LongInt identisch ist. Operationen liefern nur dann einen Wert vom Typ Int64, wenn sie für einen oder mehrere Int64-Operanden ausgeführt werden. Deshalb ergibt der folgende Quelltext kein korrektes Resultat:

var
I: Integer;
J: Int64;
... 
I := High(Integer);
J := I + 1;

Um hier einen Rückgabewert vom Typ Int64 zu erhalten, muss für I eine Typumwandlung in Int64 ausgeführt werden:

...
J := Int64(I) + 1;

Weitere Informationen hierzu finden Sie unter Arithmetische Operatoren.

Hinweis: Einige Standardroutinen mit Integer-Argumenten verkürzen Int64-Werte auf 32 Bit. Die Routinen High, Low, Succ, Pred, Inc, Dec, IntToStr und IntToHex unterstützen Int64-Argumente jedoch vollständig. Auch die Funktionen Round, Trunc, StrToInt64 und StrToInt64Def geben Int64-Werte zurück. Einige wenige Routinen können keine Int64-Werte verarbeiten.

Wenn Sie den letzten Wert eines Integertyps erhöhen oder den ersten verringern, erhalten Sie als Ergebnis den niedrigsten bzw. den höchsten Wert des Bereichs. Der Typ ShortInt umfasst beispielsweise den Bereich -128..127. Deshalb hat nach Ausführung des Codes:

var
I: Shortint;
...
I := High(Shortint);
I := I + 1;

die Variable I den Wert -128. Wenn die Bereichsprüfung des Compilers aktiviert ist, führt dieser Code allerdings zu einem Laufzeitfehler.

Zeichentypen

Die Zeichentypen sind Char, AnsiChar, WideChar, UCS2Char und UCS4Char:

  • Char entspricht in der aktuellen Implementierung WideChar, da der Standard-String-Typ nun UnicodeString ist. Die Implementierung des Typs Char kann sich in zukünftigen Versionen ändern. Wenn Sie Programme schreiben, in denen Zeichen unterschiedlicher Länge verarbeitet werden, sollten Sie deshalb statt hart codierter Konstanten die Standardfunktion SizeOf verwenden.
  • AnsiChar-Werte stellen auf Byte-Größe (8 Bit) ausgerichtete Zeichen dar. Ihre Reihenfolge wird durch den Zeichensatz des Gebietsschemas festgelegt, wobei es sich auch um einen Multibyte-Zeichensatz handeln kann.
  • WideChar-Werte stellen Zeichen mit einer Länge von mehr als einem Byte dar. In aktuellen Implementierungen repräsentieren Werte des Typs WideChar auf Word-Größe ausgerichtete (16 Bit) Zeichen. Die Größe kann sich in zukünftigen Implementierungen erhöhen. Die Reihenfolge der Zeichen ist durch den Unicode-Zeichensatz definiert. Die ersten 256 Zeichen des Unicode-Zeichensatzes entsprechen den ANSI-Zeichen.
  • Der Typ UCS2Char ist ein Alias für WideChar.
  • UCS4Char wird für 4 Byte große Unicode-Zeichen verwendet.

Eine String-Konstante der Länge 1 (wie "A") kann einen Zeichenwert darstellen. Die vordefinierte Funktion Chr gibt den Zeichenwert aller Integer-Werte im Bereich von WideChar zurück. So gibt beispielsweise Chr(65) den Buchstaben A zurück.

Wie Integer-Werte liefern auch AnsiChar- und WideChar-Werte den ersten bzw. den letzten Wert im Bereich, wenn der höchste Wert erhöht oder der niedrigste verringert wird. Beispielsweise hat nach Ausführung des Codes:

var Letter: AnsiChar;
I: Integer;
begin
  Letter := High(Letter);
  for I := 1 to 66 do Inc(Letter);
end;

Letter den Wert A (ASCII 65).

Hinweis: Die Typen AnsiChar und WideChar werden von den mobilen Object Pascal-Compilern nicht unterstützt, aber von den Object Pascal-Desktop-Compilern verwendet. Weitere Informationen finden Sie unter Migrieren von Object Pascal-Code zu mobilen Anwendungen vom Desktop aus.

Boolesche Typen

Es gibt 4 vordefinierte boolesche Typen: Boolean, ByteBool, WordBool und LongBool. In der Praxis wird in erster Linie der Typ Boolean verwendet. Die anderen Typen dienen der Kompatibilität zu anderen Sprachen und Betriebssystembibliotheken.

Eine Boolean-Variable belegt ebenso wie eine ByteBool-Variable ein Byte Speicherplatz. Eine WordBool-Variable belegt 2 (ein Word) und eine LongBool-Variable 4 Byte (2 Words).

Boolesche Werte werden mit den vordefinierten Konstanten True und False dargestellt. Dabei gelten folgende Beziehungen:

Boolean ByteBool, WordBool, LongBool

False < True

False <> True

Ord(False) = 0

Ord(False) = 0

Ord(True) = 1

Ord(True) <> 0

Succ(False) = True

Succ(False) = True

Pred(True) = False

Pred(False) = True


Ein Wert vom Typ ByteBool, LongBool oder WordBool hat den Wert True, wenn seine ordinale Position ungleich null ist. Tritt ein derartiger Wert in einem Kontext auf, in dem ein Wert vom Typ Boolean erwartet wird, wandelt der Compiler automatisch einen Wert mit einer Ordinalposition ungleich null in den Wert True um.

Die obigen Erläuterungen beziehen sich auf die Ordinalposition von booleschen Werten, nicht jedoch auf die Werte selbst. In Object Pascal können boolesche Ausdrücke nicht mit Integer- oder reellen Typen verglichen werden. Wenn beispielsweise X eine Integer-Variable ist, führt die Anweisung:

if X then ...;

deshalb zu einem Compilierungsfehler. Die Umwandlung der Variable in einen booleschen Typ ist nicht empfehlenswert. Verwenden Sie stattdessen eine der folgenden Alternativen:

 if X <> 0 then ...;    { use an expression that returns a Boolean value }
  ...
 var OK: Boolean;       { use a Boolean variable }
   ... 
 if X <> 0 then
   OK := True;
 if OK then ...;

Aufzählungstypen

Aufzählungstypen definieren eine Menge von Werten mit eindeutiger Reihenfolge, indem einfach die einzelnen Bezeichner dieser Werte aneinander gereiht werden. Die Werte haben keine eigene Bedeutung. Die Syntax für die Deklaration eines Aufzählungstyps lautet:

 type typeName = (val1, ...,valn)

typeName und val sind dabei gültige Bezeichner. Beispiel:

type Suit = (Club, Diamond, Heart, Spade);

Hier wird ein Aufzählungstyp mit dem Namen Suit mit den Werten Club, Diamond, Heart und Spade deklariert. Ord(Club) gibt 0, Ord(Diamond) 1 usw. zurück.

Bei der Deklaration eines Aufzählungstyps wird jeder val-Wert als Konstante des Typs typeName deklariert. Wenn die val-Bezeichner innerhalb desselben Gültigkeitsbereichs auch für einen anderen Zweck eingesetzt werden, können Namenskonflikte auftreten. Angenommen, Sie deklarieren folgenden Typ:

type TSound = (Click, Clack, Clock)

Click ist gleichzeitig der Name einer Methode, die für die Klasse TControl und für alle von ihr abgeleiteten Objekte in der VCL definiert ist. Wenn Sie eine Anwendung entwickeln und die folgende Ereignisbehandlungsroutine erstellen, tritt ein Compilierungsfehler auf:

 procedure TForm1.DBGridEnter(Sender: TObject);
  var
     Thing: TSound;
     begin 
       ... 
       Thing := Click;
     end;

Der Compiler interpretiert Click innerhalb des Gültigkeitsbereichs der Prozedur als Referenz auf die Methode Click von TForm. Sie können dieses Problem umgehen, indem Sie den Bezeichner qualifizieren. Wenn TSound beispielsweise in MyUnit deklariert ist, lautet die korrekte Anweisung:

Thing := MyUnit.Click;

Die bessere Lösung besteht aber in der Verwendung von Konstantennamen, die nicht mit anderen Bezeichnern in Konflikt stehen. Beispiele:

type
  TSound = (tsClick, tsClack, tsClock);
  TMyColor = (mcRed, mcBlue, mcGreen, mcYellow, mcOrange);
  Answer = (ansYes, ansNo, ansMaybe)

Sie können die Konstruktion (val1, ..., valn) wie einen Typnamen direkt in einer Variablendeklaration angeben:

var MyCard: (Club, Diamond, Heart, Spade);

Nach dieser Deklaration von MyCard ist es aber nicht mehr möglich, im selben Gültigkeitsbereich eine weitere Variable mit diesen Konstantenbezeichnern zu deklarieren. Die Deklaration:

 var Card1: (Club, Diamond, Heart, Spade);
 var Card2: (Club, Diamond, Heart, Spade);

führt deshalb zu einem Compilierungsfehler. Dagegen wird:

var Card1, Card2: (Club, Diamond, Heart, Spade);

ebenso wie die folgenden Anweisungen fehlerfrei compiliert:

type 
  Suit = (Club, Diamond, Heart, Spade); 
  var 
    Card1: Suit;
    Card2: Suit;

Aufzählungstypen mit expliziter Ordinalposition

Die Zählung der Ordinalposition von Aufzählungswerten beginnt standardmäßig bei 0 und entspricht dann der Reihenfolge, in der die Bezeichner in der Typdeklaration aufgeführt sind. Sie können diese Reihenfolge überschreiben und bestimmten oder allen Werten in der Deklaration eine explizite Ordinalposition zuweisen. Geben Sie dazu nach dem Bezeichner = konstanterAusdruck ein. Dabei ist konstanterAusdruck ein konstanter Ausdruck, der zu einem Integer-Wert ausgewertet wird. Zum Beispiel:

type Size = (Small = 5, Medium = 10, Large = Small + Medium);

Diese Deklaration definiert einen Aufzählungstyp mit Namen Size mit den Werten Small, Medium und Large. Ord(Small) gibt in diesem Fall 5 zurück, Ord(Medium) 10 und Ord(Large) 15.

Im Grunde stellt ein Aufzählungstyp einen Teilbereich dar, dessen niedrigster und höchster Wert der niedrigsten und höchsten Ordinalposition der Konstanten in der Deklaration entsprechen. Der Typ Size im obigen Beispiel kann 11 Werte umfassen, deren Ordinalpositionen von 5 bis 15 reichen (der Typ array[Size] of Char repräsentiert also ein Array mit 11 Zeichen). Nur drei dieser Werte verfügen über einen Namen. Auf die anderen Werte kann über Typumwandlungen und Routinen wie Pred, Succ, Inc und Dec zugegriffen werden. Im folgenden Beispiel werden der Variable X anonyme Werte im Bereich von Size zugewiesen.

var 
  X: Size; 
  X := Small;   // Ord(X) = 5 
  X := Size(6); // Ord(X) = 6 
  Inc(X);       // Ord(X) = 7

Die Ordinalposition eines Wertes ohne explizite Ordinalposition ist um 1 größer als die des vorhergehenden Wertes in der Liste. Wenn dem ersten Wert keine Ordinalposition zugewiesen wird, hat er die Position 0. Daher hat bei der folgenden Deklaration:

type SomeEnum = (e1, e2, e3 = 1);

SomeEnum nur zwei mögliche Werte: Ord(e1) gibt 0 zurück, Ord(e2) 1 und Ord(e3) ebenfalls 1. Da e2 und e3 dieselbe Ordinalposition haben, stellen sie denselben Wert dar.

Aufzählungskonstanten ohne festgelegten Wert haben Laufzeittypinformationen (RTTI):

type SomeEnum = (e1, e2, e3);

Bei Aufzählungskonstanten mit einem festen Wert ist dies nicht der Fall:

type SomeEnum = (e1 = 1, e2 = 2, e3 = 3);

Bereichsabhängige Aufzählungen

In Object Pascal-Quelltext können Sie bereichsabhängige Aufzählungen verwenden, wenn Sie die Compiler-Direktive {$SCOPEDENUMS ON} aktivieren.

Die Compiler-Direktive {$SCOPEDENUMS ON oder OFF} aktiviert oder deaktiviert die Verwendung von bereichsabhängigen Aufzählungen im Object Pascal-Quelltext. {$SCOPEDENUMS ON} legt fest, dass Aufzählungen bereichsabhängig sind. {$SCOPEDENUMS ON} wirkt sich bis zur nächsten Direktive {$SCOPEDENUMS OFF} auf Deklarationen von Aufzählungstypen aus. Die in den Aufzählungstypen eingeführten und nach der Direktive {$SCOPEDENUMS ON} deklarierten Bezeichner von Aufzählungen werden nicht dem globalen Gültigkeitsbereich hinzugefügt. Um einen bereichsabhängigen Aufzählungsbezeichner zu verwenden, müssen Sie ihn mit dem Namen des Aufzählungstyps qualifizieren, der diesen Bezeichner eingeführt hat.

Definieren Sie zum Beispiel in der Datei Unit1.pas die folgende Unit

unit Unit1;
interface
// {$SCOPEDENUMS ON} // clear comment from this directive
 type
   TMyEnum = (First, Second, Third);
implementation
 
end.

und das folgende Programm, das diese Unit verwendet

program Project1;
{$APPTYPE CONSOLE}

uses
  SysUtils, Unit1 in 'Unit1.pas';
 
var
  // First: Integer;  // clear comment from this variable
  Value: TMyEnum;
begin
  try
    Value := First;   
//  Value := TMyEnum.First; 
//  Value := unit1.First; 
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.

Jetzt können Sie die Auswirkungen der Compiler-Direktive {$SCOPEDENUMS} auf die Gültigkeitsbereiche untersuchen, in denen die Bezeichner First, Second und Third sichtbar sind, die in der Aufzählung TMyEnum definiert wurden.

Führen Sie zunächst diesen Code mit Start (F9) aus. Der Code wird erfolgreich ausgeführt. Das bedeutet, dass der Bezeichner First, der in der Variable

Value := First;

verwendet wird, der globale Bereichsbezeichner ist, der im Aufzählungstyp

TMyEnum = (First, Second, Third);

eingeführt wurde.

Entfernen Sie jetzt den Kommentar aus der Compiler-Direktive

{$SCOPEDENUMS ON}

in der Unit unit1. Diese Direktive veranlasst, dass die Aufzählung TMyEnum bereichsabhängig verwendet wird. Führen Sie den Code mit Start aus. Der Fehler E2003 Undeklarierter Bezeichner 'First' wird für die Zeile

Value := First;

erzeugt. Dieser Fehler informiert darüber, dass die Compiler-Direktive {$SCOPEDENUMS ON} verhindert, dass der in der bereichsabhängigen Aufzählung TMyEnum eingeführte Bezeichner First dem globalen Gültigkeitsbereich hinzugefügt wird.

Für die Verwendung von Bezeichnern, die in bereichsabhängigen Aufzählungen eingeführt wurden, stellen Sie einer Referenz auf ein Element einer Aufzählung deren Typnamen voran. Entfernen Sie beispielsweise den Kommentar aus der zweiten Version von

Value := TMyEnum.First;

der Variable Value (und kommentieren Sie die erste Version von Value aus). Führen Sie den Code mit Start aus. Das Programm wird erfolgreich ausgeführt. Das bedeutet, dass der Bezeichner First im Bereich TMyEnum bekannt ist.

Kommentieren Sie nun die Compiler-Direktive

// {$SCOPEDENUMS ON}

in der Unit unit1 aus. Entfernen Sie dann den Kommentar aus der Deklaration der Variable First

First: Integer; 

und verwenden Sie wieder die Variable

Value := First;

Der Code in program Project1 sieht nun folgendermaßen aus:

var
  First: Integer;   
  Value: TMyEnum;
begin
  try
    Value := First;

Führen Sie den Code mit Start aus. Die Zeile

 First: Integer;   

verursacht den Fehler E2010 Inkompatible Typen - 'TMyEnum' und 'Integer'. Das bedeutet, dass der Namenskonflikt zwischen dem globalen Bereichsbezeichner First, der in der Aufzählung TMyEnum eingeführt wurde, und der Variable First auftritt. Sie können diesen Konflikt umgehen, indem Sie den Bezeichner First mit der Unit unit1, in der er definiert wurde, qualifizieren. Kommentieren Sie dazu erneut die erste Version der Variable Value aus, und entfernen Sie den Kommentar aus der dritten Version:

Value := unit1.First;

Führen Sie den Code mit Start aus. Das Programm wird erfolgreich ausgeführt. Das heißt, dass jetzt der Bezeichner First mit dem Unit-Gültigkeitsbereich unit1 qualifiziert werden kann. Was passiert aber, wenn Sie erneut die Compiler-Direktive

{$SCOPEDENUMS ON}

in der Unit unit1 aktivieren. Der Compiler erzeugt den Fehler E2003 Undeklarierter Bezeichner 'First' für die Zeile

Value := unit1.First;

Das bedeutet, dass {$SCOPEDENUMS ON} das Hinzufügen des Aufzählungsbezeichners First zum Gültigkeitsbereich unit1 verhindert. Jetzt wird der Bezeichner First nur dem Gültigkeitsbereich der Aufzählung TMyEnum hinzugefügt. Um dies zu überprüfen, verwenden Sie erneut die Version

Value := TMyEnum.First;

der Variable Value. Führen Sie den Code mit Start aus. Er wird erfolgreich ausgeführt.

Teilbereichstypen

Ein Teilbereich ist eine Untermenge der Werte eines anderen ordinalen Typs (des sogenannten Basistyps). Alle Konstruktionen der Form Erster..Letzter, in denen Erster und Letzter konstante Ausdrücke desselben ordinalen Typs sind und Erster kleiner als Letzter ist, bezeichnen einen Teilbereichstyp, der alle Werte von Erster bis Letzter enthält. Beispielsweise können Sie für den deklarierten Aufzählungstyp:

type 
  TColors = (Red, Blue, Green, Yellow, Orange, Purple, White, Black);

einen Teilbereichstyp der folgenden Form definieren:

type 
  TMyColors = Green..White;

In diesem Fall umfasst TMyColors die Werte Green, Yellow, Orange, Purple und White.

Zur Definition von Teilbereichstypen können auch numerische Konstanten und Zeichen (String-Konstanten der Länge 1) verwendet werden:

type 
 SomeNumbers = -128..127;
 Caps = 'A'..'Z';

Bei der Verwendung von numerischen oder Zeichenkonstanten ist der Basistyp der kleinste Integer- oder Zeichentyp, der den angegebenen Bereich enthält.

Die Konstruktion Untergrenze..Obergrenze funktioniert wie ein Typname, weshalb sie auch direkt in der Variablendeklaration verwendet werden kann. Zum Beispiel:

var SomeNum: 1..500;

Hier wird eine Integer-Variable deklariert, deren Wert im Bereich von 1 bis 500 liegt.

Die Ordinalposition der Werte eines Teilbereichs wird vom Basistyp bestimmt. (Wenn im ersten Beispiel Color eine Variable mit dem Wert Green ist, liefert Ord(Color) den Wert 2 zurück, unabhängig davon, ob Color den Typ TColors oder TMyColors hat.) Eine Erhöhung oder Verringerung über die Grenzen eines Teilbereichs hinaus führt nur dazu, dass der Wert in den Basistyp umgewandelt wird. Dies gilt auch dann, wenn der Basistyp ein Integer- oder Zeichentyp ist. Während die Deklaration:

 type Percentile = 0..99;
 var I: Percentile;
   ... 
   I := 100;

einen Fehler ergibt, weist die Anweisung:

 ...
 I := 99;
 Inc(I);

der Variable I den Wert 100 zu (sofern die Bereichsprüfung des Compilers deaktiviert ist).

Die Verwendung von konstanten Ausdrücken in Teilbereichsdefinitionen bringt ein syntaktisches Problem mit sich. Wenn in einer Typdeklaration das erste bedeutungstragende Zeichen nach einem Gleichheitszeichen (=) eine öffnende Klammer ist, geht der Compiler davon aus, dass ein Aufzählungstyp definiert wird. Somit führt der Code:

 const X = 50; Y = 10;
 type Scale = (X - Y) * 2..(X + Y) * 2;

zu einem Fehler. Sie können dieses Problem umgehen, indem Sie bei der Typdeklaration die führende Klammer vermeiden:

 type Scale = 2 * (X - Y)..(X + Y) * 2;

Reelle Typen

Ein reeller Typ definiert eine Menge von Zahlen, die in der Gleitkommanotation dargestellt werden können. Die folgende Tabelle enthält die Bereiche und Speicherformate für die reellen Typen auf 64-Bit- und 32-Bit-Plattformen.

Reelle Typen

Typ Positiver Näherungsbereich Signifikante Stellen Größe in Byte
Real48 2,9e-39 .. 1,7e+38 11-12 6
Single 1,5e-45 .. 3,4e+38 7-8 4
Double 5,0e-324 .. 1,7e+308 15-16 8
Real 5,0e-324 .. 1,7e+308 15-16 8
Extended
  • 32-Bit-Plattformen 3,4e-4932 .. 1,1e+4932
  • 64-Bit-Plattformen 5,0e-324 .. 1,7e+308
10-20

15-16

10

8

Comp -263+1 .. 263-1 10-20 8
Currency -922337203685477.5808.. 922337203685477.5807 10-20 8

Die folgenden Erläuterungen beziehen sich auf reellen Typen:

  • Der generische Typ Real entspricht in seiner aktuellen Implementierung dem Typ Double.
  • Real48 wird nur aus Gründen der Abwärtskompatibilität verwendet. Da das Speicherformat dieses Typs kein natives Format der Intel-Prozessorarchitektur ist, laufen die entsprechenden Operationen langsamer ab als mit anderen Gleitkommatypen.
Der Typ Real48 (6 Byte) hatte in früheren Object Pascal-Versionen den Namen Real. Wenn Sie Quelltext neu compilieren, der den alten Typ Real (6 Byte) in Object Pascal enthält, ändern Sie diesen Typ in Real48. Die Compiler-Direktive {$REALCOMPATIBILITY ON} wandelt den Typ Real wieder in den alten 6-Byte-Typ um.
  • Extended bietet eine höhere Genauigkeit auf 32-Bit-Plattformen als andere reelle Typen.
Auf 64-Bit-Plattformen ist Extended ein Alias für ein Double; das heißt, dass die Größe des Datentyps Extended 8 Byte beträgt. Auf 64-Bit-Plattformen bietet Extended daher eine geringer Genauigkeit als auf 32-Bit-Plattformen, auf denen Extended 10 Byte groß ist. Wenn Sie in Ihren Anwendungen den Datentyp Extended verwenden und Genauigkeit bei Gleitkommaberechnungen wichtig ist, könnte sich dieser Größenunterschied daher auf Ihre Daten auswirken. Verwenden Sie Extended mit Bedacht, wenn Sie Datendateien anlegen, die gemeinsam und plattformübergreifend genutzt werden sollen. Weitere Informationen finden Sie unter Der Datentyp "Extended" ist auf 64-Bit-Windows-Systemen 2 Byte kleiner.
  • Der Typ Comp (für "computational") ist ein natives Format der Intel-Prozessorarchitektur und stellt einen 64-Bit-Integer dar. Er ist dennoch als reeller Typ klassifiziert, weil sein Verhalten nicht dem eines ordinalen Typs entspricht. (Ein Comp-Wert kann beispielsweise weder inkrementiert noch dekrementiert werden.) Comp ist nur aus Gründen der Abwärtskompatibilität vorhanden. Eine höhere Ausführungsgeschwindigkeit erreichen Sie mit dem Typ Int64.
  • Currency ist ein Festkomma-Datentyp, der Rundungsfehler in finanzmathematischen Berechnungen minimiert. Er wird als skalierter 64-Bit-Integer gespeichert, bei dem die 4 niedrigstwertigen Stellen implizit vier Nachkommastellen repräsentieren. Bei einer Kombination mit anderen reellen Typen in Zuweisungen und Ausdrücken werden Currency-Werte automatisch mit 10.000 multipliziert.

Siehe auch