2017-11-29 5 views
-1

Ich habe den folgenden Code, der jedes Eingabewort in einer separaten Zeile anzeigen soll. Für Tritte habe ich eine printf platziert, um die Wortzählung nach jedem Wort anzuzeigen, um sicherzustellen, dass ich die Logik verstanden habe.Interessanter Wert, wenn nicht auf 0 initialisiert

#include <stdio.h> 

/*Write a program that prints its input one word per line*/ 

#define IN 1 
#define OUT 0 

int main() 
{ 
    int c, state, wordcount; 

    state = OUT; 
    while ((c = getchar()) != EOF) 
    { 
     if (c == ' ' || c == '\t' || c == '\n') 
     { 
      if (state == IN) 
      { 
       printf("\n"); 
       printf("Current word count: %i\n", wordcount); 
       /*troubleshooting*/ 
       state = OUT; 
      } 
     } 
     else if (state == OUT) 
     { 
      state = IN; 
      putchar(c); 
      ++wordcount; 
     } 
     else 
     { 
      putchar(c); 
     } 
    } 
} 

Der Ausgang dafür ist in diesem Bild gezeigt. Aus irgendeinem Grund, ohne die Variable initialisiert zunächst wordcount auf 0, es beginnt am 9.

Wordcount variable gets set to 9 when it is not initialized to 0

Wenn die wordcount Variable auf 0 initialisiert (nur Einstellung wordcount = 0 in der int Deklarationsanweisung), alles funktioniert wie erwartet:

Wordcount variable is correct when initialized to 0

Kann mir jemand erklären, was hier los ist? Hat das etwas damit zu tun, wie diese Variablen im Speicher gespeichert werden? Versuchen zu verstehen, was vor sich geht. Vielen Dank!

+0

Was ist '' innen? 'state' wurde nicht initialisiert. – babon

+0

Undefiniertes Verhalten. –

+0

Sie möchten die reine C-Erklärung oder die Erklärung, die sich auf die C-Kompilierung bezieht? – StoryTeller

Antwort

0

Wenn Sie eine Variable initialisieren, wird es ein „random“ (nicht verwendet) Zuordnung in Ihrem RAM, wenn etwas schon da geschrieben wurde, wird die Variable verwendet diesen Wert für sich.

Deshalb deklarieren Sie immer Variablen.

Das Backend ist ein bisschen komplizierter, aber das ist die "einfache" Erklärung.

2

Vor der OP bearbeiten die Frage:

Dies ist nicht definiertes Verhalten.

if (state == IN) 
//Some code 
else if (state == OUT) 
//Some code 

Es sieht aus wie State nicht initialisiert (oder auf einen Wert gesetzt), bevor es zu vergleichen. Einen Wert nicht initialisiert zu belassen, ist kein undefiniertes Verhalten, aber der Zugriff auf diesen Weg ist definitiv ein Weg, um in UB-Schrecken zu kommen!

In C89, siehe Abschnitt 6.5.7 Initialisierung.

Wenn ein Objekt mit automatischer Speicherdauer nicht explizit initialisiert wird, ist der Wert unbestimmt. Wenn ein Objekt, die statische Speicherdauer hat nicht explizit initialisiert wird, wird es initialisiert implizit als ob jedes Mitglied, die arithmetischen Typen hat wurden 0 zugeordnet und jedes Mitglied, das Zeigertyp hat wurde ein Null-Zeiger-Konstante zugewiesen

In C99 finden Abschnitt 6.7.8 Initialisierung

Wenn ein Objekt, das die automatische Speicherdauer hat nicht explizit initialisiert, deren Wert unbestimmt ist.Wenn ein Objekt mit statischer Speicherdauer nicht explizit initialisiert wird: - wenn es einen Zeigertyp hat, wird es mit einem Nullzeiger initialisiert; - Wenn es einen arithmetischen Typ hat, wird es initialisiert auf (positiv oder vorzeichenlos) Null; - Wenn es ein Aggregat ist, wird jedes Mitglied (rekursiv) gemäß diesen Regeln initialisiert; - Wenn es sich um eine Union handelt, wird das zuerst benannte Mitglied (rekursiv) gemäß diesen Regeln initialisiert.

standard section 6.3.2.1p2 Siehe:

Wenn der L-Wert ein Objekt der automatischen Speicherdauer bezeichnet, die mit der Registerspeicher Klasse deklariert worden sein (hatte nie seine Adresse genommen), und das Objekt ist nicht initialisiert (nicht mit einem Initialisierer deklariert wurde und vor dessen Verwendung keine Zuweisung vorgenommen wurde, ist das Verhalten undefiniert.

Nach C99 Standard sein „unbestimmten Wert“, es ist entweder ein nicht näher spezifizierter Wert oder eine Falle Darstellung.

Aber, bevor Sie in die Details der Minderjährigen diese Standards bieten, sollten Sie einige der häufigsten und gut zu wissen Programmiergewohnheiten erwerben. Dies kann ein guter Anfang sein.


Nach dem Bearbeiten von OP:

ich die exakt gleiche Code von OP lief die state = OUT; heißt State initialisiert hat, verhält es sich so, wie es sein sollte.

stdin:

Lazy Frog 

Ausgang:

Lazy 
Current word count: 1 
Frog 
Current word count: 2 
+0

Mein Fehler - Ich habe den Variablennamen von "inside" in "state" geändert und muss die ursprüngliche Zuweisung verpasst haben. Das selbe passiert immer noch, selbst wenn der Zustand mit meinem OUT-Makro initialisiert wird. –

+0

Mit diesem letzten Satz würde immer eine automatische Variable initialisieren explizit unter den "gut zu wissen" Codierungsgewohnheiten fallen? Ich bin ein Noobie, also versuch ich nur, all das zu verstehen. –

+0

@DerekZhongXuanKwok: Es würde abhängen. Manchmal fangen einige Compiler einige dieser Probleme nicht mit nicht initialisierten Variablen ab.Natürlich ist das Kompilieren eines Codes mit ausgeblendeten Warnungen ein weiteres Problem. Also lasse ich meine Variablen normalerweise initialisiert und kompiliere meinen Code mit aktivierten Warnungen. – WedaPashi

Verwandte Themen