static variablen
-
Dabei ist noch wichtig zu erwähnen, dass statische Variabeln im Gegensatz zu globalen Variabeln nur den Sichtbarkeitsbereich besitzen, in dem sie deklariert wurden.
int j = 3; void func1() { static int i = 0; cout << ++i << " "; } // hier endet der Sichtbarkeitsbereich int main() { cout << i << endl; // geht hier nicht, da der Sichtbarkeitsbereich von i verlassen wurde. cout << j << endl; // globale Variable, Sichtbarkeit noch vorhanden }Das heisst, i lebt erst weiter, wenn die Funktion func1 erneut aufgerufen wird (in deinem Beispiel wird es jedoch gerade wieder mit 0 überschrieben).
Folgender Kontext könnte ein Beispiel für eine static-Anwendung sein (ist zwar ein bisschen gekünstelt, soll aber nur das Prinzip aufzeigen)
void func1(bool blub) { static int i; if (blub) i = 0; cout << ++i << " "; } int main() { func1(true); for (short a = 0; a < 4; ++a) func1(false); func1(true); func1(false); }Bei blub == true würde die Variable i immer wieder auf 0 gesetzt, sonst wird sie weitergezählt. Das ergäbe folgende Ausgabe:
1
2
3
4
5
1
2Ausserdem kann das Schlüsselwort static bei Klassen vorkommen, wenn es möglich sein soll, dass auf eine Klassenvariable ohne Objekt zugegriffen wird (aber ich denke nicht, dass du dies gemeint hast - nur so nebenbei).
-
Nunja, in seinem Beispiel wird i nicht wirklich mit 0 überschrieben.
Zumindest bei mir wird von 1 bis 10 gezählt
Also, soweit ich weiß ist es ja so:
int main() { // Anweisungsblock int i = 5; // neuer Anweisungsblock { int i = 10; cout << i << endl; // i = 10 ABER! die Variable i wird nur von // der anderen "überdeckt" } // hier stirb das "innere" i cout << i << endl; // das "äußere" i lebt noch, i = 5 }Wie siehts bei static Variablen aus?
-
Statische Variablen werden nur einmal Initialisiert.
void func1() { static int i = 0; cout << ++i << " "; }Das
int i=0;wird beim zweiten Aufruf der Funktion übersprungen.
-
Stimmt natürlich, dass i nicht überschrieben wird (hab auch schon einige Zeit nicht mehr mit static gearbeitet - sorry für Fehlinformation), da wär auch mein kompliziertes Konstrukt nicht nötig ;).
Was deine Frage angeht: Ich hab deinen Code ausprobiert, die Ausgabe ist in allen 4 möglichen Fällen (innen static, aussen nicht; innen static, aussen auch; etc.)
10
5Die innere Deklaration (egal ob static oder nicht) hat innen immer Vorrang, genauso wie diese ausserhalb des Blockes nicht mehr sichtbar ist (deshalb ist die Ausgabe aussen immer 5). Das heisst, die beiden Variabeln arbeiten jeweils in ihrem Sichtbarkeitsbereich für sich, also unabhängig vom anderen i, halt wie bei normalen Variabeln. Eben mit dem Unterschied, dass static-Variabeln "weiterleben".
Edit2: Verdammt, immer zu spät, ausserdem viel zu viel Text, um wenig zu sagen

-
Meine Frage ist schon damit beantwortet das die
static Variable nicht überschrieben wird, danke
-
natürlich kommt 1-10 raus und nichts mit 5, war wohl etwas verwirrt.
was mich irritiert hat, war, dass jedesmal beim fkt aufruf static int I=0 gesetzt wurde. aber sow ie ich es jetzt verstanden habe, wird diese nur einmal initialisiert bei static und lebt dann weiter, wobei die definition bei jedem fkt aufruf übersprungen wird.
muss man erstmal wissen sowas.@nexus: auf was beziehst du dich mit den 4 varianten?
-
Hast du richtig verstanden

er bezieht sich auf meinen Code:
int main() { // Anweisungsblock int i = 5; // neuer Anweisungsblock { int i = 10; cout << i << endl; // i = 10 ABER! die Variable i wird nur von // der anderen "überdeckt" } // hier stirb das "innere" i cout << i << endl; // das "äußere" i lebt noch, i = 5 }und meint diese Varianten (gekürzt)
// außen static int main() { static int i = 5; { int i = 10; } } // beides static int main() { static int i = 5; { static int i = 10; } } // innen static int main() { int i = 5; { static int i = 10; } } // kein static int main() { int i = 5; { int i = 10; } }kommt immer aufs gleiche raus.
-
das static innerhalb der klammer ist nciht stärker als das ausserhalb?
mhh
mal ne andere frage wenns erlaubt ist:
while(i<5){ int *p=new int; p=&i; i++; cout << *p; }?
hier benutze ich jedesmal den zeiger p um auf dem heap neuen platz zu reservieren.
wieso klappt das nicht wenn ich es so schreibe?int main(){ int *p=new int(123); int *p=new int(321); return 0; }oben wird er doch auch mehrfach benutzt
-
Beim unteren Beispiel deklarierst du *p zweimal.
Machs doch so:int *p=new int(123); *p=321; std::cout<<*p<<std::endl;Ausgabe: 321
-
oben wird es doch auch jedesmal neu deklariert?
-
Nein, oben wird es nur neu definiert (zugewiesen). Bei folgendem Befehl ist p schon deklariert (als int*):
p=&i;Dies verhält sich wie normale, nicht dynamisch definierte Datentypen:
int i = 0; int i = 3;wird nicht funktionieren wegen doppelter Deklaration (Variable i besteht bereits).
int i = 0; i = 3;geht. Hier wird i nur ein Mal deklariert.
-
ja aber am anfang der while schleife wird es doch auch jedesmal deklariert:
ich habe den typ und den namen der variablen, sehe da keinen unterschied. das muss doch was mit der while schleife zu tun haben oder?
naja hab hier noch eine andere frage:
was bewirkt das const bei dem parameter:
Ratio& Ratio::plusGleich(const Ratio &x)[cpp]
-
Der Unterschied ist, dass die While-Schleife einen Block impliziert - das ist alles innerhalb der Klammern {} - und der Sichtbarkeitsbereich am Ende des Blockes (d.h. mit der schliessenden Klammer }) verloren geht. Somit ist bei einem neuen Schleifendurchgang die Variable *p noch undeklariert, wodurch eine Deklaration erlaubt ist.
while(i<5) { // Block beginnt bei jedem Durchgang neu; *p noch undeklariert int *p=new int; // ab hier ist *p deklariert // ... } // Block ist hier beendet, Sichtbarkeit auf *p geht verloren.Das const bewirkt, dass der Parameter, der als Referenz übergeben wird (&x), konstant übergeben wird. Das bedeutet, er kann von der Funktion nicht verändert werden. Im Gegensatz zu einer Wertübergabe, bei der der Parameter auch nicht verändert werden kann, bringt eine Referenzübergabe oft Performancevorteile, da die Variable so nicht kopiert, sondern nur auf sie verwiesen wird.
Ich hoffe, ich habe mich einigermassen klar ausgedrückt, sonst einfach nachfragen

-
jup habe es verstanden, danke sehr.
wenn der wert eh nicht verändert werden kann, dann hätte ich doch direkt eine wertübergabe machen können und bräuchte keine referenz, wie du es sagst. da war mir gerade die logik nicht klar...
achja da fällt mir ein:
int const i=3; const int i=3;wo ist der unterschied wenn es einen gibt?
-
Soweit ich weiß keiner.
Übrigens, bin da jetzt auch nicht so der Profi
auf dem Zeigergebiet, aber sollte man nicht eigentlich
Speicher den man mit new angefordert hat auch wieder
mit free freigeben? Oder wird auch der Speicher wenn der
Zeiger stirbt wieder freigegeben?
Ich kenns nur von C
-
Genau, hab ich vergessen zu schreiben:
Den Speicher für Variabeln, die du dynamisch (das heisst mit new) deklarierst, solltest du wieder mit delete freigeben, da ansonsten der Speicherplatz nicht mehr genutzt werden kann, was bei Schleifen allmählich den Arbeitsspeicher füllt. Beim Beenden des Programms (v.a. nach längerer Laufzeit) ist der Computer dann langsamer.while(i<5) { int *p=new int; // ... delete p; }Wie blub² bereits sagte, ist const int i mit int const i identisch. const int i ist allerdings die gebräuchlichere Schreibweise.
-
Nexus schrieb:
Beim Beenden des Programms (v.a. nach längerer Laufzeit) ist der Computer dann langsamer.
Beim Beenden des Programms sind alle Memory Leaks hinfällig. Das Betrienssystem kratzt das nicht die Bohne. Übrigens, einen einzelnen "int" mit new anzulegen ist wohl arg übertrieben, aber sollte bestimmt nur ein Beispiel sein.
-
danke jungs,ihr habt mir sehr geholfen!!
gruß
-
funky cat schrieb:
Nexus schrieb:
Beim Beenden des Programms (v.a. nach längerer Laufzeit) ist der Computer dann langsamer.
Beim Beenden des Programms sind alle Memory Leaks hinfällig. Das Betrienssystem kratzt das nicht die Bohne. [...]
Da bin ich aber anderer Meinung, zumal der Arbeitspeicher auch Zeit braucht, bis er aufgeräumt ist. Ich hab mal ein kleines Spiel programmiert, da konnte man nach dem Beenden eine Minute lang warten, bis man den Computer wieder benutzen konnte. Nachdem ich überall delete und SDL_FreeSurface (eine Grafikfunktion, die einen Zeiger freigibt, also wie delete) hinzugefügt hatte, war das Problem beseitigt.
Wenn du es nicht glaubst, mach doch mal eine Schleife, die in jedem Durchgang Speicher alloziert und sehr viele Durchgänge hat (halt soviele bis es dein PC nicht mehr verkraftet :D).
-
Natürlich braucht es Zeit, aber der Effekt ist der Gleiche wenn du unheimlich viel Speicher allozierst und dann auf einen Schlag freigibst.