Forum: Compiler & IDEs STATIC


von Chris++ (Gast)


Lesenswert?

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?

von A.K. (Gast)


Lesenswert?

"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.

von Patrick D. (oldbug) Benutzerseite


Lesenswert?

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?

von A.K. (Gast)


Lesenswert?

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).

von Chris++ (Gast)


Lesenswert?

> 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.

von Patrick D. (oldbug) Benutzerseite


Lesenswert?

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.

von Frank H. (avrnooby)


Lesenswert?

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

von Stefan E. (sternst)


Lesenswert?

n+1

von Frank H. (avrnooby)


Lesenswert?

Vielen Dank !

von Olli (Gast)


Lesenswert?

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?

von Frank H. (avrnooby)


Lesenswert?

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.

von Johannes M. (johnny-m)


Lesenswert?

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).

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von Frank H. (avrnooby)


Lesenswert?

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.

von Frank H. (avrnooby)


Lesenswert?

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.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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!

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

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
Noch kein Account? Hier anmelden.