static keyword
-
Hallo,
ich habe eine Funktion, die static verwendet und etwas anders abläuft, als ich das erwartet habe.
void func() { while(...) { do { i = read(ifstream); while(8x); } unsigned char read(std::ifstream& in) { static unsigned char c = in.get(); }Die Variable c wird nur alle 8 Male quasi initialisiert, dh. nur alle 8 mal wird ein Zeichen aus der Datei gelesen. Sonst bleibt es bei jedem Funktionsaufruf gleich.
Erst nachdem die while-schleife die nächste Runde startet, bekommt auch c einen neuen Wert.
Hat static einen Scope innerhalb der while Schleife oder wie?

Ich dachte eine static Variable bleibt während des kompletten Programmablaufs statisch?
-
Poste mal kompilierenden Code.
-
Wenn du dich über das merkwürdige Verhalten eines Programms wunderst, wie wäre es damit, das Programm zu zeigen?
Guckst du hier, was passiert, wenn man deinen Code zu etwas ausführbarem ergänzt:
http://ideone.com/W7hFX
Es verhält sich also, wie du es erwartest und wie es auch richtig ist, aber nicht so, wie du beschreibst, was du beobachtest. Folglich ist das Programm, welches du benutzt falsch.
-
JojoPo schrieb:
Die Variable c wird nur alle 8 Male quasi initialisiert
Die Variable
cwird 1x initialisiert, und zwar beim ersten Aufruf der Funktion.JojoPo schrieb:
dh. nur alle 8 mal wird ein Zeichen aus der Datei gelesen. Sonst bleibt es bei jedem Funktionsaufruf gleich.
Nein, es wird genau 1x etwas aus der Datei gelesen.
JojoPo schrieb:
Hat static einen Scope innerhalb der while Schleife oder wie?
Eine static-Variable verliert beim Verlassen des Scopes ihre Gültigkeit. Allerdings wird der für die Variable reservierte Speicherbereich nicht freigegeben, sondern bleibt geschützt.
-
SeppJ schrieb:
Wenn du dich über das merkwürdige Verhalten eines Programms wunderst, wie wäre es damit, das Programm zu zeigen?
Das ganze Probgramm zu zeigen, dürfte etwas schwer werden, weil das nicht 10 Zeilen sind, sondern mehrere Dateien, die miteinander in Beziehung stehen.
Hier der komplett ausführbare code.
#include <iostream> char read(std::istream& in) { static int pos = 0; static char c = in.get(); ++pos; pos %= 8; if(pos == 0) { if( !in.eof()) { c = in.get(); } } return c; } void func() { for(int i = 0; i < 5; ++i) { for (int j = 0; j < 8; ++j) { char c = read(std::cin); std::cout << c; } } } int main() { func(); return 0; }Und das Resultat:
abcdefghijklmnopqrstuvwxyz
aaaaaaabbbbbbbbccccccccddddddddeeeeeeeef
-
Ja wie, jetzt sag bloß da erwartest du jetzt, dass c nicht geändert wird? Nur weil c nur ein mal initialisiert wird, heißt das nicht dass die Funktion auch nur ein mal ausgeführt wird..
-
Gugelmoser schrieb:
Eine static-Variable verliert beim Verlassen des Scopes ihre Gültigkeit.
Ich bin mir nicht sicher, ob du das richtig meinst. Der Name ist nach Verlassen des Scopes kein gültiger Bezeichner mehr, das ist richtig. Aber Zeiger und Referenzen auf die Variable bleiben gültig.
-
cooky451 schrieb:
Ja wie, jetzt sag bloß da erwartest du jetzt, dass c nicht geändert wird?
Das erwarte ich natürlich nicht. ich hatte wegen einer variable einen denkfehler, weil ich darauf fixiert war das eine static var zwar ihren wert beibehält, aber eben nur einmal durch in.get() initialisiert wird. Thema hat sich erledigt.
-
SeppJ schrieb:
Gugelmoser schrieb:
Eine static-Variable verliert beim Verlassen des Scopes ihre Gültigkeit.
Ich bin mir nicht sicher, ob du das richtig meinst. Der Name ist nach Verlassen des Scopes kein gültiger Bezeichner mehr, das ist richtig. Aber Zeiger und Referenzen auf die Variable bleiben gültig.
Hmm ja, schlecht formuliert. Ich meinte, der Bezeichner für die Variable verliert beim Verlassen des Scopes seine Gültigkeit, die Variable aber wird nicht zerstört.
-
Ich kann aus eigener Erfahrung nur sagen, statische Variablen können sehr heimtückisch sein. Ich habe einmal stundenlang ein großes Programm auf einen vermeintlichen Fehler abgesucht, weil eine Klasse eine Funktion aus einer anderen Klasse nutzte, die eine statische Variable hatte. Da eine statische Variable unabhängig von einer konkreten Instanz existiert, also zur Klasse gehört und nicht zum Objekt, können sich mitunter eigenartige Szenarien ergeben.
Das Programm lief fehlerfrei. Erst als man eine API-Funktion mehrmals nutzte ergaben sich merkwürdige Fehler in den geschriebenen Dateien.
Nach meiner Debugsuche fand ich endlich die Klasse mit der Funktion, die die statische Variable nutzte und korrigierte ihr Verhalten. Das hat mich damals ziemliche Nerven gekostet.
Mit statischen Variablen sollte man also sorgsam umgehen.
