4D v16.3

Zeiger

Home

 
4D v16.3
Zeiger

Zeiger  


 

Mit Hilfe der Zeiger können Sie Ihre Methoden strukturunabhängig schreiben und dadurch Ihre Programme übertragbarer gestalten.

Sie können mit einem Zeiger Objekte wie Tabellen, Variablen lesen oder ändern, ohne das Objekt genau anzugeben, bzw. ohne genau zu wissen, welches Objekt es ist.

Hinter einem Zeiger steht folgendes Konzept: Einen gesuchten Rechner erkennen Sie normalerweise an seiner Seriennummer. Dies ist aber nicht der einzige Weg. Sie können ihn auch über seinen Besitzer identifizieren. Sprechen Sie den Rechner über die Seriennummer an, nennt man das "direktes" Ansprechen; sprechen Sie ihn über den Besitzer an, z. B. "Meier’s PC", so nennt man das "indirektes" Ansprechen. Diese Methode hat einige Vorteile: Meier kann seinen Rechner beliebig auswechseln. Sie erkennen ihn immer an seinem Besitzer. Das Objekt wird also über eine Art Vermittler, der auf das Objekt zeigt, angesprochen.

Mit Zeigern können Sie auf Tabellen, Datenfelder, Variablen, Arrays und Tabellenelemente verweisen. Folgende Tabelle zeigt ein Beispiel für jeden Datentyp:

ObjektReferenzVerwendenZuweisen

Tabelle
vpTable:=->[Table]DEFAULT TABLE(vpTable->)---
DatenfeldvpField:=->[Table]FieldALERT(vpField->)vpField->:="John"
VariablevpVar:=->VariableALERT(vpVar->) vpVar->:="John"
ArrayvpArr:=->ArraySORT ARRAY(vpArr->;>) COPY ARRAY (Arr;vpArr->)
Array ElementvpElem:=->Array{1}ALERT (vpElem->)vpElem->:="John"

Wir erläutern die Verwendung von Zeigern an einem Beispiel. Wir erstellen zuerst eine Variable:

 MyVar:="Hello"

MyVar ist nun eine Variable mit der Zeichenkette “Hello”. Wir erstellen nun den Zeiger für MyVar:

 MyPointer:=->MyVar

Das Symbol -> bedeutet “setze Zeiger auf.” Dieses Symbol ist die Kombination aus einem Bindestrich und dem Zeichen “größer als”. In diesem Fall zeigt der Zeiger auf MyVar. Der Zeiger wird mit dem Zuordnungsoperator dem Zeiger MyPointer zugewiesen.

MyPointer ist nun eine Variable mit einem Zeiger auf MyVar. MyPointer enthält nicht “Hello”, den Wert von MyVar, Sie erhalten diesen Wert über MyPointer. Folgender Ausdruck gibt den Wert in MyVar zurück:

 MyPointer->

In diesem Fall gibt er die Zeichenkette “Hello” zurück. Das Symbol -> nach dem Zeiger verweist auf das Objekt, auf das gezeigt wird. Das nennt man Dereferenzierung.

Sie können den Ausdruck MyPointer-> überall verwenden, wo Sie auch die urspüngliche Variable MyVar einsetzen können.

Folgende Programmierzeile zeigt eine Warnung mit dem Wort Hello:

 ALERT(MyPointer->)

Über MyPointer können Sie auch den Inhalt von MyVar ändern. Folgendes Statement speichert die Zeichenkette "Goodbye" in der Variablen MyVar:

 MyPointer->:="Goodbye"

Wie Sie sehen, verhält sich der Ausdruck MyPointer-> wie die Variable MyVar. Die beiden nachfolgenden Zeilen führen dieselbe Aktion aus—beide zeigen eine Warnung mit dem aktuellen Wert der Variablen MyVar:

 ALERT(MyPointer->)
 ALERT(MyVar)

Die beiden nachfolgenden Zeilen führen dieselbe Aktion aus—beide weisen der Variablen MyVar die Zeichenkette "Goodbye" zu:

 MyPointer->:="Goodbye"
 MyVar:="Goodbye"

Dieser Abschnitt beschreibt die Verwendung von Zeigern am Beispiel Schaltflächen. Die Beschreibung gilt für alle Variablen, die über einen Zeiger angesprochen werden können.

Wir gehen von einer Anzahl Schaltflächen in Ihren Formularen aus, die aktiviert oder deaktiviert werden sollen. Jeder Schaltfläche ist eine Bedingung zugewiesen, die TRUE oder FALSE ist. Die Bedingung gibt an, ob die Schaltfläche aktiviert oder deaktiviert wird. Sie können den Status über folgenden Code prüfen:

 If(Condition) ` Ist die Bedingung TRUE…
    OBJECT SET ENABLED(MyButton;True` aktiviere Schaltfläche
 Else ` Sonst…
    OBJECT SET ENABLED(MyButton;False` deaktiviere Schaltfläche
 End if

Denselben Test benötigen Sie für alle weiteren Schaltflächen, lediglich der Name der Schaltfläche ändert sich. Hier bietet sich an, die Schaltfläche über einen Zeiger anzusprechen und für den eigentlichen Test eine Subroutine zu verwenden.

Bei Subroutinen müssen Sie Zeiger einsetzen, da Sie nur so die Variablen der Schaltflächen ansprechen können. Ihre Projektmethode könnte folgendermaßen aussehen:

  ` Projektmethode SET BUTTON
  ` SET BUTTON ( Pointer ; Boolean )
  ` SET BUTTON ( -> Button ; aktiviere oder deaktiviere )
  ` $1 – Zeiger auf eine Schaltfläche
  ` $2 – Boolean. Bei TRUE aktiviere die Schaltfläche. Bei FALSE deaktiviere die Schaltfläche
 
 If($2` Ist die Bedingung TRUE…
    OBJECT SET ENABLED($1->;True` aktiviere die Schaltfläche
 Else ` Sonst…
    OBJECT SET ENABLED($1->;False` deaktiviere die Schaltfläche
 End if

Die Projektmethode SET BUTTON aufrufen:

  ` ...
 SET BUTTON(->bValidate;True)
  ` ...
 SET BUTTON(->bValidate;False)
  ` ...
 SET BUTTON(->bValidate;([Employee]Last Name#"")
  ` ...
 For($vlRadioButton;1;20)
    $vpRadioButton:=Get pointer("r"+String($vlRadioButton))
    SET BUTTON($vpRadioButton;False)
 End for

Sie können auch einen Zeiger erstellen, der auf eine Tabelle zeigt. Sie definieren den Zeiger folgendermaßen:

 TablePtr:=->[anyTable]

Sie können einen Zeiger über die Funktion Table einrichten:

 TablePtr:=Table(20)

oder den dereferenzierten Zeiger in Befehlen verwenden:

 DEFAULT TABLE(TablePtr->)

Sie können einen Zeiger verwenden, der das Datenfeld anspricht. Sie definieren den Zeiger folgendermaßen:

 FieldPtr:=->[Table1]Field

Sie können einen Zeiger über die Funktion Field einrichten:

 FieldPtr:=Field(1;2)

oder den dereferenzierten Zeiger in Befehlen verwenden:

 OBJECT SET FONT(FieldPtr->;"Arial")

Das Beispiel zu Beginn dieses Abschnitts erläutert die Verwendung eines Zeigers auf eine Variable:

 MyVar:="Hello"
 MyPointer:=->MyVar

Sie können Zeiger auf Interprozess- und Prozessvariablen, ab Version 2004.1 auch auf lokale Variablen verwenden.

Bei Verwendung auf Prozess- oder lokale Variablen müssen Sie sicherstellen, dass die Variable, auf die gezeigt wird, bereits eingerichtet ist. Beachten Sie folgendes: Lokale Variablen werden gelöscht, wenn die Ausführung der Methode, welche diese erstellt hat, beendet ist; Prozessvariablen werden mit Beenden des Prozesses gelöscht, der sie erstellt hat. Ruft ein Zeiger eine Variable auf, die nicht mehr existiert, verursacht das im interpretierten Modus einen Syntaxfehler (Variable nicht definiert), im kompilierten Modus kann dies hingegen zu einem ernsteren Fehler führen.

Hinweis zu lokalen Variablen: Über Zeiger auf lokale Variablen lassen sich in vielen Fällen Prozessvariablen sichern. Zeiger auf lokale Variablen lassen sich nur im gleichen Prozess verwenden.
Im Debugger erscheint der ursprüngliche Methodenname nach dem Zeiger in Klammern, wenn Sie einen Zeiger auf eine lokale Variable anzeigen, die in einer anderen Methode deklariert wurde. Schreiben Sie zum Beispiel in Method1:

 $MyVar:="Hello world"
 Method2(->$MyVar)

Zeigt der Debugger in Method2 $1 wie folgt an:

$1 ->$MyVar (Method1)

Der Wert von $1 lautet:

$MyVar (Method1) "Hello world"

Sie können einen Zeiger auf ein Array Element erstellen. Im folgenden Beispiel wird ein Array erstellt und dem ersten Element des Array ein Zeiger auf die Variable ElemPtr zugewiesen:

 ARRAY REAL(anArray;10) `Array anlegen
 ElemPtr:=->anArray{1} `Zeiger auf das Array Element erstellen

Sie können den dereferenzierten Zeiger verwenden, um dem Element einen Wert zuzuweisen, z.B.:

 ElemPtr->.=8

Sie können auch einen Zeiger erstellen, der auf ein Array zeigt. Da Sie einer Methode kein komplettes Array als Parameter übergeben können, ist diese Möglichkeit besonders wichtig. Sie übergeben statt des Array einfach einen Zeiger und verwenden diesen in der Unterroutine, um so das Array anzusprechen.
Folgende Methode erstellt ein Array und weist dem Array einen Zeiger auf die Variable ArrPtr zu:

 ARRAY REAL(Array;10` Erstelle Array
 ArrPtr:=->Array ` Erstelle Zeiger auf Array

Beachten Sie, dass der Zeiger das Array anspricht und nicht ein Element dieses Arrays. Sie können den soeben angelegten Zeiger folgendermaßen einsetzen:

 SORT ARRAY(ArrPtr->;>) ` Sortiere Array

oder über den Zeiger das 4. Element des Arrays ansprechen:

 ArrPtr->{4}:=84

Mit einem Zeiger-Array können Sie eine Gruppe verknüpfter Objekte ansprechen.

Ein Beispiel dafür ist ein Variablenraster in einem Formular. Die Variablen im Raster sind durchnumeriert, also Var1, Var2, …, Var10. Oft müssen Sie diese Variablen indirekt mit einer Nummer ansprechen. Dafür erstellen Sie einen Zeiger-Array, und initialisieren die Zeiger, so dass jede Variable angesprochen wird. Sie schreiben folgenden Code:

 ARRAY POINTER(apPointer;10` Erstelle ein Array für 10 Zeiger
 For($i;1;10) ` Durchlaufe einmal für jede Variable
    apPointer{$i}:=Get pointer("Var"+String($i)) ` Initialisiere das Array Element
 End for

Die Funktion Get pointer gibt den Zeiger für das genannte Objekt zurück.

Sie sprechen eine beliebige Variable über die Elemente des Array an. Um z.B. Variablen vom Typ Datum mit den nächsten 10 Kalenderdaten zu füllen, schreiben Sie folgenden Code:

 For($i;1;10) ` Durchlaufe einmal für jede Variable
    apPointer{$i}->:=Current date+$i  ` Weise die Kalenderdaten zu
 End for

Über Zeiger können Sie rasch eine Gruppe verknüpfter Optionsfelder setzen. Die Schaltflächen sind durchnumeriert, also Button1, Button2, …, Button5.

In einer Gruppe von Optionsfeldern ist immer nur ein Optionsfeld an. Die Zahl dieses Optionsfeldes lässt sich in einem numerischen Datenfeld speichern. Beispiel: Enthält das Datenfeld [Preferences]Setting die Zahl 3, wird Button3 ausgewählt. Die Formularmethode zum Setzen der Schaltfläche lautet:

 Case of
    :(Form event=On Load)
  ` ...
       Case of
          :([Preferences]Setting=1)
             Button1:=1
          :([Preferences]Setting=2)
             Button2:=1
          :([Preferences]Setting=3)
             Button3:=1
          :([Preferences]Setting=4)
             Button4:=1
          :([Preferences]Setting=5)
             Button5:=1
       End case
  ` ...
 End case

Jedes Optionsfeld muss in einer eigenen Abfrage getestet werden. Das ergäbe bei vielen Optionsfeldern im Formular eine sehr lange Methode. Dafür verwenden Sie Zeiger. Mit der Funktion Get pointer können Sie einem Optionsfeld einen Zeiger zuordnen. Schreiben Sie dafür folgenden Code:

 Case of
    :(Form event=On Load)
  ` ...
       $vpRadio:=Get pointer("Button"+String([Preferences]Setting))
       $vpRadio->:=1
  ` ...
 End case

Die Zahl der gesetzten Schaltfläche muss im Datenfeld [Preferences]Setting gespeichert werden. Dafür verwenden Sie die Formularmethode für das Ereignis On Clicked:

 [Preferences]Setting:=Button1+(Button2*2)+(Button3*3)+(Button4*4)+(Button5*5)

Sie können einen Zeiger als Parameter in einer Methode übergeben. Die Methode TAKE TWO enthält zwei Parameter in Form von Zeigern. Das erste angesprochene Objekt wird in Großbuchstaben umgewandelt, das zweite in Kleinbuchstaben. Die Methode sieht folgendermaßen aus:

  ` Projektmethode TAKE TWO
  ` $1 – Zeiger auf alphanumerisches Feld oder Variable. Wandle dieses um in Großbuchstaben.
  ` $2 – Zeiger auf alphanumerisches Feld oder Variable. Wandle dieses um in Kleinbuchstaben.
 $1->:=Uppercase($1->)
 $2->:=Lowercase($2->)

Nachfolgende Zeile wandelt über die Methode TAKE TWO ein Datenfeld in Großbuchstaben um und eine Variable in Kleinbuchstaben:

 TAKE TWO(->[MyTable]MyField;->MyVar)

Das Datenfeld [MyTable]MyField mit dem alphanumerischen Inhalt "meier", wird umgewandelt in "MEIER". Die Variable MyVar mit dem alphanumerischen Inhalt "hello" wird umgewandelt in "Hello".

Achten Sie darauf, dass in der Methode TAKE TWO und immer, wenn Sie Zeiger verwenden das angesprochene Objekt vom richtigen Datentyp ist. Im vorigen Beispiel muss der Zeiger ein Objekt vom Typ alphanumerisch oder Text ansprechen.

Wenn Sie die Dinge komplexer machen wollen, können Sie auch Zeiger verwenden, die auf andere Zeiger verweisen. Beispiel:

 MyVar:="Hello"
 PointerOne:=->MyVar
 PointerTwo:=->PointerOne
 (PointerTwo->)->:="Goodbye"
 ALERT((Point Two->)->)

Es zeigt eine Warnung mit dem Inhalt “Goodbye”.

Im folgenden werden die einzelnen Zeilen erläutert:

  • MyVar:="Hello"
    --> Diese Zeile setzt die Zeichenkette "Hello" in die Variable MyVar.
  • PointerOne:=->MyVar
    --> PointerOne enthält nun den Zeiger auf MyVar.
  • PointerTwo:=->PointerOne
    --> PointerTwo (eine neue Variable) enthält einen Zeiger auf PointerOne, der auf MyVar zeigt.
  • (PointerTwo->)->:="Goodbye"
    --> PointerTwo-> verweist auf den Inhalt von PointerOne, der wiederum auf MyVar verweist.
    (PointerTwo->)-> verweist also auf den Inhalt von MyVar. In diesem Beispiel ist also der Variablen MyVar "Goodbye" zugewiesen.
  • ALERT ((PointerTwo->)->)
    --> Hier gilt das gleiche: PointerTwo->PointerTwo-> verweist auf den Inhalt von PointerOne, der wiederum auf MyVar verweist. (PointerTwo->)-> verweist also auf den Inhalt von MyVar. In diesem Beispiel zeigt die Warnung den Inhalt von MyVar an.

Die folgende Zeile setzt "Hello" in MyVar:

 (PointerTwo->)->:="Hello"

Die folgende Zeile nimmt "Hello" aus MyVar und setzt es in NewVar:

 NewVar:=(PointerTwo->)->

Wichtig: Bei mehrfacher Dereferenzierung müssen Sie mit Klammern arbeiten.



Siehe auch 

Ablaufsteuerung
Arrays und Zeiger
Datentypen
Einführung in Arrays
Konstanten
Methoden
Namenskonventionen
Operatoren
Variablen

 
EIGENSCHAFTEN 

Produkt: 4D
Thema: Grundbegriffe

 
GESCHICHTE 

 
ARTIKELVERWENDUNG

4D Programmiersprache ( 4D v16)
4D Programmiersprache ( 4D v16.1)
4D Programmiersprache ( 4D v16.2)
4D Programmiersprache ( 4D v16.3)