2009-08-04 22 views
2

In C enthalten automatische Variablen, wenn sie nicht initialisiert sind, einen ungültigen Wert. Beachten Sie jedoch das folgende Programm:Nicht initialisierte Werte werden initialisiert?

int main(){ 
signed char term; 
(char)term--; 
printf("%d\n",term); 
} 

Es druckt einen Wert von "7". Wenn ich keine (char)term-- mache, wird der Wert '8' ausgegeben. Also, es enthält definitiv keinen Müllwert. Ist das nicht widersprüchlich?

Antwort

15

Das ist Müll. Sie erhalten 8 als Müll und subtrahieren um 7 zu erhalten.

Dies ist was undefiniertes Verhalten ist. Nur weil du 8 bekommst, heißt das nicht, dass es gut definiert ist. Versuchen Sie, in Ihrem Code komplexere Dinge zu tun. Fügen Sie Variablen oberhalb und unterhalb Ihrer char hinzu.


über Ihren "test", sagen Sie:

jedoch die Konsistenz ist schwer zu übersehen, dass Müll unter Berücksichtigung zufällig sein sollte.

Sie müssen Ihre Annahmen überprüfen. "Müll sollte zufällig sein", sagt wer? Nach was soll der Müll zufällig sein? Der einzige Weg, auf dem Müll zufällig ist, ist, wenn das System periodisch Speicher durchläuft und ihm Zufallszahlen zuordnet.

Wenn wir "zufällig" sagen, meinen wir, wir wissen nicht, was es sein wird. Das macht es nicht unbestimmt. Dies sind Computer. Wenn Sie ihnen sagen, dass sie immer und immer wieder die gleiche Sache machen sollen, wird es dasselbe tun über und über.

Ihr Compiler und Ihre Einstellungen produzieren immer den gleichen Code, der Ihnen diese Müllwerte gibt. Deterministisch, aber Sie können sich nicht auf dieses Verhalten verlassen: "zufällig".

Auch 1-800 bedeutet nicht, dass Sie das so nehmen wie Sie. "8" bedeutet nicht unbedingt Müll, denn in der Art, wie Dinge eingerichtet werden, füllt Ihr Compiler sie mit 8. Was er damit meint, ist 8 genauso Müll wie jede andere Zahl.

2

Müll in Bezug auf den Wert ist, was noch auf dem Stapel durch einige vorherige Funktion übrig war. Ändern Sie libc oder eine beliebige Anzahl von Dingen, und diese Zahl wird sich ändern.

4

Der Wert 8 ist in der Zahlengruppe enthalten, die als "Müll" oder "nicht initialisiert" gilt.

0

Es hält Müll, es enthält 8 Bits Müll und liest die Binärzahl als eine Zahl von 0-255 (Vortäuschen Sie mit einem unsigned Char).

So hat der Speicher könnte so gewesen:

| 0 0 1 0 1 0 1 0 0 1 0 0 1 0 0 1 0 1 0 1 |

Und es dauerte das Ende (1 0 0 1 0 1 0 1) und lesen Sie es als eine Zahl, die 149 ist. Es hängt nur ab, was zufälliges binäres ist in der Stelle der angegebenen Länge (zB: unsigned char = 1 Byte)

Wenn es ein unsigned int wäre, würde es 4 Bytes zufälligen Müll nehmen und es zu einer Zahl machen.

0

Stellen Sie sich vor, dass es mit einem beliebigen Wert (Bitmuster) initialisiert wird.

Dieser willkürliche Wert hängt davon ab, wofür die Stapelposition für die Variable zuletzt verwendet wurde, es ist definitiv kein zufälliger Wert. Es kann oder kann nicht immer der gleiche Wert sein. Es kann von etwas anderem abhängen, das vorher passiert ist.

Es empfiehlt sich, automatische Variablen immer zu initialisieren, um undefiniertes Verhalten zu vermeiden.

2

Sie scheinen die Begriffe "Müll" und "nicht deterministisch" vermischt zu haben. Der Wert im Begriff wird als Müll betrachtet, weil Sie keine Kontrolle darüber haben, welcher Wert darin enthalten ist. Er kann von Plattform zu Plattform wechseln oder zum Ausführen laufen, dh undefiniertes Verhalten.

Auf der anderen Seite, wenn alle Dinge in der Laufzeitumgebung des Programms sind gleich, der Wert wird wahrscheinlich für jeden Lauf gleich sein. Dies schließt jedoch nicht aus, dass es Müll ist.

+0

Zustimmen. Wenn Sie das verstehen wollen, versuchen Sie es mit dem Debugger durch den Code zu gehen, mit einem Schritt (möglicherweise im Assembly-Modus), da dies Sie durch den Startcode führt, der vor main() läuft. – Adriaan

0

Danke für die Antworten. Ich habe versucht, eine kleine Änderung aus:

int main(){ 
      signed char term1; 
      signed char term2; 
      signed char term3; 
      printf("%d\n%d\n%d\n",term1,term2,term3); 
} 

ich das Programm auf drei verschiedenen Rechnern lief. Das Ergebnis war das gleiche auf allen 3 Maschinen: Term1 bekommt value = -124, term2 = 4 und term3 = 8. Wenn ich term3, term1 = 4, term2 = 8 entferne. Wenn ich term2 entferne, ist term1 = 8. Also, im Grunde genommen , der letzte Wert, der als signiertes Zeichen deklariert wird, erhält den Wert '8'. Als 1800 INFORMATION sagte, "8" ist einer der Werte, die verwendet werden, um Müll zu bezeichnen, dies kann es sein. Die Konsistenz ist jedoch schwer zu übersehen, wenn man bedenkt, dass Müll zufällig sein sollte.

+0

Nichts auf einem Computer ist wirklich zufällig. Sie könnten ein verwenden. Sie könnten Ihr Programm auf drei verschiedenen Architekturen mit drei verschiedenen Laufzeiten und verschiedenen Compilern testen. Zum Beispiel eine x86-Windows-Maschine, eine x86-Linux-Maschine und ein PowerPC-Macintosh. Meine Vermutung ist, dass Sie unterschiedliche Ergebnisse erhalten werden. Sie können sogar unterschiedliche Ergebnisse mit verschiedenen Compilern (z. B. Visual Studio 2008 gegenüber Visual C++ 6.0) erhalten. Der entscheidende Punkt ist, dass es in Bezug auf die C-Laufzeitumgebung inkonsistent ist. –

Verwandte Themen