![]() |
allgemeine Pointer Frage
Hallo
Ich weiß blöde Überschrift Ich habe da eine Frage, die wohl Banal ist, nur mache ich immer und immer wieder den gleichen Fehler.
Delphi-Quellcode:
was ist der Unterschied
TBuffer = array[0..0] of byte;
var Buffer : ^TBuffer;
Delphi-Quellcode:
falsch
Stream.Write(Buffer, counter );
Delphi-Quellcode:
Also das Hochzeichen
richtig
Stream.Write(Buffer^, counter ); Ich weiß was Pointer sind nur blicke ich nicht wohin die Pointer hier zeigen |
AW: allgemeine Pointer Frage
Buffer bezeichnet den Pointer an sich, Buffer^ den Speicherbereich, auf den der Pointer zeigt (also Dein Array).
|
AW: allgemeine Pointer Frage
Wenn man das geziehlt für Klassen, oder einen neuen Klassentypen, optional aktivieren könnte, dann wäre es ja unproblematisch mit alten Codes kompatibel.
Delphi war mal stolz darauf mal sowas von abwärtskompatibel gewesen zu sein. |
AW: allgemeine Pointer Frage
ich hab's mir so gemerkt:
Delphi-Quellcode:
oder
Zeiger:=Adr(variable);
wie Himitsu es ausgeführt hat
Delphi-Quellcode:
der Zugriff erfolgt dann über
Zeiger:=@Variable;
Delphi-Quellcode:
wichtig ist nur
TIrgendeinTyp(Zeiger^)
Delphi-Quellcode:
enthält nur die Adressinformation, der eigentliche Wert ist in
Zeiger
Delphi-Quellcode:
Gruß
Zeiger^
K-H |
AW: allgemeine Pointer Frage
Mir stellt sich da spontan die Frage:
![]() Wieso ein Typecast auf PChar um dann den Pointer zu dereferenzieren?
Delphi-Quellcode:
Stream.Write(PChar(Daten[I].Name)^, Len);
kann man da nicht einfach
Code:
übergeben?
Daten[I].Name
grüße |
AW: allgemeine Pointer Frage
Lies doch einfach mal 3 Sätze weiter :zwinker:
|
AW: allgemeine Pointer Frage
ah :)
Okay, ich hatte folgendes gemacht: Wenn
Delphi-Quellcode:
mir nur die SpeicherAdresse in den STREAM schreibt dann kann Ich doch
myarray[I].mystring
Delphi-Quellcode:
direkt dereferenzieren oder?
myarray[I].mystring^
Dann gibts aber den Compilerfehler "Zeigertyp erforderlich". Dann Casten wir den String als PChar und dereferenzieren dann, wieso ist dann kein "Zeigertyp erforderlich"? Grüße |
AW: allgemeine Pointer Frage
Und da wundern sich manche, daß Pointer gerne gemieden werden.
Gruß K-H |
AW: allgemeine Pointer Frage
Ein "LongString" ist halt intern ein Zeiger.
Man könnte nun
Delphi-Quellcode:
übergeben, oder
str[1]
Delphi-Quellcode:
, nur daß Ersteres knallt, wenn der String leer ist, wärend PChar im Falle eines Leerstrings (intern nil) einen Zeiger auf einen alternativen "leeren String" zurückgibt (also einen "String" aus #0 bestehend, bzw. genauer aus #0#0)
PChar(str)^
Zitat:
aber lies die Datei mal morgen wieder aus :zwinker: (abgesehn davon, daß du dir dann beim Auslesen des "Zeigers" die automatische Speicherverwaltung des Strings zerschossen hast) Deswegen gibt es ja auch spezialisierte Streams, welche direkt mit Strings umgehen können. TStringStream, TReader, TWriter, TStringList uvm. |
AW: allgemeine Pointer Frage
Bevor wir hier langatmig erklären, verweise ich aus Faulheit auf den
![]() |
AW: allgemeine Pointer Frage
Okay bevor ich weiter leichtfertig Fragen stelle merke ich grade, da sind noch ein paar nette Sachen zu lernen.
Ich verstehe z.b. nicht warum in dem Tutorial LongInt genommen wurde und kein Integer. Oder warum es mit AnsiChar funktioniert aber falls ich aus dem Datentyp einen normalen String mache, nicht mehr richtig... Das mit dem Str[1] leuchtet ein. danke |
AW: allgemeine Pointer Frage
Vielleicht weil der autor damit betonen wollte, daß es sich um eine 32bit-Zahl handelt.
Ich würde dann ein longword bevorzugen, weil dann das Vorzeichen ausgeschlossen ist, aber über die Typen kann man trefflich streiten. Gruß K-H Zitat:
einen "normalen" String gibt es nicht! |
AW: allgemeine Pointer Frage
LongInt: Damals, als dieses tutorial geschrieben wurde, war Integer noch ein dynamischer Typ, bzw. ein Alias. (in Win 3.1 war er 16 Bit, in Win32 war er 32 Bit und in Win64 wäre er 64 Bit gewesen).
Nun war nur jemand auf die saublöde Idee gekommen den Integer einzufrieren (das war mal nicht Emba ... die sind C++ nur um Jahre verspätet nachgelaufen) und stattdessen wurd jetzt der NativeInt erfunden. Beim Speichern oder Datenübertragen sollte man aber grundsätzlich nur generische Typen verwenden, also Jene, welche sich niemals verändern. Einfaches Beispiel, welches sei 2009 immer wieder für Probleme sorgt, ist der Char, String, PChar usw.), wenn man das früher mit "ANSI" gespeichert hatte und nun versucht als Unicode auszulesen, dann muß das schief gehn. Oder eben die Verwendung von APIs ... wenn da Einer das als ANSI übergibt oder auslies und der Andere aber Unicode nutzt, dann paßt das ebenfalls nicht zusammen und keiner versteht was der Andere sagt. |
AW: allgemeine Pointer Frage
Ich möchte nochmal auf die Ausgangsfrage zurückkommen :stupid:
Man kann sich die Signatur von Write mal angucken:
Delphi-Quellcode:
function Write(const Buffer; Count: Longint): Longint; virtual; abstract;
Ein const-Parameter ist ein spezieller var-Parameter, also kennzeichnet const einen Call-By-Reference-Parameter. Dh. wenn du
Delphi-Quellcode:
aufrufst, übergibst du einen Zeiger (const) auf den Inhalt (^) eines Zeigers (buffer).
Stream.Write(Buffer^, counter );
Also hat die Funktion am Ende eine Referenz auf die Daten, die zu schreiben sind. Im Unterschied dazu übergibt
Delphi-Quellcode:
einen Zeiger (const) auf einen Zeiger (buffer).
Stream.Write(Buffer, counter );
Also hat die Funktion am Ende eine Referenz auf den Zeiger buffer und nicht auf die zu schreibenden Daten. |
AW: allgemeine Pointer Frage
Oh ich sehe so trivial war die Frage gar nicht.
Es ist nur blöd wenn man alle Jubeljahre so was macht und dann im Stream.Memory nur Schrott stehen hat. Supi für die vielen Antworten:thumb: |
AW: allgemeine Pointer Frage
Wertest du das Result von Write eigentlich aus?
Wenn nicht, dann verwende besser WriteBuffer, denn da ist wenigstens noch eine Prüfung mit eingebaut. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:58 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz