Hallo !! Ich bin neu und versuche den Sinn der Static-Variable zu verstehen, bzw. den Unterschied zu normal deklarierten Variablen. Und zwar habe ich im Netz folgendes gelesen: ------------ Eine static Variable innerhalb einer Funktion ist garantiert 0, wenn die Funktion das erste Mal angesprungen wird und behält zwischen Funktionsaufrufen ihren Wert. Eine automatische Variable wird jedes Mal neu angelegt und ggf. initialisiert. Die folgende Funktion zählt wie häufig sie aufgerufen wurde: int f(){ static int count; return ++count; } ------------ Dabei habe ich nicht verstanden: "....behält zwischen Funktionsaufrufen ihren Wert." Dies ist m.M. auch so wenn ich eine normale Variable nutze. (Wenn sie NUR von dieser Funktion verändert wird.) Wo ist also der Unterschied zum Static?
"Dies ist m.M. auch so wenn ich eine normale Variable nutze. (Wenn sie NUR von dieser Funktion verändert wird.)" Nein. Normalerweise ist das nicht so. Nur bei einigen µC-Compiler für i51,PIC,... kann dieser Eindruck entstehen, weil diese Prozessoren mit der sonst üblichen Technik der Speicherung lokaler Variablen auf Kriegsfuss stehen. Aber auch da ist das nicht sicher, da gute Compiler die lokalen Variablen verschieder und diskjunkter Funktionen überlagern werden.
1 | int f(void) |
2 | {
|
3 | int count = 0; |
4 | return ++count; |
5 | }
|
...liefert nach jedem Aufruf '1' als Wert,
1 | int f(void) |
2 | {
|
3 | static int count; /* hier ist das '= 0' implizit */ |
4 | return ++count; |
5 | }
|
...liefert nach jedem Aufruf 'n+1'. Das Ergebnis wäre Äquivalent zur Verwendung einer globalen Variablen
1 | int count; /* hier ist das '= 0' ebenfalls implizit */ |
2 | |
3 | int f(void) |
4 | {
|
5 | return ++count; |
6 | }
|
...oder einer Übersetzungsmodul begrenzten "lokal-globalen" Variablen
1 | static int count; /* '= 0' hier auch wieder implizit */ |
2 | |
3 | int f(void) |
4 | {
|
5 | return ++count; |
6 | }
|
Ist das so einigermaßen Verständlich?
Klarer: Das Verhalten von int f(void) { int count; return ++count; } ist undefiniert. Gute Compiler werden auf diesen Fehler hinweisen (oft aber nur bei eingeschalteter Optimierung).
> Das Ergebnis wäre Äquivalent zur Verwendung einer globalen Variablen
OK, das klärt es auf. Ich bin immer von Globalen Variablen ausgegangen.
In dem Fall wäre Static das gleiche.
Nur bedingt! Mit dem Schlüsselwort "static" wird dem Compiler in einer sog. 'translation-unit' mitgeteilt, daß diese Variable innerhalb dieser 'translation-unit' gültig ist, er sich aber nicht auch noch darum kümmern muss, ob diese Variable evtl. von einer anderen Stelle (ein Stück Code aus einer anderen Datei) verändert wird.
Hallo, bin ganz neu hier. Ich habe noch Probleme "static" genau zu verstehen. Wenn ich schreibe:
1 | int f(void) |
2 | {
|
3 | static int count = 0; |
4 | return ++count; |
5 | }
|
Würde dann auch bei jedem Aufruf n+1 zurück gegeben werden, oder immer 1 ? MfG
Das hier steht wörtlich so im 3. Post:
1 | int f(void) |
2 | {
|
3 | static int count; /* hier ist das '= 0' implizit */ |
4 | return ++count; |
5 | }
|
> ...liefert nach jedem Aufruf 'n+1'. Das Ergebnis wäre Äquivalent zur > Verwendung einer globalen Variablen Also was soll diese Frage?
WÖRTLICH steht bei meiner Frage was anderes: "=0" steht da noch, ein Segen wenn man lesen kann. Ich dachte mir in meiner Naivität: vielleicht wird, wenn man =0 explizit hinschreibt das implizite =0 (welches im ursprünglichen Post beschrieben wurde) immer wieder bearbeitet. Habe erst seit Montag mit C und Controllern zu tun und muss jetzt den Quelltext eines anderen verstehen um einige Kleinigkeiten zu ändern, da kam eben static mit explizit =0x00 vor und ich konnte damit nichts anfangen. Bin halt nicht so schlau wie Du und habe bisher "nur" rein analoge Leistungselektronik im Kilowattbereich betrieben und keine Ahnung was Ihr Schwachstromelektroniker so macht. Controller kotzen mich sowieso an, aber jetzt muss ich mich halt damit befassen. Eigentlich bin ich nach vielen Jahren Leistungselektronikentwicklung zu alt für den Controllerkram, aber man kann sich nicht alles aussuchen im Leben ... bisher konnte ich das immer umgehen. Vielleicht kannst Du das Programm ja für mich ändern ... offenbar bist Du beruflich noch nicht ausgelastet genug wenn Du nichts besseres zu tun hast als Dich seit heute Morgen über meine zugegeben etwas naive Frage aufzuregen.
Frank Heluk wrote: > WÖRTLICH steht bei meiner Frage was anderes: "=0" steht da noch, ein > Segen wenn man lesen kann. Ich dachte mir in meiner Naivität: vielleicht > wird, wenn man =0 explizit hinschreibt das implizite =0 (welches im > ursprünglichen Post beschrieben wurde) immer wieder bearbeitet. Du hättest natürlich etwas präziser auf den genauen Gegenstand der Frage hinweisen können... Es gibt eine Regel, die man sich gut merken kann: Globale und statische lokale Variablen werden, wenn nichts anderes angegeben ist, automatisch zu Programmbeginn mit 0 initialisiert, so dass das "= 0" an der Stelle überhaupt keinen Effekt hat. Automatische Variablen werden hingegen nicht automatisch initialisiert, so dass es bei denen undefiniert ist, was drinsteht (und wenn man eine automatische Variable uninitialisiert verwendet, gibt's auch eine Warnung vom Compiler). Wenn man eine statische Variable auf einen anderen Wert als 0 initialisiert, dann wird die Initialisierung genau wie bei globalen Variablen nur ein einziges Mal bei Programmstart durchgeführt. Ansonsten würde das Ganze keinen Sinn machen. Statische Variablen verhalten sich exakt so wie globale Variablen, nur mit dem Unterschied, dass sie einen eingeschränkten Gültigkeitsbereich haben (also nur innerhalb des Blockes/der Compile-Einheit verwendbar sind, in dem/der sie definiert wurden).
Frank Heluk wrote: > Controller kotzen mich sowieso > an, ... Das ist allerdings nicht die beste Voraussetzung dafür. C ist übrigens eine verbreitete Sprache, hat aber ihre Tücken (wie du ja eigentlich gerade merkst). > Eigentlich bin ich > nach vielen Jahren Leistungselektronikentwicklung zu alt für den > Controllerkram, ... Ach was. Man ist nie zu alt, etwas neues zu lernen. Oder um bei Manfred von Ardenne zu bleiben: alle 5 Jahre sollte man was komplett anderes anfangen, damit man nicht verlernt, sich in ein neues Problem einzuarbeiten. Ich habe zwar noch nie wirkliche Leistungselektronik gebaut, würde mich aber trotzdem nicht überfordert fühlen, wenn die Aufgabe morgen plötzlich auf mich zu käme. Lass dich nicht von einem Einzelnen abschrecken, der sich hier mal im Ton vergreift.
Vielen Dank für die gute Erklärung. Jetzt habe ich das auch wirklich verstanden. Das Forum hier ist wirklich sehr gut, die meisten meiner Anfängerfragen konnten durch das suchen in alten Threads gelöst werden.
Die Controller haben schon Ihre Vorteile. Bisher hab ich Ablaufsteuerungen in reiner Logik-Hardware entworfen. Mit einem Controller kann man hinterher noch Änderungen über die Software einfliessen lassen, wo bei Hardware wieder ein neues Layout nötig ist. Vielleicht finde ich noch Spass daran, wenn es erst mal besser funktioniert.
Eine Bitte nur noch: mach einen neuen Thread auf für ein neues Problem. Selbst wenn dein Problem ganz genau dasselbe zu sein scheint, wie das, worüber du gerade in einem anderen Thread gelesen hast... Du kannst immer noch den alten Thread als URL referenzieren, wenn du meinst, dass dem so wäre -- in aller Regel ist es am Ende aber doch ganz was anderes. Viel Erfolg!
Johannes M. wrote: > Statische Variablen verhalten sich > exakt so wie globale Variablen, nur mit dem Unterschied, dass sie einen > eingeschränkten Gültigkeitsbereich haben (also nur innerhalb des > Blockes/der Compile-Einheit verwendbar sind, in dem/der sie definiert > wurden). Stimmt so nicht ganz.
1 | // gut
|
2 | int * foo () |
3 | {
|
4 | static int bar; |
5 | |
6 | return & bar; |
7 | }
|
erlaub es, auch ausserhalb der Funktion auf die Variable bar zuzugreifen, und der Zugriff ist gültig. Bei lokalen Variablen ist so der Zugriff zwar syntaktisch möglich, greift aber an einen Platz, wo nach Verlassen der Funktion idR was undefiniertes steht:
1 | // böse
|
2 | int * foo () |
3 | {
|
4 | int bar = 0; |
5 | |
6 | return & bar; |
7 | }
|
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.