2012-08-29 19 views
13

C++ Primer sagtauf lokale und globale statische Variablen in C++

Jede lokale statische Variable vor dem ersten Mal initialisiert wird Ausführung der Definition des Objekts durchläuft. Lokale Statiken sind nicht zerstört, wenn eine Funktion endet; Sie werden zerstört, wenn das Programm beendet wird.

Sind lokale statische Variablen anders als globale statische Variablen? Anders als der Ort, an dem sie erklärt werden, was ist noch anders?

void foo() { 
    static int x = 0; 
    ++x; 

    cout << x << endl; 
} 

int main (int argc, char const *argv[]) { 
    foo(); // 1 
    foo(); // 2 
    foo(); // 3 
    return 0; 
} 

Vergleichen mit

static int x = 0; 

void foo() { 
    ++x; 

    cout << x << endl; 
} 

int main (int argc, char const *argv[]) { 
    foo(); // 1 
    foo(); // 2 
    foo(); // 3 
    return 0; 
} 

Antwort

18

Die Unterschiede sind:

  • Der Name in der Funktion nur zugänglich ist, und keine Bindung hat.
  • Es wird initialisiert, wenn die Ausführung zum ersten Mal die Definition erreicht, nicht notwendigerweise während der Initialisierungsphasen des Programms.

Der zweite Unterschied kann nützlich sein, die statische intialisation um Fiasko zu vermeiden, wo globale Variablen zugegriffen werden kann, bevor sie initialisiert sind. Indem Sie die globale Variable durch eine Funktion ersetzen, die einen Verweis auf eine lokale statische Variable zurückgibt, können Sie sicherstellen, dass sie initialisiert wird, bevor ein Zugriff darauf möglich ist. (Es gibt jedoch immer noch keine Garantie dafür, dass es nicht zerstört wird, bevor es vollständig zugänglich ist. Sie müssen dennoch sehr vorsichtig sein, wenn Sie eine global zugängliche Variable benötigen. Lesen Sie die Kommentare für eine link, um in dieser Situation zu helfen.)

+1

Sie können die Reihenfolge der Zerstörung mit ein wenig Arbeit garantieren. http://stackoverflow.com/a/335746/14065 –

5

Ihr Umfang ist anders. Eine statische Variable mit globalem Gültigkeitsbereich ist für jede Funktion in der Datei zugänglich, während die auf Funktionsumfang beschränkte Variable nur innerhalb dieser Funktion zugänglich ist.

+0

Ja, natürlich. Vielen Dank – JAM

+0

@ DavidRodríguez-Dribeas: 'ist undefiniert über Kompilierungseinheit ** s **. Innerhalb einer Übersetzungseinheit ist die Reihenfolge als Deklarationsreihenfolge definiert. –

+0

@LokiAstari: Du hast Recht ... Ich war zu vage in dem Kommentar :) –

4

Es richtiger Name ist:

static storage duration object. 

Globale Variablen sind auch 'statische Speicherdauer Objekt'. Der wesentliche Unterschied von den globalen Variablen sind:

  • Sie werden erst bei der ersten Verwendung
    Hinweis initialisiert: Eine Ausnahme bei der Konstruktion bedeutet, dass sie nicht initialisiert wurden und somit nicht verwendet.
    So wird es erneut versuchen, wenn die Funktion das nächste Mal eingegeben wird.
  • Es visability durch ihren Umfang begrenzt
    (dh sie können nicht außerhalb der Funktion zu sehen)

von Apart, dass sie genau wie andere ‚statische Speicherdauer-Objekte‘.

Hinweis: Wie alle statischen Aufbewahrungsobjekte werden sie in umgekehrter Reihenfolge der Erstellung zerstört.

+0

Misse ich die Spezifikation falsch, wenn ich es lese, dass die statischen Locals _may_ zusammen mit den anderen Statiken initialisiert werden können und nicht bis zum ersten Aufruf verzögert werden können ? (C++ 11 §6.7.4 scheint in einigen Fällen auf §3.6.2 zu verweisen und erlaubt dies) –

+0

** 3.7.1 Statische Speicherdauer ** (Hinweis: 6.7 beschreibt die Initialisierung von lokalen statischen Variablen). ** 6.7 Deklarationsanweisung ** (Konstante Initialisierung (3.6.2) einer Block-Scope-Entität mit statischer Speicherdauer wird ggf. vor der ersten Eingabe des Blocks ausgeführt. ... Andernfalls wird eine solche Variable das erste Mal initialisiert Die Steuerung geht durch ihre declarationConstant-Initialisierung (3.6.2) einer Block-Scope-Entity mit statischer Speicherdauer; eine solche Variable wird nach Abschluss ihrer Initialisierung als initialisiert betrachtet.) –

1

Der wichtigste oder schwerwiegendste Unterschied ist der Zeitpunkt der Initialisierung. Lokale statische Variablen werden beim ersten Aufruf initialisiert, um dort zu funktionieren, wo sie deklariert werden.Die globalen werden zu einem bestimmten Zeitpunkt vor dem Aufruf der Hauptfunktion initialisiert. Wenn Sie nur wenige globale statische Variablen haben, werden sie in einer nicht angegebenen Reihenfolge initialisiert, was zu Problemen führen kann. Dies wird als statisches Initialisierungsfiasko bezeichnet.

0

In Ihrem ersten Codeblock ist x lokal für die Funktion foo(), was bedeutet, dass es in foo() erstellt und am Ende der Funktion nach cout zerstört wird. In Ihrem zweiten Block ist x jedoch global, was bedeutet, dass der Umfang von x das gesamte Programm ist. Wenn Sie unter int main wollten Sie könnte < < x < < Endl cout und es wäre jedoch im ersten Block drucken würde es sagen x nicht

erklärt
0
  1. Sie auf alle Funktionen in einem Programm, während globalen bekannt sind Variablen sind nur in einem begrenzten Umfang bekannt.
  2. Globale statische Variablen können vor dem Programmstart initialisiert werden, während lokale statische Variablen initialisiert werden können, wenn die Ausführung den Punkt erreicht.
3

Hoffentlich hilft dieses Beispiel, den Unterschied zwischen statischen lokalen und globalen Variablen zu verstehen.

#include <iostream> 

using namespace std; 

static int z = 0; 

void method1() { 
    static int x = 0; 
    cout << "X : " << ++x << ", Z : " << ++z << endl; 
} 

void method2() { 
    int y = 0; 
    cout << "Y : " << ++y << ", Z : " << ++z << endl; 
} 

int main() { 
    method1(); 
    method1(); 
    method1(); 
    method1(); 
    method2(); 
    method2(); 
    method2(); 
    method2(); 
    return 0; 
} 

Ausgang:

X : 1, Z : 1 
X : 2, Z : 2 
X : 3, Z : 3 
X : 4, Z : 4 
Y : 1, Z : 5 
Y : 1, Z : 6 
Y : 1, Z : 7 
Y : 1, Z : 8 
Verwandte Themen