PRIVATE Variable: Unterschied zwischen den Versionen
Georg (Diskussion | Beiträge) Keine Bearbeitungszusammenfassung |
Georg (Diskussion | Beiträge) Keine Bearbeitungszusammenfassung |
||
Zeile 1: | Zeile 1: | ||
== Definition einer PRIVATE Variablen == | |||
PRIVATE Variablen werden dynamisch erzeugt und "entsorgt". | PRIVATE Variablen werden dynamisch erzeugt und "entsorgt". | ||
Zeile 13: | Zeile 16: | ||
PRIVATE dHeute | PRIVATE dHeute | ||
PARAMETER nEins, nZwei, lVier | PARAMETER nEins, nZwei, lVier | ||
cZeit := Time() | |||
Innerhalb dieser Funktion sind damit fünf PRIVATE Variable definiert: | |||
- dHeute | |||
- nEins | |||
- nZwei | |||
- lVier | |||
- cZeit (vorausgesetzt, es existiert keine PUBLIC oder STATIC Variable dieses Namens) | |||
== Unterschiede zu lexikalischen Variablen == | |||
Eine PRIVATE Variable ist an ihre Position im Call-Stack gebunden. | PRIVATE Variablen können "on the fly" definiert und zerstört werden. Es muss keine Deklaration wie in anderen Sprachen durchgeführt werden. Dies ist sehr bequem und bringt die Gefahr mit sich, dass PRIVATE Variablen sich "überlagern" und damit ungewünschte Effekte erzeugen. | ||
FUNCTION Main | |||
PRIVATE nIndex | |||
FOR nIndex := 1 TO 3 | |||
? ProcName() + " " + Str(nIndex, 2) | |||
TueWas(nIndex) | |||
NEXT | |||
WAIT | |||
RETURN(.T.) | |||
FUNCTION TueWas(nWert) | |||
FOR nIndex := 1 TO 5 | |||
? ProcName() + " " + Str(nWert * nIndex, 3) | |||
NEXT | |||
RETURN(.T.) | |||
Bei Aufruf dieses Programms wird folgendes am Bildschirm ausgegeben: | |||
MAIN 1 | |||
TUEWAS 1 | |||
TUEWAS 2 | |||
TUEWAS 3 | |||
TUEWAS 4 | |||
TUEWAS 5 | |||
In TueWas() wird nIndex angesprochen. Gäbe es diese Variable nicht (in unserem Beispiel wurde sie in Main() erzeugt), würde sie durch die Zuweisung in der FOR-Anweisung erzeugt. Da sie aber existiert, wird die existierende Variable verwendet. Nach dem Durchlauf der Schleife in TueWas() hat die Variable nIndex den Wert 6 und daher wird die Schleife in Main() beendet. | |||
Um diesen Effekt zu vermeiden, muss die Funktion TueWas() leicht erweitert werden: | |||
FUNCTION TueWas(nWert) | |||
PRIVATE nIndex | |||
FOR nIndex := 1 TO 5 | |||
? ProcName() + " " + Str(nWert * nIndex, 3) | |||
NEXT | |||
RETURN(.T.) | |||
Dadurch, dass eine explizite Deklaration aufgenommen wurde, wird in TueWas() eine separate PRIVATE Variable nIndex erzeugt, die nicht mehr mit der in Main() definierten identisch ist. | |||
Dieses Beispiel zeigt, dass die bequeme Anlage von PRIVATE Variablen durch Wertzuweisung auch ihre Schattenseiten hat, wenn es bereits eine PRIVATE Variable dieses Namens gibt. | |||
== Besonderheiten == | |||
Eine PRIVATE Variable ist an ihre Position im Call-Stack gebunden. (Sichtbar ist sie, wie das vorige Beispiel zeigt in der Funktion, in der sie deklariert wird, sowie in allen daraus aufgerufenen Funktionen bis zu dem Zeitpunkt, da die Funktion, in der sie deklariert wurde, endet.) | |||
FUNCTION Main() | FUNCTION Main() | ||
Zeile 41: | Zeile 91: | ||
cVar wird das erste Mal in folgender Aufruf-Konstellation (= Call-Stack) angesprochen: | cVar wird das erste Mal in folgender Aufruf-Konstellation (= Call-Stack) angesprochen: | ||
Main | Main() | ||
+---> ProcA | +---> ProcA() | ||
+---> ProcC() | |||
cVar wird in ProcC erzeugt und ist in dem Moment, in dem ProcC durch die RETURN-Anweisung verlassen wird, nicht mehr "adressierbar". | cVar wird in ProcC() erzeugt und ist in dem Moment, in dem ProcC durch die RETURN-Anweisung verlassen wird, nicht mehr "adressierbar". | ||
Wenn später über ProcB ein weiterer Aufruf von ProcC erfolgt, wird eine neue (!) PRIVATE Variable erzeugt: | Wenn später über ProcB() ein weiterer Aufruf von ProcC() erfolgt, wird eine neue (!) PRIVATE Variable erzeugt: | ||
Main | Main | ||
+---> ProcB | +---> ProcB() | ||
+---> ProcC() | |||
Auch für diese Variable endet ihre Lebenszeit, wenn ProcC mit RETURN verlassen wird. | Auch für diese Variable endet ihre Lebenszeit, wenn ProcC mit RETURN verlassen wird. | ||
== Sichtbarkeit von LOCAL Variablen == | |||
Genaueres findet sich hier: [[Lebenszeit und Sichtbarkeit der Variablen-Klassen]] |
Version vom 27. Mai 2013, 09:49 Uhr
Definition einer PRIVATE Variablen
PRIVATE Variablen werden dynamisch erzeugt und "entsorgt".
Eine PRIVATE Variable kann auf drei verschiedenen Wegen erzeugt werden:
- durch die (ausführbare!) Anweisung "PRIVATE cVar" - durch eine Wertzuweisung "cVar := 'Heute'" - durch die Anweisung PARAMETER in einer Funktion (die übergebenen Werte werden in die vorgegebenen Variablen übernommen)
In den beiden ersten Fällen wird eine Variable mit dem Namen cVar erzeugt.
FUNCTION TueIrgendEtwas LOCAL nI PRIVATE dHeute PARAMETER nEins, nZwei, lVier cZeit := Time()
Innerhalb dieser Funktion sind damit fünf PRIVATE Variable definiert: - dHeute - nEins - nZwei - lVier - cZeit (vorausgesetzt, es existiert keine PUBLIC oder STATIC Variable dieses Namens)
Unterschiede zu lexikalischen Variablen
PRIVATE Variablen können "on the fly" definiert und zerstört werden. Es muss keine Deklaration wie in anderen Sprachen durchgeführt werden. Dies ist sehr bequem und bringt die Gefahr mit sich, dass PRIVATE Variablen sich "überlagern" und damit ungewünschte Effekte erzeugen.
FUNCTION Main PRIVATE nIndex FOR nIndex := 1 TO 3 ? ProcName() + " " + Str(nIndex, 2) TueWas(nIndex) NEXT WAIT RETURN(.T.) FUNCTION TueWas(nWert) FOR nIndex := 1 TO 5 ? ProcName() + " " + Str(nWert * nIndex, 3) NEXT RETURN(.T.)
Bei Aufruf dieses Programms wird folgendes am Bildschirm ausgegeben:
MAIN 1 TUEWAS 1 TUEWAS 2 TUEWAS 3 TUEWAS 4 TUEWAS 5
In TueWas() wird nIndex angesprochen. Gäbe es diese Variable nicht (in unserem Beispiel wurde sie in Main() erzeugt), würde sie durch die Zuweisung in der FOR-Anweisung erzeugt. Da sie aber existiert, wird die existierende Variable verwendet. Nach dem Durchlauf der Schleife in TueWas() hat die Variable nIndex den Wert 6 und daher wird die Schleife in Main() beendet.
Um diesen Effekt zu vermeiden, muss die Funktion TueWas() leicht erweitert werden:
FUNCTION TueWas(nWert) PRIVATE nIndex FOR nIndex := 1 TO 5 ? ProcName() + " " + Str(nWert * nIndex, 3) NEXT RETURN(.T.)
Dadurch, dass eine explizite Deklaration aufgenommen wurde, wird in TueWas() eine separate PRIVATE Variable nIndex erzeugt, die nicht mehr mit der in Main() definierten identisch ist.
Dieses Beispiel zeigt, dass die bequeme Anlage von PRIVATE Variablen durch Wertzuweisung auch ihre Schattenseiten hat, wenn es bereits eine PRIVATE Variable dieses Namens gibt.
Besonderheiten
Eine PRIVATE Variable ist an ihre Position im Call-Stack gebunden. (Sichtbar ist sie, wie das vorige Beispiel zeigt in der Funktion, in der sie deklariert wird, sowie in allen daraus aufgerufenen Funktionen bis zu dem Zeitpunkt, da die Funktion, in der sie deklariert wurde, endet.)
FUNCTION Main() ProcA() ProcB() RETURN(.T.) FUNCTION ProcA() ProcC() ... RETURN(.T.) FUNCTION ProcB() ProcC() ... RETURN(.T.) FUNCTION ProcC() cVar := "Hugo" RETURN(.T.)
cVar wird das erste Mal in folgender Aufruf-Konstellation (= Call-Stack) angesprochen:
Main() +---> ProcA() +---> ProcC()
cVar wird in ProcC() erzeugt und ist in dem Moment, in dem ProcC durch die RETURN-Anweisung verlassen wird, nicht mehr "adressierbar".
Wenn später über ProcB() ein weiterer Aufruf von ProcC() erfolgt, wird eine neue (!) PRIVATE Variable erzeugt:
Main +---> ProcB() +---> ProcC()
Auch für diese Variable endet ihre Lebenszeit, wenn ProcC mit RETURN verlassen wird.
Sichtbarkeit von LOCAL Variablen
Genaueres findet sich hier: Lebenszeit und Sichtbarkeit der Variablen-Klassen