Programmiersprache Pascal

Manipulation von Zeigern

Die direkte Veränderung des Wertes von Zeigern, d.h. die Manipulation von Adressen ist weder in Standard noch in Extended Pascal möglich.

Es gibt jedoch Pascal-Systeme, die hier Ausnahmen machen: Turbo Pascal, Delphi.


Turbo Pascal

Zur Manipulation von Adressen können die Prozeduren Inc und Dec eingesetzt werden:

  VAR p : ^typ;

  Inc(p);       { erhöht die Adresse um SizeOf(typ) }
  Dec(p);       { erniedrigt die Adresse um SizeOf(typ) }
SizeOf(typ) ist der Speicherbedarf für ein Element mit dem Datentyp typ.

Arithmetische Operationen dürfen mit Adreßwerten nicht (direkt) ausgeführt werden.

Beispiel 1:

  PROGRAM ptr_aria;

  VAR a : ARRAY[1..5] OF INTEGER;
      p : ^INTEGER;
      i : INTEGER;

  BEGIN
    FOR i:=1 TO 5 DO
      a[i] := i;

    p := @a;
    FOR i := 1 TO 5 DO BEGIN
      Write(p^:2);
      Inc(p);
    END;
    Writeln;
  END.
Eine Alternative zur obigen Lösung beruht auf der Ausnutzung der Struktur einer Adresse unter DOS:
Die Adresse besteht aus einer Segmentadresse und einem Offset, die beide 16 Bit lang sind und deshalb in einer INTEGER-Variable gespeichert werden können.
Segment- und Offsetadresse können mit Hilfe der Prozeduren Seg und Ofs bestimmt werden. Mittels Ptr läßt sich aufbauend auf Segment und Offset eine neue Adresse bilden.

  PROGRAM ptr_arip;

  VAR a : ARRAY[1..5] OF INTEGER;
      p : ^INTEGER;
      ps, po : INTEGER;
      i : INTEGER;

  BEGIN
    FOR i:=1 TO 5 DO
      a[i] := i;

    ps := Seg(a); po := Ofs(a);
    FOR i := 1 TO 5 DO BEGIN
      p := Ptr(ps, po);
      Write(p^:2);
      po := po + SizeOf(INTEGER);
    END;
    Writeln;
  END.
Im Gegensatz zur eigentlichen Adresse können auf Segment- und Offsetadresse alle Operationen angewendet werden, die für ganzzahlige Variablen zulässig sind.

Beispiel 2:

  PROGRAM ptr_arit;

  VAR str : STRING[32];    { Turbo-Pascal-Zeichenkette }
      b : ^CHAR;
      i : INTEGER;

  BEGIN
    str := 'Pointer lassen sich manipulieren';
    Writeln(str);
    b := @str;
    FOR i := 1 TO Length(str) DO BEGIN
      Inc(b);
      Write(b^);
    END;
    Writeln;

    FOR i := 1 TO Length(str) DO BEGIN
      Write(b^);
      Dec(b);
    END;
    Writeln;
  END.
Testergebnis
  Pointer lassen sich manipulieren
  Pointer lassen sich manipulieren
  nereilupinam hcis nessal retnioP

Delphi

Es gibt prinzipiell die gleichen Möglichkeiten wie bei Turbo Pascal.
Zu beachten sind jedoch die Unterschiede bei der Adressierung unter DOS und den verschiedenen Windows-Versionen.

Beispiel: (Delphi)

  PROGRAM ptr_arit;
  USES SysUtils;

  VAR str : ARRAY[0..32] OF CHAR;   { Null-terminierte Zeichenkette }
      b : ^CHAR;
      i : INTEGER;

  BEGIN
    StrCopy(str, 'Pointer lassen sich manipulieren');
    Writeln(str);
    b := @str;
    FOR i := 1 TO StrLen(str) DO BEGIN
      Write(b^);
      Inc(b);
    END;
    Writeln;

    FOR i := 1 TO StrLen(str) DO BEGIN
      Dec(b);
      Write(b^);
    END;
    Writeln;
  END.
Das Programm liefert die gleichen Ergebnisse wie das unter Turbo Pascal angegebene Beispiel 2.
Beide Programme unterscheiden sich in der Art der verwendeten Zeichenkette: Zu beachten ist die unterschiedliche interne Speicherung und die Nutzung unterschiedlicher Funktionen.



P. Böhme, 28.09.1996