statische Variable

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
haderlump
Beiträge: 185
Registriert: Fr 18. Jan 2013, 09:29
OS, Lazarus, FPC: Windows 10, Windows XP, Lazarus 1.6
CPU-Target: Celeron

statische Variable

Beitrag von haderlump »

Hallo zusammen
Gibt es die Möglichkeit innerhalb einer Procedure statische Variable zu definieren, die also ihren Wert nicht nach Procedureende verlieren, sondern beim nächsten Aufruf wieder zur Verfügung stehen.
Oder geht das nur über gloale Variable?

Gruß Fritz

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: statische Variable

Beitrag von siro »

Das sollte gehen:
So habe ich es zumindest schon ausprobiert und das scheint sich exakt wie "static" in "C" zu verhalten.

Code: Alles auswählen

const MeineVar : Integer = 1234;


Also vorn als "const" definieren,
dann einen beliebigen Init-Wert angeben,
der wird "automatisch" nur einmal beim Starten der Software gesetzt
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Benutzeravatar
Niesi
Lazarusforum e. V.
Beiträge: 331
Registriert: So 26. Jun 2016, 19:44
OS, Lazarus, FPC: Linux Mint Cinnamon (Windows wenn notwendig), Lazarus 3.0 FPC 3.3.1

Re: statische Variable

Beitrag von Niesi »

Es geht auch mit var:

procedure xyz;
var
i : integer = 0;
i1 : integer = 0;
i2 : integer = 0;

...

Ist eigentlich Initieren, sollte aber "reichen" ...
Wissen ist das einzige Gut, das sich vermehrt, wenn es geteilt wird ...

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: statische Variable

Beitrag von m.fuchs »

Das initiert aber den Wert bei jedem Aufruf die Variable wieder auf 0.
Der OP möchte aber den Wert vom Ende der Prozedur zum nächsten Aufruf mitnehmen.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: statische Variable

Beitrag von Warf »

Afaik gibt es das in Pascal nicht.
MMn. auch aus gutem grund. Dabei handelt es sich technisch ja nur um eine globale variable, welche nur im lokalen scope verfügbar ist. Das macht unter C Sinn und hätte im rein Prozedualen programmieren bestimmt auch eine Existenzberechtigung (auch wenn es mMn. kein schöner programmierstil ist, ich würde eher globale variablen mit nem namensprefix verwenden), aber seit OOP braucht man das gar nicht mehr, da all die informationen die über die Methodenlaufzeit hinweg gespeichert werden müssen als private Feld der Klasse angelegt werden können. Kombiniert mit dem Singelton Muster benötigt man in den meisten fällen keine globalen variablen mehr, und statische variablen sind ja nichts anderes.

Edit: grad mit const ausprobiert, scheint doch zu gehen, irgendwie komisch, hätte ein solches verhalten mit const nicht erwartet
Zuletzt geändert von Warf am Sa 2. Jun 2018, 14:12, insgesamt 1-mal geändert.

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: statische Variable

Beitrag von siro »

mit var geht das nicht,
aber mit const funktioniert es bei mir einwandfrei.

Code: Alles auswählen

 
procedure Test;
const x:integer = 0;    // var geht nicht !!!!!!!!!!
begin
  x:=x+1;
  form1.caption:=IntToStr(x);
end;
 
procedure TForm1.Button1Click(Sender: TObject);
begin
  Test;
end;         


benutzt man "var" wird bei jedem Wiedereintritt in die procedure Test der Wert x auf 0 gesetzt.
Bei const bleibt der Wert erhalten.
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: statische Variable

Beitrag von m.fuchs »

Warf hat geschrieben:Afaik gibt es das in Pascal nicht.

Wie kannst du denn sowas schreiben, wenn siro schon im zweiten Beitrag die Lösung geschrieben hat?

Warf hat geschrieben:auch wenn es mMn. kein schöner programmierstil ist

Definitiv ist das kein schöner Stil.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: statische Variable

Beitrag von Warf »

m.fuchs hat geschrieben:Wie kannst du denn sowas schreiben, wenn siro schon im zweiten Beitrag die Lösung geschrieben hat?


Hatte es mit const noch nicht ausprobiert gehabt, hab den post total überlesen, hatte auf die schnelle nur die "lösung" mit var gesehen, die nicht funktioniert. Ich dummerchen hatte bei const immer Konstanten im Kopf, hab an sowas nie gedacht

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: statische Variable

Beitrag von m.fuchs »

Warf hat geschrieben:Ich dummerchen hatte bei const immer Konstanten im Kopf, hab an sowas nie gedacht

Das ist eine furchtbare Altlast aus Turbo-Pascal-Zeiten. Wenn man einer Konstante einen Typ zuweist, dann ist sie nicht mehr konstant sondern eine statische Variable.

Mit der Compileroption

Code: Alles auswählen

{$J-}
kann man das deaktivieren. Dann verhalten sich auch typisierte Konstanten wirklich konstant.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: statische Variable

Beitrag von siro »

grad probiert, mit der Option {$J-} geht es wirklich nicht mehr. Da meckert der Compiler.

Auch wenn es nicht sonderlich schön aussieht, mag ich diese Möglichkeit, leider gibt es ja das Schlüsselwort static (meines Wissen nach) "noch" nicht in Pascal.
Es gibt aber auch zugegebenermaßen wenig sinnvolle Anwendungen dafür. Im Prinzip ist das ja, wie Warf schon schrieb, nur eine Globale Variable mit
geringer Sichtbarkeit (nur innerhalb der Procedure bzw. Funktion).
Fazit: Es geht, man muss es aber nicht unbedingt benutzen...
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: statische Variable

Beitrag von Warf »

m.fuchs hat geschrieben:Das ist eine furchtbare Altlast aus Turbo-Pascal-Zeiten. Wenn man einer Konstante einen Typ zuweist, dann ist sie nicht mehr konstant sondern eine statische Variable.

Mit der Compileroption

Code: Alles auswählen

{$J-}
kann man das deaktivieren. Dann verhalten sich auch typisierte Konstanten wirklich konstant.


Danke, das werd ich jetzt wohl öfter benutzen müssen. Ich bin immer davon ausgegangen das es richtige konstanten wären. Klar macht das bis auf ein paar kleinere Optimierungen nicht so viel aus, aber ich will wenn ich konstanten verwende sicher gehen das wenn ich Ausversehen eine Zuweisung o.ä. mache (z.B. als var parameter übergeben) der Compiler meckert.

siro hat geschrieben:Fazit: Es geht, man muss es aber nicht unbedingt benutzen...


Um noch eine Alternative zu zeigen mit einem Singelton objekt (wäre die alternative zu einer reinen funktion, nicht zu einer Methode, da solltest du einfach das zur klasse hinzufügen):

Code: Alles auswählen

unit XYUtils
{$Mode ObjFPC}{$H+}
type
  TXYUtilities = class
  private
    CurrentInt: Integer;
  public
    function GetNextInt: Integer;
end;
 
function XYUtilities: TXYUtilities;
implementation
var MyXYUtilities: TXYUtilities;
 
function XYUtilities: TXYUtilities;
begin
  if not Assigned(MyXYUtilities) then
    MyXYUtilities = TXYUtilities.Create;
  Result := MyXYUtilities;
end;
 
function TXYUtilities.GetNextInt: Integer;
begin
  Result := CurrentInt;
  Inc(CurrentInt);
end;

Benutzen dann

Code: Alles auswählen

uses ..., XYUtils;
...
  i := XYUtilities.GetNextInt;

Mathias
Beiträge: 6164
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: statische Variable

Beitrag von Mathias »

Auch wenn es nicht sonderlich schön aussieht, mag ich diese Möglichkeit, leider gibt es ja das Schlüsselwort static (meines Wissen nach) "noch" nicht in Pascal.

Dies stimmt nicht ganz, in Classen kann man static verwenden.:

Code: Alles auswählen

type
  Tclass = class
    i: integer; static;  // Dies geht
  end


Aber in einer normalen procdure hätte ich es auch lieber so:

Code: Alles auswählen

procedure Test;
var
  i: integer = 123; static;
begin
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: statische Variable

Beitrag von siro »

Guten Morgen zusammen:

Mathias hat geschrieben:Dies stimmt nicht ganz, in Classen kann man static verwenden.:

Code: Alles auswählen

type
  Tclass = class
    i: integer; static;  // Dies geht
  end



Da verstehe ich jetzt nicht.
Wenn ich eine Instanz einer Klasse anlege, dann sind die Eigenschaften doch IMMER static, (sie existieren solange bis ich die Instanz freigebe)
oder hab ich da jetzt einen Gedankenfehler,
was macht das static an dieser Stelle ?, wird hier lediglich eine Sichtbarkeit unterdrückt ?
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: statische Variable

Beitrag von mse »

siro hat geschrieben:was macht das static an dieser Stelle ?, wird hier lediglich eine Sichtbarkeit unterdrückt ?

Alle Instanzen der Klasse beziehen sich auf die gleiche globale Variable.

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: statische Variable

Beitrag von siro »

Ach echt :shock: das kannte ich noch garnicht.
Man lernt nie aus, Ich danke Dir mse.
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Antworten