2016-03-30 4 views
-2

Warum erhalte ich Müll Wert, wenn ich den folgenden C-Code mit GCC/Clang kompilieren? Hinweis, wenn ich nur den Wert von x im inneren Bereich drucken, erhalte ich das erwartete Ergebnis.Warum bekomme ich einen Müllwert für das C-Programm?

#include<stdio.h> 
int main() 
{ 
    int x = 5; 
    { 
     int x = x; 
     printf("%d", x); 
    } 
    return 0; 
} 
+2

Die 'X' in Umfang ist 'X', nicht 'X'. (Möglicherweise [verwandte Frage] (http://stackoverflow.com/q/14935722).) –

+0

Nehmen Sie die Zeile "int x = 5;" weg und nichts ändert sich im Code. Auf dieses 'x' wird niemals zugegriffen. –

Antwort

4

In dieser Erklärung

int x = x; 

der Punkt der Erklärung des Identifiers x nach der vollständigen Definition des declarator ist die x bereits Zeichen sichtbar vor der Zuweisung ist = und versteckt die Variable mit dem gleichen Namen deklarierte im äußeren Block Umfang ..

Und Sie haben das x, die an sich nicht initialisiert wird zugewiesen. Als Ergebnis hat es einen unbestimmten Wert.

Sie können es die folgende Art und Weise vorstellen

int x; 
x = x; 

Genau das gleiche Beispiel in dem C++ Standard existiert (Ziffer 3.3.2 der Erklärung)

1 Der Punkt der Erklärung für einen Namen ist unmittelbar nach seiner vollständigen declarator (Ziffer 8) und vor dessen Initialisierer (falls vorhanden), außer wie unten angemerkt. [Beispiel:

int x = 12; 
{ int x = x; } 

Hier wird die zweite x ist mit einer eigenen (unbestimmt) Wert initialisiert. -Ende Beispiel]

im C-Standard dort geschrieben wird (6.2.1 Scopes von Kennungen)

7 Struktur, Vereinigung und Enumeration-Tags Umfang, die von nur nach dem Erscheinen beginnt das Tag in einem Typspezifizierer, der das Tag deklariert. Jede Aufzählungskonstante hat einen Gültigkeitsbereich, der unmittelbar nach dem Erscheinen seines definierenden Aufzählers in einer Aufzählungsliste beginnt. Jede andere Kennung hat Bereich, der unmittelbar nach dem Abschluss des seines declarator beginnt.

Beachten Sie die Definition von Enumeratoren. Die Regel für Enumeratoren ist anders.

Dieses Programm ist gut ausgebildet, und der Enumerator x wird durch die Variable x in dem äußeren Umfang erklärt initialisiert werden (während der Enumerator y wird durch den vorhergehenden Enumerator x initialisiert werden).

#include <iostream> 

int main() 
{ 
    const int x = 10; 
    { 
     enum E { x = x + 1, y = x }; 
     std::cout << "E::x = " << x << ", E::y = " << y << std::endl; 
    } 
    std::cout << "x = " << x << std::endl; 
}  

Die Programmausgabe ist

E::x = 11, E::y = 11 
x = 10 
0

Die Deklaration int x = 5; liegt außerhalb des Gültigkeitsbereichs Ihres zweiten Blocks. Dies bedeutet, dass variable x in der folgenden Codeabschnitt

{ 
    int x = x; 
    printf("%d", x); 
} 

verschieden ist von der Außenseite variable x, in dem Haupt erklärt. Also, wenn Sie versuchen, seinen Wert in der Zuordnung zuzugreifen, gibt es einen Müll Wert, da es nicht in diesem Bereich gab es vor und deshalb es nicht initialisiert.

Verwandte Themen