Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Pointer


01Detlef - Do 10.04.03 15:56
Titel: Pointer
hallo,

ich habe noch so meine Probleme mit den zeigern:


Quelltext
1:
2:
3:
4:
5:
6:
Var a : Byte;
      zeiger_auf_byte : ^Byte;
BEGIN
 zeiger_auf_Byte := Addr(a) // Speichert die Adresse von a ?!
 a:= 1 //Die Adresse erhält den Wert 1?
...


Worin besteht der Sinn in Zeigern? Um a jetzt einen anderen Wert zu zuordnen muss dass dann so aussehen:

Quelltext
1:
2:
a:= 5;
zeiger_auf_a^ := 5;


Dadurch wird doch Speicherplatz gespart!

Danke Detlef


Klabautermann - Do 10.04.03 18:15

Hallo,

Zeiger sparen keinen speicher sie verbrauchen sogar ein wenig mehr (neben den Nutzdaten wird auch noch speicher für die Adresse belegt). Sie sind aber immer dann wichtig, wenn du beim Programmieren noch nicht weißt, wie viel Speicher (Variablen) du später benötigst. Du kannst nämlich zur laufzeit Speicher reservieren und mit Zeigern referenzieren. Heutzutage gibt es als alternative noch Dynamische-Arrays.
Desweiteren sind Zeiger sehr praktisch, wenn du Datenstukturen hast bei denen bestimme Objekte ein oder mehrere andere Refenzieren z.B. Baumstruktuten.
Ein kleines Beispiel wie du mit Zeigern zur Laufzeit Speicher reservierst, damit arbeitest und ihn wieder freigibst habe ich mal hier [http://www.delphi-forum.de/viewtopic.php?p=12751#12751] gegeben.

Gruß
Klabautermann


Motzi - Do 10.04.03 20:09

Erweiternd kann ich dir das Tutorial auf http://www.mydelphi.de empfehlen! ;) 8)


01Detlef - Fr 11.04.03 15:38

ok, werde ich jetzt mal durcharbeiten!

Habt ihr vielleicht noch ein Tutorial zu Verketteten Listen? Die Funktion und der Einsatz von Pointern ist mir da noch nicht so klar!

Ach ja, ersetzt eigentlich jetzt das New(p1) diese schreibweise p1^? oder ist New(p1) gleich Addr(p1)?


Danke Detlef


Klabautermann - Fr 11.04.03 15:48

Hallo,
01Detlef hat folgendes geschrieben:
Ach ja, ersetzt eigentlich jetzt das New(p1) diese schreibweise p1^? oder ist New(p1) gleich Addr(p1)?

New(p1) reserviert Speicher von dem Typ aus dem P1 Zeigen soll, und lässt p1 drauf zeigen. Bevor du New(p1) aufgerufen hasst, Zeigt p1 irgendwohin (oder wenn du initialisiert hast dann auf NIL) und kannst p1^ noch nciht sinvoll verwenden.

Hier ein ausschnitt aus dem obern verlinkten Beispiel:
Es geht um verkettete Listen die als Daten Realwerte enhalten sollen, deshalb sehen die Datentypen so aus:

Quelltext
1:
2:
3:
4:
5:
6:
TYPE 
  pRealList = ^tRealList; 
  tRealList = RECORD 
   Value : Real; // Nutzdaten
   Next : pRealList; // Zeiger auf dan nächste Element
  END; // tRealList

Und so wird der Liste ein neues Element hinzugefügt (es wird ans Ende angehängt (Last in Last Out [LILO]):

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
procedure Appent2RealList(Value : Real; aList : pRealList); 
  VAR 
   Runner, NewEle : pRealList; 
 BEGIN 
  NEW(NewEle); // Hier wird Speicher für das neue Element reserviert
  NewEle^.Value := Value; // nur deshalb kann das hier funktionieren
  NewEle.Next := NIL; // Da dies das letzte element sein soll gibt es kein nächstes
  Runner := aList; 
  IF (Runner = NIL) THEN // Sonderfall Liste ist leer 
   aList := NewEle 
  ELSE BEGIN // Eintrag anhängen 
   WHILE (Runner^.Next <> NIL) DO
    Runner := Runner^.Next; 
   Runner^.Next := NewEle; 
  END; // Eintrag anhängen 
 END; // Appent To RealList


Gruß
Klabautermann


Udontknow - Fr 11.04.03 15:51

Zitat:
Ach ja, ersetzt eigentlich jetzt das New(p1) diese schreibweise p1^? oder ist New(p1) gleich Addr(p1)?

Weder noch. New reserviert Speicherbereich in der Größe des vom übergebenen Zeiger referenzierten Datentyps und gibt eben die Adresse des zugewiesenen Speicherbereichs an den Pointer zurück. Ähnliches erreicht man mit Getmem.

Cu,
Udontknow


01Detlef - Fr 11.04.03 18:24

Vielen Dank!

Den Code habe ich verstanden! Aber was will man mit den verketteten Listen erreichen? Oft ist doch eine edit-Kompo und Weiter-Button! Soll man dann da was eingeben und was soll passieren?


Detlef