Statische Variablen



  • Hallo zusammen,

    ich beschäftige mich grade mit dem Lernen von C.
    Und in einem Buch gab es ein kleines Beispiel zu statischen Variablen:

    
    #include <stdio.h>
    
    void inkrement(void) {
    
    	static int i = 1;
    	printf("Wert von i: %d\n", i);
    	i++;
    
    }
    
    int main()
    {
    
    	inkrement();
    	inkrement();
    	inkrement();
    
    	return 0;
    
    }
    

    Nun verstehe ich, dass statische Variablen erhalten bleiben, wenn der Block (in dem Fall die Funktion) beendet wird. Aber wenn man den zweiten Aufruf der Funktion "inkrement" macht, müsste es dann nicht einen Fehler geben, weil man die Variable mehrfach initialisiert?

    Wenn ich das Beispiel etwas umschreibe, dann ist das so.

    int main()
    {
    
    	static int y = 1;
    	static int y = 2;
    
    	printf("Der Inhalt von y: %d\n", y);
    
    	return 0;
    
    }
    

    Danke 🙂



  • @Timmi87 Die Variablendefinition ist eine Anweisung an den Compiler, Platz für die Variable zu machen.

    Somit kommt es im Programmablauf nicht zu einer erneuten Definition. (Wäre ja auch blöd).

    Ebenso blöd wäre es, wenn die statische Variable bei jedem Aufruf neu initialisiert wird - dann wäre sie nicht statisch.

    Statische Variablen werden schon beim Programmstart initialisiert (der Speicherbereich ist vorbesetzt). Das ist aber eine praktische Umsetzung und die interessiert den C-Standard nicht.

    Daher ist deine Vermutung "Wenn ich das Beispiel etwas umschreibe, dann ist das so." falsch



  • @DirkB sagte in Statische Variablen:

    Statische Variablen werden schon beim Programmstart initialisiert (der Speicherbereich ist vorbesetzt). Das ist aber eine praktische Umsetzung und die interessiert den C-Standard nicht.

    Nein, statische Variablen in Funktionen werden erst bei der ersten Nutzung initialisiert.



  • Hallo @DirkB und @john-0,

    vielen Dank für eure Antworten.
    Aber ich habe sie leider nicht verstanden.

    In beiden Fällen (in dem Buch-Beispiel und in meinem umgeschriebenen Beispiel) wird der Befehl

    static int i = 1;
    

    mehrfach aufgerufen. Aber im Buchbeispiel führt das nicht dazu, dass es eine Fehlermeldung gibt.
    In meinem Beispiel gibt es eine Fehlermeldung wegen mehrfacher Initialisierung.



  • @Timmi87 Beim Aufruf der Funktion wird die Initialisierung (Zuweisung bei der Definition) bei der static Variablen nur beim ersten Aufruf der Funktion ausgeführt.
    Darum wird das, auch bei mehrmaligen Aufruf der Funktion, nur einmal gemacht.

    Im main steht das aber zweimal mit unterschiedlichen Werten.
    Was soll der Compiker da machen?

    Deine Annhame, dass der Befehl die Initialisierung mehrfach aufgerufen, wird ist falsch.



  • Ein kurzes Beispiel

    #include "stdio.h"
    #include "stdlib.h"
    
    static int global_int = 10;
    
    int foo (void) {
        static int x = 0;
    
        x++;
    
        return x;
    }
    
    int main () {
        printf ("%i\n", global_int);
    
        for (int i = 0; i<10; ++i) {
            printf ("%i\n", foo());
        }
    
        return EXIT_SUCCESS;
    }
    

    x in der Funktion foo wird nur einmal, nämlich bei der ersten Nutzung initialisiert. Die Variable global_int wird auch nur einmal initialisiert, aber das erfolgt vor der Ausführung der main-Funktion. Was nicht definiert ist, ist die Reihenfolge der Initialisierung von statischen Objekten in verschiedenen Übersetzungseinheiten.



  • @john-0, @DirkB

    Ok, ich glaube ich hab es jetzt kapiert.
    In dem Buch steht was von "Datensegment" und das habe ich mal gegoogelt.
    Bei Wikipedia steht:

    Als Datensegment bezeichnet man den Teil von Objektdateien oder eines laufenden Prozesses, in dem globale und statische Variablen abgelegt sind. Diese Variablen müssen beim Start des Programms bereits im Speicher vorhanden und initialisiert sein, außerdem ist ihr Speicherplatzbedarf bereits zur Übersetzungszeit bekannt. Daher wird bereits beim Übersetzen ein Datenblock erstellt, der später als Teil des Programms beim Starten in den Speicher geladen und sofort verwendet werden kann.

    Das heißt, dass der Compiler für statische Variablen bereits zur Übersetzungszeit den Speicherbedarf reserviert. Und deswegen darf die Initialisierung nur einmal im kompletten Code vorkommen.

    Richtig?



  • @Timmi87 sagte in Statische Variablen:

    Das heißt, dass der Compiler für statische Variablen bereits zur Übersetzungszeit den Speicherbedarf reserviert. Und deswegen darf die Initialisierung nur einmal im kompletten Code vorkommen.

    Umgekehrt.
    Der Standard verlangt, dass die Initialisierung nur einmal im kompletten Code vorkommt.
    Wie das technisch umgesetzt wird (Datensegment) ist egal, hauptsache es wird irgendwie gemacht.

    Normale Variablen werden meist auf dem Stack abgelegt. Da sind static-Variablen ungünstig, da sich die Belegung des Stack dauernd ändert.



  • Alles klar,

    vielen Dank 🙂

    @DirkB
    @john-0


Anmelden zum Antworten