Reihenfolge der Zusammenstellung/Auswertung der Parameter beim Prozeduraufruf willkürlich?!

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
alfware17
Beiträge: 218
Registriert: Di 14. Dez 2010, 23:27

Reihenfolge der Zusammenstellung/Auswertung der Parameter beim Prozeduraufruf willkürlich?!

Beitrag von alfware17 »

Ich habe einen merkwürdigen Fehler in einem Programm, betroffen sind im Wesentlichen diese Teile:

Code: Alles auswählen

FUNCTION Str2Int(S: STRING):INTEGER;
VAR w: WORD; Zahl: INTEGER;
BEGIN
   Val(S, Zahl, w);
   IF w = 0 THEN Str2Int:=Zahl ELSE Str2Int:=-1;
END;

FUNCTION Strip(VAR Zeile: STRING): STRING;
VAR k: INTEGER;
BEGIN
   k := Pos(';', Zeile);
   IF k = 0 THEN k := LENGTH(Zeile) + 1;
   Strip := Copy(Zeile, 1, k - 1);
   Zeile := Copy(Zeile, k + 1, 255);
END;

PROCEDURE LoadCSV(CONST FileName: STRING; VAR Daten: TDaten);
VAR
   CSVFile: TEXT;
   Zeile: STRING;
   Satz: TSatz;
BEGIN
   Daten.Init;
   Assign(CSVFile, FileName); Reset(CSVFile);
   ReadLn(CSVFile, Zeile);
   WHILE NOT EOF(CSVFile) DO BEGIN
      ReadLn(CSVFile, Zeile);
      Writeln('Zeile=', Zeile);
      Satz.Fuellen(Str2Int(Strip(Zeile)), Str2Int(Strip(Zeile)), Str2Int(Strip(Zeile)),
                Strip(Zeile), Strip(Zeile), Strip(Zeile),
                Str2Int(Strip(Zeile)), Str2Int(Strip(Zeile)), Str2Int(Strip(Zeile)));
      Writeln('Satz=');
      Satz.Zeigen;
      Daten.Hinzufuegen(Satz);
   END;
   Close(CSVFile);
END;                                                                           
Da sind noch Testausgaben drin, die mir im Prinzip klar gemacht haben, daß bei Satz.Fuellen die Teile der Zeile (CSV) leider nicht in der angegebenen Reihenfolge kommen, sondern bunt durcheinandergewürfelt. Eigentlich schneidet die Strip der Reihe nach ab und gibt den Rest zurück, wenn Strip 9x aufgerufen wurde ist die Zeile leer. Soweit so gut in Turbo-Pascal. Aber nicht in Lazarus. Was wird hier optimiert? Und wie kann/muß ich es abstellen.

Klar, ich könnte 9 Variablen einführen und 9x nacheinander Strip aufrufen, aber das hatte ich gerade ausgebaut. Warum werden die 9 Aufrufe, so wie sie da stehen, nicht der Reihe nach ausgewertet? Und ja, ich weiß, Seiteneffekt bezüglich der Zeile VAR aber ich fand es so elegant. Ich verstehe nicht, was Lazarus anders/besser/schlechter macht als Turbo Pascal, nur ist eben das Ergebnis in Lazarus unbefriedigend


alfware17
Beiträge: 218
Registriert: Di 14. Dez 2010, 23:27

Re: Reihenfolge der Zusammenstellung/Auswertung der Parameter beim Prozeduraufruf willkürlich?!

Beitrag von alfware17 »

Okay, danke für die schnelle Antwort und die Einsicht: Optimieren ist nicht immer gut für mich.

Habe das inzwischen schon wieder auf 9 Zwischenvariablen umgestellt. Schade. Mal sehen vielleicht nutze ich dann wenigstens den Record statt 9 Einzelwerten, wie das aussieht.

Benutzeravatar
Zvoni
Beiträge: 416
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz 2.2.2 FPC 3.2.2)
CPU-Target: 32Bit
Wohnort: BW

Re: Reihenfolge der Zusammenstellung/Auswertung der Parameter beim Prozeduraufruf willkürlich?!

Beitrag von Zvoni »

Doofe Frage: Wieso nutzt du nicht einfach SplitString? https://www.freepascal.org/docs-html/rt ... tring.html
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

alfware17
Beiträge: 218
Registriert: Di 14. Dez 2010, 23:27

Re: Reihenfolge der Zusammenstellung/Auswertung der Parameter beim Prozeduraufruf willkürlich?!

Beitrag von alfware17 »

Zvoni hat geschrieben: Di 22. Okt 2024, 15:19 Doofe Frage: Wieso nutzt du nicht einfach SplitString? https://www.freepascal.org/docs-html/rt ... tring.html
Es gibt keine doofen Fragen - aber wie immer steht da so ein bißchen versteckt im Text, das Programm soll auch mal im Turo-Pascal laufen, ich kann also keine FreePascal oder Lazarus Bibliotheken benutzen. Und selbst wenn, ein neues Array wollte ich nicht, dafür habe ich ja eigentlich mein Objekt...

alfware17
Beiträge: 218
Registriert: Di 14. Dez 2010, 23:27

Re: Reihenfolge der Zusammenstellung/Auswertung der Parameter beim Prozeduraufruf willkürlich?!

Beitrag von alfware17 »

Was mich aber zu einem neuerlichen Dilemma bringt:

Code: Alles auswählen

TYPE
   PSatz = ^TSatz;
   TSatz = OBJECT
      M1, M2, M3, N1, N2, L1: INTEGER;
      PROG, BEZEICHNER, CODE: STRING[50];
      Folge: PSatz;

      PROCEDURE Init;
      PROCEDURE Fuellen(M1_, M2_, M3_ : INTEGER; PROG_, BEZEICHNER_, CODE_: STRING; N1_, N2_, L1_: INTEGER);
      PROCEDURE Zeigen;
   END;

   TDaten = OBJECT
      Kopf, Fuss: PSatz;
      Anzahl: INTEGER;

      PROCEDURE Init;
      PROCEDURE Freigeben;
      PROCEDURE Hinzufuegen(VAR Satz: TSatz);
      PROCEDURE Zeigen;
      FUNCTION  LesenSatzbyM(M1_, M2_, M3_: INTEGER; VAR Satz: TSatz): BOOLEAN;
      FUNCTION  LesenDatenbyM(M1_, M2_: Integer; VAR Bereich: TDaten): BOOLEAN;
   END;

PROCEDURE TSatz.Fuellen(M1_, M2_, M3_ : INTEGER; PROG_, BEZEICHNER_, CODE_: STRING; N1_, N2_, L1_: INTEGER);
BEGIN
   M1 := M1_; M2 := M2_; M3 := M3_; N1 := N1_; N2 := N2_; L1 := L1_;
   PROG := PROG_; BEZEICHNER := BEZEICHNER_; CODE := CODE_;
   Folge := NIL;
END;

...

PROCEDURE LoadCSV(CONST FileName: STRING; VAR Daten: TDaten);
VAR
   CSVFile: TEXT;
   M1, M2, M3, N1, N2, L1: INTEGER;
   Zeile, PROG, BEZEICHNER, CODE: STRING;
   Satz: TSatz;

   FUNCTION Strip: STRING;
   VAR k: INTEGER;
   BEGIN
      k := Pos(';', Zeile);
      IF k = 0 THEN k := LENGTH(Zeile) + 1;
      Strip := Copy(Zeile, 1, k - 1);
      Zeile := Copy(Zeile, k + 1, 255);
   END;

BEGIN

      ...

      (* Variante 1, Aufrufreihenfolge *)
      Satz.Fuellen(Str2Int(Strip(Zeile)), Str2Int(Strip(Zeile)), Str2Int(Strip(Zeile)),
                   Strip(Zeile), Strip(Zeile), Strip(Zeile),
                   Str2Int(Strip(Zeile)), Str2Int(Strip(Zeile)), Str2Int(Strip(Zeile)));

      Satz.Fuellen(M1, M2, M3, PROG, BEZEICHNER, CODE, N1, N2, L1);
      Satz.Zeigen;
      Daten.Hinzufuegen(Satz);


      (* Variante 2, Zwischenvariablen *)
      M1:=Str2Int(Strip); M2:=Str2Int1(Strip); M3:=Str2Int(Strip);
      PROG:=Strip; BEZEICHNER:=Strip; CODE:=Strip;
      N1:=Str2Int(Strip); N2:=Str2Int(Strip); L1:=Str2Int(Strip);

      Satz.Fuellen(M1, M2, M3, PROG, BEZEICHNER, CODE, N1, N2, L1);
      Satz.Zeigen;
      Daten.Hinzufuegen(Satz);

      (* Variante 3, direkter Zugriff ohne Fuellen *)
      Satz.M1:=Str2Int(Strip); Satz.M2:=Str2Int1(Strip); Satz.M3:=Str2Int(Strip);
      Satz.PROG:=Strip; Satz.BEZEICHNER:=Strip; Satz.CODE:=Strip;
      Satz.N1:=Str2Int(Strip); Satz.N2:=Str2Int(Strip); Satz.L1:=Str2Int(Strip);

      Satz.Zeigen;
      Daten.Hinzufuegen(Satz);

END                                                                                                                                                                                                                                        
Variante 1 geht nun mal nicht mehr. Aber was ist nun günstiger, Variante 2 oder 3. Ich bin ja noch ein Anfänger was OO betrifft, glaube mich aber zu erinnern, daß der direkte Zugriff auf die Attribute zwar möglich solange public aber auch irgendwie bäh ist. Daher hatte ich ja die Fuellen Methode vorgesehen. Wenn ich die nun aber gar nicht brauche?

Benutzeravatar
Jorg3000
Lazarusforum e. V.
Beiträge: 398
Registriert: So 10. Okt 2021, 10:24
OS, Lazarus, FPC: Win64
Wohnort: NRW

Re: Reihenfolge der Zusammenstellung/Auswertung der Parameter beim Prozeduraufruf willkürlich?!

Beitrag von Jorg3000 »

Hi!
Ich wäre für Variante 3, denn das ist einfach und macht keine Probleme.
Wenn du dafür gerne Objektorientierung möchtest, mach eine Methode, welcher der ganze String (ganze Zeile) übergeben wird.
Grüße, Jörg
Zuletzt geändert von Jorg3000 am Di 22. Okt 2024, 15:42, insgesamt 1-mal geändert.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6873
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Reihenfolge der Zusammenstellung/Auswertung der Parameter beim Prozeduraufruf willkürlich?!

Beitrag von af0815 »

Warum zerlegst du nicht mit den Funktionen von der Stringlist ?
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
Zvoni
Beiträge: 416
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz 2.2.2 FPC 3.2.2)
CPU-Target: 32Bit
Wohnort: BW

Re: Reihenfolge der Zusammenstellung/Auswertung der Parameter beim Prozeduraufruf willkürlich?!

Beitrag von Zvoni »

Mal unabhängig: Schon mal überlegt, StrUtils zu verwenden?
Da gibts Copy2SymbDel --> https://www.freepascal.org/docs-html/rt ... mbdel.html

Das macht eigentlich das, was deine Strip-Funktion macht

Keine Ahnung ob das auch für TP funzt
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

alfware17
Beiträge: 218
Registriert: Di 14. Dez 2010, 23:27

Re: Reihenfolge der Zusammenstellung/Auswertung der Parameter beim Prozeduraufruf willkürlich?!

Beitrag von alfware17 »

Jorg3000 hat geschrieben: Di 22. Okt 2024, 15:40 Hi!
Ich wäre für Variante 3, denn das ist einfach und macht keine Probleme.
Wenn du dafür gerne Objektorientierung möchtest, mach eine Methode, welcher der ganze String (ganze Zeile) übergeben wird.
Grüße, Jörg
Das habe ich jetzt gemacht, vielen Dank. So sieht der Code jetzt aus:

Code: Alles auswählen

PROGRAM csvread_obj;

USES Stdio;

TYPE
   TEintrag = RECORD
      M1, M2, M3, N1, N2, L1: INTEGER;
      PROG, BEZEICHNER, CODE: STRING[50];
   END;

   PSatz = ^TSatz;
   TSatz = OBJECT
      Inhalt: TEintrag;
      Folge: PSatz;
      PROCEDURE Init;
      PROCEDURE Fuellen(VAR Eintrag: TEintrag; Ende: BOOLEAN);
      PROCEDURE Zeigen;
   END;

   PListe = ^TListe;
   TListe = OBJECT
      Kopf, Fuss: PSatz;
      Anzahl: INTEGER;
      PROCEDURE Init;
      PROCEDURE Freigeben;
      PROCEDURE Hinzufuegen(VAR Satz: TSatz);
      PROCEDURE Zeigen;
      FUNCTION  LesenSatzbyM(M1, M2, M3: INTEGER; VAR Ergebnis: TSatz): BOOLEAN;
      FUNCTION  LesenDatenbyM(M1, M2: INTEGER; VAR Ergebnis: TListe): BOOLEAN;
   END;

PROCEDURE TSatz.Fuellen(VAR Eintrag: TEintrag; Ende: BOOLEAN);
BEGIN
   Inhalt.M1 := Eintrag.M1; Inhalt.M2 := Eintrag.M2; Inhalt.M3 := Eintrag.M3;
   Inhalt.N1 := Eintrag.N1; Inhalt.N2 := Eintrag.N2; Inhalt.L1 := Eintrag.L1;
   Inhalt.PROG := Eintrag.PROG; Inhalt.BEZEICHNER := Eintrag.BEZEICHNER; Inhalt.CODE := Eintrag.CODE;
   IF Ende THEN Folge := NIL;
END;

PROCEDURE TSatz.Init;
VAR Neu: TEintrag;
BEGIN
   WITH Neu DO BEGIN
      M1:=-1; M2:=-1; M3:=-1; N1:=-1; N2:=-1; L1:=-1; PROG:=''; BEZEICHNER:=''; CODE:='';
   END;
   Fuellen(Neu, TRUE);
END;

PROCEDURE TSatz.Zeigen;
BEGIN
   WITH Inhalt DO
      WriteLn('M1=', M1, ', M2=', M2, ', M3=', M3, ', PROG=', PROG,
              ', BEZ=', BEZEICHNER, ', CODE=', CODE, ', N1=', N1, ', N2=', N2, ', L1=', L1);
END;

PROCEDURE TListe.Init;
BEGIN
   Kopf := NIL; Fuss := NIL; Anzahl := 0;
END;

PROCEDURE TListe.Freigeben;
VAR Zeiger, Temp: PSatz;
BEGIN
   Zeiger := Kopf;
   WHILE Zeiger <> NIL DO BEGIN
      Temp := Zeiger^.Folge;
      Dispose(Zeiger);
      Zeiger := Temp;
   END;
   Init;
END;

PROCEDURE TListe.Hinzufuegen(VAR Satz: TSatz);
VAR Neu: PSatz;
BEGIN
   New(Neu);
   Neu^ := Satz;
   Neu^.Folge := NIL;
   IF Kopf = NIL THEN
      Kopf := Neu
   ELSE
      Fuss^.Folge := Neu;
   Fuss := Neu;
   INC(Anzahl);
END;

PROCEDURE TListe.Zeigen;
VAR Zeiger: PSatz;
BEGIN
   Zeiger := Kopf;
   WHILE Zeiger <> NIL DO BEGIN
      Zeiger^.Zeigen;
      Zeiger := Zeiger^.Folge;
   END;
END;

FUNCTION TListe.LesenSatzbyM(M1, M2, M3: INTEGER; VAR Ergebnis: TSatz): BOOLEAN;
VAR Zeiger: PSatz;
BEGIN
   Ergebnis.Init;
   LesenSatzbyM := False;
   Zeiger := Kopf;
   WHILE Zeiger <> NIL DO BEGIN
      IF (Zeiger^.Inhalt.M1 = M1) AND (Zeiger^.Inhalt.M2 = M2) AND (Zeiger^.Inhalt.M3 = M3) THEN BEGIN
         Ergebnis := Zeiger^;
         LesenSatzbyM := True;
         Exit;
      END;
      Zeiger := Zeiger^.Folge;
   END;
END;

FUNCTION TListe.LesenDatenbyM(M1, M2: INTEGER; VAR Ergebnis: TListe): BOOLEAN;
VAR Zeiger: PSatz;
BEGIN
   Ergebnis.Freigeben;
   LesenDatenbyM := False;
   Zeiger := Kopf;
   WHILE Zeiger <> NIL DO BEGIN
      IF (Zeiger^.Inhalt.M1 = M1) AND (Zeiger^.Inhalt.M2 = M2) THEN BEGIN
         Ergebnis.Hinzufuegen(Zeiger^);
         LesenDatenbyM := True;
      END;
      Zeiger := Zeiger^.Folge;
   END;
END;

PROCEDURE LoadCSV(CONST FileName: STRING; VAR Liste: TListe);
VAR
   CSVFile: TEXT;
   Neu: TSatz;
   Temp: TEintrag;
   Zeile: STRING;
   FUNCTION Strip: STRING;
   VAR k: INTEGER;
   BEGIN
      k := Pos(';', Zeile);
      IF k = 0 THEN k := LENGTH(Zeile) + 1;
      Strip := Copy(Zeile, 1, k - 1);
      Zeile := Copy(Zeile, k + 1, 255);
   END;
BEGIN
   Liste.Init;
   Assign(CSVFile, FileName); Reset(CSVFile);
   ReadLn(CSVFile, Zeile);
   WHILE NOT EOF(CSVFile) DO BEGIN
      ReadLn(CSVFile, Zeile);
      WITH Temp DO BEGIN
         M1 := Str2Int(Strip); M2 := Str2Int(Strip); M3 := Str2Int(Strip);
         PROG := Strip; BEZEICHNER := Strip; CODE := Strip;
         N1 := Str2Int(Strip); N2 := Str2Int(Strip); L1 := Str2Int(Strip);
      END;
      Neu.Fuellen(Temp, TRUE);
      Liste.Hinzufuegen(Neu);
   END;
   Close(CSVFile);
END;

VAR
   Gesamt, Auswahl: TListe;
   Satz: TSatz;

BEGIN
   Gesamt.Init; Satz.Init; Auswahl.Init;
   LoadCSV('daten.csv', Gesamt);
   Gesamt.Zeigen;
   IF Gesamt.LesenSatzbyM(0, 0, 9, Satz) THEN BEGIN
      WriteLn('Datensatz 0 0 9 : ');
      Satz.Zeigen;
   END ELSE
      WriteLn('Datensatz nicht gefunden.');
   IF Gesamt.LesenDatenbyM(0, 6, Auswahl) THEN BEGIN
      WriteLn('Gefundene Datensätze für M1=0, M2=6:');
      Auswahl.Zeigen;
   END ELSE
      WriteLn('Keine Datensätze für M1=0, M2=6 gefunden.');
   Gesamt.Freigeben; Auswahl.Freigeben;
   ReadLn;
END.
Wobei sich mir jetzt die Frage stellt (ich habe noch ein paar mehr Abfragemethoden zu bauen, die auch alle True/False ergeben sollen), ob als VAR-Parameter eventuell Poeinter auf die Records besser wären. Ich habe es probiert, kam aber ganz schnell mit dem ^ ins Strudeln und habe dann den unschönen Effekt daß die globalen Gesamt, Auswahl und Satz auch Pointer werden und das grausam wird und man außerdem aus den ganzen ^ nicht rauskommt. Das macht man doch auch nicht, oder? Eine VAR Übergabe des Records oder Objects ist erlaubt oder muß man sich mit so vielen Pointern herumärgern.

Und nochmals als Antwort, warum ich keine StringList, SysUtils usw verwende - eines der Zielsysteme ist 16bit mit Turbo Pascal und da habe ich die Bibliotheken nicht. Ich habe ein 30 Jahre altes Programm welches ursprünglich aus einer dBase Portierung kam, neu portiert (erst in Python, Java steht noch aus und nun in Pascal) und dabei u.a. gelernt daß Turbo sogar schon Objekte kannte. Die kann ich also nehmen, die Bibliotheken leider nicht.

Sieben
Beiträge: 292
Registriert: Mo 24. Aug 2020, 14:16
OS, Lazarus, FPC: Ubuntu Xenial 32, Lazarus 2.2.0, FPC 3.2.2
CPU-Target: i386

Re: Reihenfolge der Zusammenstellung/Auswertung der Parameter beim Prozeduraufruf willkürlich?!

Beitrag von Sieben »

Eine VAR Übergabe des Records oder Objects ist erlaubt oder muß man sich mit so vielen Pointern herumärgern.
Eine var-Übergabe ist nicht nur nicht nötig, um Felder eines Records oder einer Klasse zu ändern, sie ist sogar kontraproduktiv, da so das ganze Objekt durch ein anderes ersetzt werden kann, was normalerweise nicht im Sinne des Erfinders ist. Vergiß den ganzen Pointer-Kram, er findet bei Pascal i.a. hinter den Kulissen statt - wenn du einen Record oder eine Klasse weitergibst ist es eben eigentlich nur seine Adresse, die übergeben wird - und die willst du wie gesagt ja gar nicht verändert haben.

alfware17
Beiträge: 218
Registriert: Di 14. Dez 2010, 23:27

Re: Reihenfolge der Zusammenstellung/Auswertung der Parameter beim Prozeduraufruf willkürlich?!

Beitrag von alfware17 »

Sieben hat geschrieben: Mi 23. Okt 2024, 13:20
Eine VAR Übergabe des Records oder Objects ist erlaubt oder muß man sich mit so vielen Pointern herumärgern.
Eine var-Übergabe ist nicht nur nicht nötig, um Felder eines Records oder einer Klasse zu ändern, sie ist sogar kontraproduktiv, da so das ganze Objekt durch ein anderes ersetzt werden kann, was normalerweise nicht im Sinne des Erfinders ist. Vergiß den ganzen Pointer-Kram, er findet bei Pascal i.a. hinter den Kulissen statt - wenn du einen Record oder eine Klasse weitergibst ist es eben eigentlich nur seine Adresse, die übergeben wird - und die willst du wie gesagt ja gar nicht verändert haben.
Vielleicht verstehe ich dich nicht richtig. Lasse ich in meinen Methodenköpfen das VAR weg, jedenfalls da wo ich Objekte oder Records übergebe, wird das Ergebnis falsch. Und nein, ich übergebe keine Pointer weil ich die nicht mag sobald es über simple Listen hinausgeht - es ging mir nur generell darum ob sowas üblich wäre (die Pointer anstelle der Objekte/Records) in der OO-Welt, die ich hier erstmal nur wieder ausprobieren will. Mein Beispielprogramm ist auch noch nicht fertig, wenn ich nach der Python Vorgabe gehe, die ich gemacht habe und die mir durch Kompaktheit viel besser gefällt, dann wandern die meisten Methoden der TListe eh noch in den TMenueManager...

Sieben
Beiträge: 292
Registriert: Mo 24. Aug 2020, 14:16
OS, Lazarus, FPC: Ubuntu Xenial 32, Lazarus 2.2.0, FPC 3.2.2
CPU-Target: i386

Re: Reihenfolge der Zusammenstellung/Auswertung der Parameter beim Prozeduraufruf willkürlich?!

Beitrag von Sieben »

Was habe ich denn da für einen Blödsinn verzapft, und warum lässt man mir das durchgehen? Jedenfalls was Records angeht, die sind ja nichts anderes als strukturierte Variablen, und da braucht man natürlich einen var-Parameter. Was Objekte - jedenfalls im Sinne von Klassen - angeht, ist es aber tatsächlich anders und so wie ich geschrieben habe. Da wird tatsächlich nur die Adresse der Instanz weitergegeben, und die will man iA ja gerade nicht verändert haben.

Code: Alles auswählen

type
  TRTest = record
    Feld1: integer;
    Feld2: string;
  end;

  TOTest = class
    Feld1: integer;
    Feld2: string;
  end;

procedure ChangeObject(ATest: TOTest);
begin
  ATest.Feld2 := 'B';
end;

procedure ChangeRecord(ATest: TRTest);
begin
  ATest.Feld2 := 'B';
end;

procedure TfrmMain.Button2Click(Sender: TObject);
var RTest: TRTest;
    OTest: TOTest;
begin
  RTest.Feld2 := 'A';
  ChangeRecord(RTest);
  ShowMessage(RTest.Feld2);
  OTest := TOTest.Create;
  OTest.Feld2 := 'A';
  ChangeObject(OTest);
  ShowMessage(OTest.Feld2);
  OTest.Free;
end; 
Das wird zunächst einmal 'A' anzeigen, als zweites dann aber, wie geändert 'B'. Erst wenn bei ChangeRecord ein var einfügt, wird zweimal 'B' angezeigt.

Antworten