Moin, code: int zaehlen() { static int counter = 0; return ++counter; } int main() { printf("Zaehler: %d\n", zaehlen()); printf("Zaehler: %d\n", zaehlen()); printf("Zaehler: %d\n", zaehlen()); return 0; } die Ausgabe: Zaehler: 1 Zaehler: 2 Zaehler: 3 mir ist nicht ganz klar, warum die Ausgabe so aussieht wie sie aussieht.. Wird nicht jedesmal wenn die Funktion zaehlen aufgerufen wird die Variable counter neu mit 0 initialisiert? Demnach müsste die Ausgabe doch Zaehler: 1 Zaehler: 1 Zaehler: 1 ..sein, oder nicht? Kann mir das so frueh am Morgen schon jemand klar machen? :)
Eine Initialisierung ist keine Zuweisung. Der Inhalt wird am Anfang der Lebensdauer der Variablen initialisiert.
Les im Internet mal nach was eine static Variable macht... Danke das sollte reichen. Gruß Bean
Die Initialisierung geschieht bereits vor main im Startup-Code. Das "= 0" ist übrigens redundant, da Variablem im Static Storage, die keinen Initializer haben, immer mit 0 initialisiert werden — auch wenn sie lokal sind.
Johann L. schrieb: > Die Initialisierung geschieht bereits vor main im Startup-Code. aber nur bei C, bei C++ wird es später gemacht.
Also ich denke, wenn ich die Variable mit = 0 initialisiere, dann wird ihr der Wert 0 zugewiesen.. was auch definitiv so ist. hab das =0 mal weggelassen, dann stehen da irgendwelche Werte drin. Wenn ich die Variable nicht als static deklariere aber mit 0 initialisiere, dann ist die Ausgabe immer 1, wie ich das eben dachte. ...doch nicht... sorry. das =0 scheint tatsächlich redundant zu sein. Jetzt stört mich nur noch, dass einer nicht static Variablen die 0 immer wieder zugewiesen wird, bei der static allerdings nicht. Es scheint also so zu sein, dass static Variablen nur einmal Initialisiert werden können..
Tom L. schrieb: > Es scheint also so zu sein, dass static Variablen nur einmal > Initialisiert werden können.. Genau so ist es... was "stört" dich daran? Niemand zwingt dich sie "static" zu machen wenn dir das Verhalten nicht gefällt.
Vielleicht solltest du doch mal in den sauren Apfel beissen und ein C Buch besorgen, oder entsprechende Webseiten lesen.
A. K. schrieb: > Vielleicht solltest du doch mal in den sauren Apfel beissen und ein C > Buch besorgen, oder entsprechende Webseiten lesen. tu ich doch gerade :D in dem Tutorial wird nicht explizit auf meine Frage eingegangen.. und da ich weiß, dass hier ab und an mal jemand hilfsbereites am Start ist und es auch schneller geht hier eine Antwort zu bekommen als im WWW hab ich diesen Weg gewählt. Fertige Texte kann man nix fragen.. Und stören tut mich an dem Verhalten nix, wollte nur wissen warum sich sone static anders verhält als eine nicht static. Brauchen tu ich sie momentan gar nicht. Ich versuche gerade C zu lernen. ;)
Läubi .. schrieb: > Tom L. schrieb: >> Es scheint also so zu sein, dass static Variablen nur einmal >> Initialisiert werden können.. > > Genau so ist es... was "stört" dich daran? Niemand zwingt dich sie > "static" zu machen wenn dir das Verhalten nicht gefällt. Das Verhalten ist in dem code ja gerade genau so erwünscht.. wollte nur wissen wieso das so ist :). Aber ich kann erstmal damit leben, dass statics eben nur einmal initialisiert werden, im Gültigkeitsbereich
A. K. (prx) schrieb: > Vielleicht solltest du doch mal in den sauren Apfel beissen und ein C > Buch besorgen, oder entsprechende Webseiten lesen. Da isser nicht der einzige mit dieser Verhaltensweise. Andere fragen dem halben Forum Löcher in den Bauch, was sie denn jetzt für 'ne Programmiersprache lernen sollten, anstatt sich mal selber mit den elementarsten Eigenarten der einzelnen Richtungen zu beschäftigen. ;)
W7 schrieb: > A. K. (prx) schrieb: > >> Vielleicht solltest du doch mal in den sauren Apfel beissen und ein C >> Buch besorgen, oder entsprechende Webseiten lesen. > > Da isser nicht der einzige mit dieser Verhaltensweise. Andere fragen dem > halben Forum Löcher in den Bauch, was sie denn jetzt für 'ne > Programmiersprache lernen sollten, anstatt sich mal selber mit den > elementarsten Eigenarten der einzelnen Richtungen zu beschäftigen. > > ;) Wenn das wirklich falsch wäre, würde hier niemand irgendwas fragen dürfen. Ich denke schon, dass das Forum dafür nutzbar sein sollte. Aber darum geht es hier nicht.. Wen solche Fragen stören, der kann sie ja ignorieren. Oder ein Moderator gibt mir mal den hinweis, dass meine Frage zu "lowleveled" ist und ich mich bitte um anderweitige Lösung bemühen soll... ;) Danke
Tom L. (xedux) schrieb: > .. Oder ein Moderator gibt mir mal den hinweis, dass meine > Frage zu "lowleveled" ist und ich mich bitte um anderweitige Lösung > bemühen soll... ;) Das kann schneller passieren als man denkt. ;-) Beitrag "Re: Variable zu ASCII umwandeln in C"
Tom L. schrieb: > Das Verhalten ist in dem code ja gerade genau so erwünscht.. wollte nur > wissen wieso das so ist :) Ei weil die Funktion / Variable so ein "Gedächtnis" hat, was bei nicht-statischen Variablen eben nicht so ist. Das kann vor und Nachteile haben, und ja nach Anwendungsfall wird man Speicherklasse static oder auto wählen. static: Gedächtnis, die Funktion kann einen Status über mehrere Aufrufe behalten. auto: Die Funktion ist reentrand, der Platz wird nicht statisch belegt (was wieder Vor- und nachteile haben kann) malloc: Lebensdauer der Variablen ist unbekannt bzw. geht nicht einher mit einem C-Block / einer C-Funktion (dann ginge alloca oder lokale (statische) Variable), schlecht oder nicht statisch analysierbar
Die Lebensdauer einer Static-Variable reicht vom Programmbeginn bis zum Programmende. Sie wird also innerhalb eines Programmlaufs genau einmal angelegt und genau einmal wieder zerstört. Das Gleiche gilt auch für globale Variablen. Die Lebensdauer einer Auto-Variable (also einer die innerhalb eines Blocks, aber nicht als static definiert wird) reicht von ihrer Definition bis zum Blockende. Jeder Block kann aber innerhalb eines Programmlaufs mehrmals durchlaufen werden. Deswegen hat so eine Variable sozusagen mehrere Leben. Jetzt schau dir noch einmal die Aussage von A. K. an: A. K. schrieb: > Der Inhalt wird am Anfang der Lebensdauer der Variablen initialisiert. Ist's jetzt etwas klarer?
Tom L. schrieb: > Das Verhalten ist in dem code ja gerade genau so erwünscht.. wollte nur > wissen wieso das so ist :). Aber ich kann erstmal damit leben, dass > statics eben nur einmal initialisiert werden, im Gültigkeitsbereich Die "Erfinder von C" haben sich auch etwas dabei gedacht. Was bringt dir eine static-Variable, wenn sie bei jedem Funktionsaufruf wieder auf einen festen Wert gesetzt wird? Nichts.
mich hat ja nur verwirrt, warum der Befehl: static int counter = 0; die Variable counter nicht wieder auf 0 gesetzt hat, bei jedem Funktionsaufruf, da diese Zuweisung ja im Funktionsblock steht und somit bei jedem Durchlauf wieder neu auf 0 gesetzt werden müsste. Das ist aber nur bei "nicht static" Variablen so, wenn ich das gerade richtig verstanden hab, bzw. static Variablen lassen sich nur einmal initialisieren/zuweisen.
Tom L. schrieb: > mich hat ja nur verwirrt, warum der Befehl: static int counter = 0; > die Variable counter nicht wieder auf 0 gesetzt hat, bei jedem > Funktionsaufruf, da diese Zuweisung ja im Funktionsblock steht Nochmal. Das ist nämlich wichtig. DAS IST KEINE ZUWEISUNG! (Selbst wenn da ein = geschrieben steht) Das ist eine Initialisierung. Und initialisiert werden kann immer nur EINMAL! Egal welche Variable. Wenn sie überhaupt initialisiert wird (lokale nicht statische Variablen werden per Default nicht initialisiert) dann geschieht das ganz am Anfang ihrer Lebensdauer. Sozusagen wenn sie zur Welt kommt. Immer. Egal welche Variable. Diese Regelung ist für alle Variablen gleich. WEnn sie initialisiert wird, dann geschieht das ausschliesslich und nur an dem Zeitpunkt, an dem die Variable tatsächlich erzeugt wird. > verstanden hab, bzw. static Variablen lassen sich nur einmal > initialisieren/zuweisen. Alle Variablen werden nur EINMAL initialisiert (wenn überhaupt). Da liegt der springende Punkt. In C ist das noch nicht soooo wichtig. Aber in C++ ist die Unterscheidung zwischen Initialisierung und Zuweisung ein essentiell wichtiger Punkt, wenn auch die Regeln an dieser Stelle in diesem Hinblick absolut identisch sind! Aber in C++ hängt einfach nur noch mehr an dieser Unterscheidung in Form von Folgerungen drann. Das ist alles. Initialisiert wird eine Variable dann, wenn sie umgangssprachlich geboren wird. Alles danach kann dann nur noch eine Zuweisung sein. d.h. zwischen int j = 5; und int k; k = 5; gibt es einen essentiell wichtigen Unterschied! Das erste ist eine Initalisierung. Dies deshalb, weil die Angabe bei der Variablendefinition steht. Deshalb ist int j = 5; eine Initialisierung. Mittels int j .... wird eine neue Variable erzeugt (definiert). Und mittels ..... = 5 wird festgelegt, wie diese Variable im Zuge dieser Erzeugung zu initialisieren ist. Wohingegen im 2.tem Fall eine uninitialisierte Variable k erzeugt wird (die natürlich auch einen Wert hat, irgendeinen Wert haben Variablen immer, aber eben keinen definierten, da uninitialisiert), die dann im 2.ten Schritt mit einer Zuweisung auf den Wert 5 gesetzt wird. Hier ist also k = 5; tatsächlich eine Zuweisung. Und ja. So gesehen hat das = 2 Bedeutungen und ist nicht automatische immer eine Zuweisung.
wenn ich den code also so ausführe: int zaehlen() { static int counter = 0; return ++counter; } int main() { printf("Zaehler: %d\n", zaehlen()); printf("Zaehler: %d\n", zaehlen()); printf("Zaehler: %d\n", zaehlen()); return 0; } wird static int counter nur einmal initialisiert, weil das generell nur einmal geht (geboren werden). Sie erhält den Wert 0. Für den weiteren Ablauf des Programms hat die Zeile: static int counter = 0; also keine Bedeutung mehr? Wenn ich den code so ausführe: (also ohne static) int zaehlen() { int counter = 0; return ++counter; } int main() { printf("Zaehler: %d\n", zaehlen()); printf("Zaehler: %d\n", zaehlen()); printf("Zaehler: %d\n", zaehlen()); return 0; } ..hat die Zeile Bedeutung für den weiteren Ablauf.. counter wird bei jedem Durchlauf "auf 0 gesetzt". Würde also in deiner Denke bedeuten, dass sie einmal initialisiert wird mit 0 und danach, je nach dem wie oft die Schleife läuft, den Wert 0 zugewiesen bekommt? eine neue Initialisierung gibts ja nicht, sagst Du. Ist das so? Und wenn JEDE Variable nur EINMAL initialisiert werden kann, warum wird dann immernoch die int counter neu "zugewiesen" und die static int counter nicht? Warum ignoriert die static Variable die Zeile static int counter = 0; bei jedem weiteren SchjleifendurchlauF?
Tom L. schrieb: > Würde also in deiner Denke bedeuten, dass sie einmal initialisiert > wird mit 0 und danach, je nach dem wie oft die Schleife läuft, den > Wert 0 zugewiesen bekommt? Nein, die Variable wird jedesmal initialisiert, weil sie in jedem Aufruf von zaehlen() neu angelegt wird, denn beim Verlassen der Funktion verschwindet sie wieder. Wenn man's genauer betrachtet, ist counter also in jedem neuen Funktionsaufruf eine andere Variable, die lediglich den gleichen Namen hat wie die Variable aus dem vorangegangenen Aufruf. Die jeweils neu angelegte Variable kann am gleichen Speicherplatz liegen wie die alte, muss es aber nicht. Ist counter hingegen als static deklariert, bleibt die Variable bei jedem Aufruf dieselbe. Sie verschwindet auch nicht zwischen zwei Funktionsaufrufen, lediglich ihr Name "counter" existiert außerhalb der Funktion nicht.
Tom L. schrieb: > int zaehlen() { > static int counter = 0; > return ++counter; > } static Variablen werden genau 1 (ein) Mal zur Laufzeit des Programms angelegt. counter liegt nicht im Stack Frame der Funktion zaehlen, sondern der Speicherplatz wird (tadaa) statisch, fix reserviert. counter ist immer da, aber der Compiler erlaubt nur der Funktion zaehlen Zugriff darauf. Tom L. schrieb: > int zaehlen() { > int counter = 0; > return ++counter; > } counter wird bei jedem Einsprung in die Funktion zaehlen neu erzeugt (auf dem Stack) und bei Verlassen der Funktion wieder vernichtet.
das war das was ich nicht verstanden hab.. nun ist es einleuchtend. Danke! Das heißt dann also, es ist Unsinn dass "nonstatic" Variablen nur einmal initialisiert werden... wobei nee das is kein Unsinn. Initialisiert werden sie ja nur einmal.. dann halt immer ne neue counter Variable.. und deshalb wird sie auch immer neu mit 0 initialisiert, wohingegen die static Variable fest im Speicher liegt und nicht neu angelegt/initialisiert wird, weil sie als static markiert ist.?
Tom L. schrieb: > das war das was ich nicht verstanden hab.. nun ist es einleuchtend. > Danke! > Das heißt dann also, es ist Unsinn dass "nonstatic" Variablen nur einmal > initialisiert werden... wobei nee das is kein Unsinn. Initialisiert > werden sie ja nur einmal.. dann halt immer ne neue counter Variable.. > und deshalb wird sie auch immer neu mit 0 initialisiert, wohingegen die > static Variable fest im Speicher liegt und nicht neu > angelegt/initialisiert wird, weil sie als static markiert ist.? Genau. Und es ist deswegen kein (genereller) Unsinn, lokale Variablen zu initialisieren, denn wenn du sie nicht initialisierst, dann haben sie irgendeinen Wert. Erinnere dich daran: lokale, nicht statische Variablen werden per Default überhaupt nicht initialisiert. In
1 | void foo() |
2 | {
|
3 | int i; |
4 | |
5 | ...
|
6 | }
|
ist nicht klar, welchen Wert i nach seiner Geburt (nach Betreten der Funktion) hat. Das kann 0 sein, das kann aber auch jeder andere beliebige Wert sein. Was eben gerade zufällig die Bits im Speicher für einen Wert hatten. Mit einer Initialisierung hingegen
1 | void foo() |
2 | {
|
3 | int i = 0; |
4 | |
5 | ...
|
6 | }
|
kannst du dich darauf verlassen, dass i nach seiner Geburt garantiert den Wert 0 hat. Das mag für dich wichtig sein, wenn es das nicht ist, dann kann man die Inisitlisierung auch weglassen. hier zb
1 | void foo() |
2 | {
|
3 | int i; |
4 | |
5 | for( i = 0; i < 8; i++ ) |
6 | ...
|
7 | }
|
ist es nicht wichtig, dass i nach seiner Geburt einen definierten Wert hat, denn im Zuge des for bekommt es sowieso dann einen ersten definierten Wert zugewiesen. Hier ist eine Initialisierung von i daher nicht wichtig. Sie würde aber (ausser ein bischen zusätzlicher Programmlaufzeit) auch nicht schaden. Und wie schon gesagt: In dem Moment, in dem der Rücksprung aus der Funktion zum Aufrufer zurück erfolgt, werden alle lokalen, nicht statischen Variablen zerstört. So als ob sie nie existiert hätten. Bei static geht es also nicht im eigentlichen Sinn um Initialisierung oder nicht. Bei static bzw. nicht static geht es (an dieser Stelle, static hat auch noch eine 2.te Bedeutung) um die Lebensdauer von Variablen in Funktionen! Die Sache mit der Initialisierung ist nur eine logische Folgerung aus dieser Lebensdauer und dem Grundsatz "initialisiert wird nur einmal"
Karl Heinz Buchegger schrieb: > Und wie schon gesagt: > In dem Moment, in dem der Rücksprung aus der Funktion zum Aufrufer > zurück erfolgt, werden alle lokalen, nicht statischen Variablen > zerstört. So als ob sie nie existiert hätten. > > Bei static geht es also nicht im eigentlichen Sinn um Initialisierung > oder nicht. Bei static bzw. nicht static geht es (an dieser Stelle, > static hat auch noch eine 2.te Bedeutung) um die Lebensdauer von > Variablen in Funktionen! Die Sache mit der Initialisierung ist nur eine > logische Folgerung aus dieser Lebensdauer und dem Grundsatz > "initialisiert wird nur einmal" jo, nu hab ichs :) danke nochmal
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.