Warum sehe ich seltsame Werte an, wenn ich drucken nicht initialisierten Variablen?
In der folgende code, der Variablen kein Anfangswert und bedruckt diese variable.
int var;
cout << var << endl;
Ausgabe : 2514932
double var;
cout << var << endl;
Ausgabe : 1.23769 e-307
Ich verstehe nicht, diese Ausgabe der Startnummern. Kann irgend jemand erklären mir das an?
- Wenn Sie diesen code kompilieren. Funktioniert der compiler nicht erzeugen eine Menge von Warnungen über nicht initialisierte Variablen? Wenn Sie Ihren compiler Warnungen als Fehler behandeln (eine gute Idee), und erhöhen auch die Warnung Ebene, dann wird es nicht kompilieren und erstellen Sie sicherer code (Warnungen sind in der Regel logische Fehler).
- ja, ich habe diesen code kompilieren mit gcc auf ubuntu. es war keine Warnung.
- kompilieren mit
-Wall
, wird Ihnen helfen, vor Ort mehr Warnungen. Und dieses Problem wird angezeigt, wenn Sie verwenden die Flagge.gcc -Wall source.c -o myexecutable
- Welche Werte haben Sie erwarten, dass Ihr Programm zu drucken statt?
- Kennedy - ich erwarte gar nichts. ich war neugierig, was es ist.
- Ich bin das hinzufügen dieser auf die C++ FAQ, weil wir nicht haben eine nicht initialisierte Variablen, die Frage, und meine Antwort gibt die kanonischen und technischen Gründe für die Ergebnisse.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Einfach gesagt
var
ist nicht initialisiert und Lesen einer nicht initialisierten Variablen führt zu Undefiniertes Verhalten.Also tun Sie es nicht. Der moment, den Sie tun, Ihr Programm ist nicht mehr gewährleistet, das zu tun, was Sie sagen.
Formal "Lesen" einen Wert bedeutet, dass die Durchführung eines lvalue-zu-rvalue-Konvertierung auf. Und §4.1 erklärt: "...wenn das Objekt nicht initialisiert ist, wird ein Programm, das erfordert diese Umwandlung hat Undefiniertes Verhalten."
Pragmatisch, bedeutet das nur, der Wert ist Müll (nachdem alle, es ist leicht zu sehen, Lesen
int
zum Beispiel, bekommt nur zufällige bits), aber wir können nicht schließen dies, oder würden Sie Sie definieren nicht definiertes Verhalten.Für ein reales Beispiel:
Naiv, dann kann man folgern (über die Argumentation in den Kommentaren), dies sollte niemals drucken
"impossible"
; aber mit undefiniertem Verhalten, alles ist möglich. Kompilieren Sie es mitg++ -02
.double
endete mit Müll, dass es normalerweise unmöglich für einendouble
zu haben, es somit gegen eine invariante derdouble
geben. Die belegen, dass mitbool
ist viel einfacher und dramatischer."false"
im g++ - 4.9 und 5.1, wie sollte es drucken"impossible"
?false
undtrue
Zweige waren nicht genommen, weil der UB), aber Sie scheinen endlich geändert werden.Wenn du dies tust:
int var;
Sind Sie nur deklarieren Sie einen integer namens
var
. Sie tun nicht initialisiert ihn mit einem Wert, also in welcher Lagevar
ist, wird eine garbage-Daten.int var = 5;
Erklären würde, var und initialisieren Sie es auf 5.
Mehr sehen: http://en.wikipedia.org/wiki/Uninitialized_variable
Was Sie bekommen ist, was auch immer Daten, die zufällig auf dem Stapel an die Stelle der compiler beschlossen, dass variable sollte gehen, interpretiert als integer oder ein double. Es werden wahrscheinlich die gleichen, jedes mal das Programm ausgeführt wird, weil Programme in der Regel Verhalten sich deterministisch. Aber es gibt auch viele Fälle, in denen es am Ende nicht das gleiche von der run-to-run des Programms. Wenn Sie Ihr Programm im geringsten, oder haben Sie Entscheidungen basierend auf Benutzereingaben, bevor Sie Sie erhalten zu diesem code können Sie oder können nicht erhalten verschiedene zahlen.
Grundsätzlich den Wert einer variable noch nicht initialisiert ist unspezifisch und kann absolut nichts. Es gibt keinen Reim oder Grund zu dem, was da ist. Verwenden Sie eine variable, die nicht initialisiert ist (formal) nicht definiertes Verhalten zur Folge haben kann in allerlei seltsame Dinge.
Dies ist in der Regel eine schlechte Praxis. Sie wollen Programme, die sich in einer vorhersagbaren Weise, und mit nicht initialisierten Variablen ist eine Quelle von Unberechenbarkeit. Beachten Sie, dass es ausdrücklich nicht, eine Quelle der Zufälligkeit, nur Unberechenbarkeit. Die meisten Compiler beschweren sich über code wie, dass, wenn Sie schalten Sie alle Warnungen.
In C++, wenn Sie eine variable deklarieren, der compiler weist eine Speicher-Adresse zu. Und das ist es, keine Bereinigung erfolgt. Dies ist vor allem, weil C++ (und C) wo bauen Sie mit Leistung im Verstand. C++ nicht verbringen Zeit der Initialisierung eine Adresse, es sei denn, Sie sagen, es explizit zu tun.
Und der sogenannte Müll, die Sie sehen, ist, was es war Links an die Adresse von der letzten variable, die es verwendet.
Anderen Sprachen wird die Initialisierung der Daten für Sie. In der Tat, C# wird nicht lassen Sie diese variable verwenden, bis Sie Sie initialisieren. Diese Sprachen sind entworfen, um sicher, in dem Sinne, dass es nicht zulassen, Sie schreiben einen code, der versehentlich eine nicht initialisierte Adresse und Absturz Ihres Programms oder, noch schlimmer, Ihre Daten beschädigen.
du nicht initialisieren
var
in jedem Fall, also bekommst du Müll ausgegeben.hatte Sie getan
const int var(5);
wäre es initialisiert mit dem Wert
5
Wenn Sie erklären var es zugewiesen bekommt einen Speicherort im Speicher. Aber, dass Speicher nicht alles standardmäßig, so dass Sie abholen, was auch immer vorher da war. Dies wird einigen Müll Wert, keine Bedeutung hat.
In C++ - das gilt für beide Membervariablen und lokale Variablen. Aber in Sprachen wie Java und C# Ihre member-Variablen werden automatisch initialisiert zu 0 für numberic Typen, false für Boolesche Werte und null-Referenzen. Dies ist nicht für lokale Variablen und (zumindest in der C# - compiler) Ihren build schlägt fehl, wenn Sie versuchen, den Wert einer nicht initialisierten variable.