2014-06-05 11 views
7

Ich arbeite mit dem Classic K & R Buch "The C Programming Language", Second Edition.C Programmiersprache Beispiel Über Arrays

Ich habe dieses Problem mit der Übung in Seite 24 über Arrays.

Übung (Kopieren und Einfügen von PDF) sagen:

#include <stdio.h> 
/* count digits, white space, others */ 
main() 
{ 
    int c, i, nwhite, nother; 
    int ndigit[10]; 

    nwhite = nother = 0; 

    for (i = 0; i < 10; ++i) 
     ndigit[i] = 0; 

    while ((c = getchar()) != EOF) 
     if (c >= '0' && c <= '9') 
      ++ndigit[c-'0']; 
    else if (c == ' ' || c == '\n' || c == '\t') 
      ++nwhite; 
    else 
      ++nother; 

    printf("digits ="); 

    for (i = 0; i < 10; ++i) 

     printf(" %d", ndigit[i]); 

    printf(", white space = %d, other = %d\n", 
     nwhite, nother); 
} 

In diesem Fall sagt das Buch, das nach dem Programm der folgenden Ausgabe ausgeführt wird.

An dieser Stelle das Buch verwirrend, weil es, dass die Person, die Eingabe nicht sagen ...

Die Ausgabe dieses Programms auf sich selbst ist Ziffern = 9 3 0 0 0 0 0 0 0 1, Leerraum = 123, andere = 345

Ok, Jetzt werde ich meinen kopierten Code aus dem Buch setzen

Dies ist meine Übung von eclipse-kopiert und einfügen:

#include <stdio.h> 
#include <stdlib.h> 

int main(void) { 

    int c, i, nwhite, nother; 

    int ndigit[10]; 

    nwhite = nother = 0; 

    for (i = 0; i < 10; ++i) { 

     ndigit[i] = 0; 

    } 

    while ((c = getchar()) != EOF) { 
     if (c >= '0' && c <= '9') 

      ++ndigit[c - '0']; 

     else if (c == ' ' /*|| c == '\n'*/|| c == '\t') 
      ++nwhite; 

     else 
      ++nother; 

    } 

    printf(" After "); 
    printf(" Var c %d \n", c); 
    printf(" Var i %d \n", i); 
    printf(" Var nwhite %d \n", nwhite); 
    printf(" Var nother %d \n", nother); 

    printf(" Digits are = "); 
    for (i = 0; i < 10; ++i) 
     printf(" %d ", ndigit[i]); 

    return EXIT_SUCCESS; 
} 

Wenn ich es laufen und geben Sie so etwas wie:

abc def ghi jkl 123

ich erhalten diese Ausgabe:

Nach Var c -1 Var i 10 Var nwhite 4 Var nher 13 Ziffern sind = 0 1 1 1 0 0 0 0 0 0

Mein Code unterscheidet sich nur vom Original in den letzten Zeilen Becose Ich benutze dieses printf, um den Wert der Variablen zu sehen.

Und das ich umbenennen/|| c == '\ n'/weil ich es nicht wie ein Weiß zählen möchte.

Der Rest denke ich, das ist gleich und scheint gut zu funktionieren, mag Buch Beispiel.

Frage:

Warum die Werte des Beispiels sie mir erzählen?

Meine Frage ist, dass ich nicht diese Ausgabemittel verstehen, oder dass es auf die Informationen, die ich habe eingegeben bezogen werden:

Input: abc def ghi jkl 123

Ausgang: Digits sind = 0 1 1 1 0 0 0 0 0 0

Final:

ich an dieser Stelle eine Erklärung zu schätzen wissen würde, dass das Buch für meinen nicht klar ist und keine Ich verstehe wirklich, dass diese Werte zeigen.

Added 2014.05.06:

Lösung meines Zweifels.

Firts

Als erstes habe ich allen danken für ihre Hilfe bei der Frage (Links des Buches) wollen, dachte ich, es in der Öffentlichkeit war. Ich werde dies für zukünftige Post berücksichtigen.

Vielen Dank an: WhozCraig und Amir für ihren unschätzbaren Input und dank ihnen endlich in der Lage, die Übung zu verstehen.

Und natürlich, um sicherzustellen, habe ich verstanden, der nächste Schritt Überprüfung durchzuführen, die zukünftige Leser helfen angebracht Beitrag zu klären:

Um sicherzustellen, dass ich verstand ich den folgenden Test gemacht:

In diesem neuen Fall führen wir die folgende Reihe ein;

ab cd ef gh 1234136 
After Var c -1 
Var i 10 
Var nwhite 4 
Var nother 9 
Digits = 0 2 1 2 1 0 1 0 0 0 

Und in der Tat die 0, und jetzt WHE haben 2 (Einer) 1 (zwei) 2 (zu dritt) 1 (vier), habe ich absichtlich weggelassen fünf auf die Überprüfung 0 (Fünfer ist OK) und schließlich 1 (sechs), und das nächste für 7,8 und 9 sind empy.

Das ist !!!

+2

+1 für K & R und eine klare erste Frage – timgeb

+1

Ich bezweifle ernsthaft, dass die Herausgeber von K & R2 die Erlaubnis gegeben haben, dass ihr Buch kostenlos veröffentlicht wird. Ich habe den Link von Ihrer Frage gelöscht. (Das gepostete PDF lässt den ursprünglichen Copyright-Hinweis des Buches weg.) –

+2

So wie ich Kernighan & Ritchie respektiere, denke ich, dass dieser Code ernsthaft geschweifte Klammern benötigt. –

Antwort

2

Analyse der Ausgabe:

After Var c -1 Var i 10 Var nwhite 4 Var nother 13 Digits are =0 1 1 1 0 0 0 0 0 0 
  • c -1: Sie fertig Ihre Lese-Schleife mit c zu EOF gleich, die auf Ihrer Plattform -1 ist.
  • i 10: Die Schleife for (i = 0; i < 10; ++i) brach, als i < 10 nicht mehr wahr war. Das letzte Mal, als es berührt wurde, war das letzte Inkrement ++i, das i als 10 verursachte und seither nicht mehr berührt wurde.
  • nwhite 4: Es gibt vier Leerzeichen nicht-Newline (weil Sie es eliminiert) Zeichen in der Zeichenfolge Sie gemacht haben: abc def ghi jkl 123
  • nother 13: Die Neue-Zeile als „andere“ char pro Ihre Modifizierung gezählt wird, die Ziffern sind nicht . Daher sind abcdefghijkl\n die dreizehn Werte, die zu dieser Akkumulation beigetragen haben.

, dass der letzte Punkt lässt:

Digits are =0 1 1 1 0 0 0 0 0 0 

Wie Sie die Eingangsdaten Schleife gehen durch, wenn eine Ziffer char ('0'..'9') angetroffen wird, dessen ASCII-Wert (oder, wenn Sie laufen eine iSeries oder zSeries, deren EBCDIC-Wert), erzeugt abzüglich des Wertes des char '0' einen nullbasierten Index in einem Array von 10 ganzen Zahlen. Dies funktioniert, weil der Standard erfordert, dass jeder dieser Codepunkte für die Ziffernzeichen sequenziell und zusammenhängend ist, und alle Plattformen (einschließlich EBCDIC) beachten dies. Der Zähler an diesem Index in dem Array wird mit jeder Begegnung des entsprechenden Ziffernzeichens inkrementiert. Wenn der Vorgang beendet ist, wird der resultierende Array-Inhalt in stdout ausgegeben. Sie hatten jeweils eine Ziffer '1', '2' und '3'. Der erste Schlitz im Array für '0' ist, die nächste für '1', etc .. Die 0 1 1 1 ... stellt die Anzahl der Nullen, Einsen, Zweien, Dreien, usw.

Für weitere Informationen über ASCII-Wert see this table. Wenn so geneigt, die Unterschiede mit EBCDIC zu sehen, see this table, und beachten Sie, dass in beiden, obwohl unterschiedliche tatsächliche numerische Werte, die vollständige Sequenz '0'..'9' zusammenhängend ist.

Hoffe, dass hilft. Gut produzierte Frage, übrigens. Besonders für deinen ersten Post.

+0

Vielen Dank für Ihre perfekte detaillierte Erklärung sowie ich konnte zuerst verstehen. Leider finde ich das Buch trotz ein Meisterwerk zu sein, habe ich einige dunkle Bereiche. – jsampedro

1

Ich lese gerade dieses Buch und hier ist, wie ich das verstehe.

Die Ausgabe, Sie werden immer korrekt ist:

c = -1 weil die while-Schleife beendet werden, wenn (c = getchar()) erreicht EOF (wohl wissend, dass EOF gleich bis -1), und denken Sie daran, dass Sie die getchar sind Speichern() in c vor dem Vergleich mit EOF seit Klammern haben höhere Priorität. Daher hat die Bedingung: c = EOF, dann vergleicht sie getchar() mit EOF und tritt aus der while-Schleife

i = 10, weil Sie mit einer for-Schleife werden Looping, und wenn i 10 erreicht sollte es stoppen. So letzte Wertspeicher in i ist 10.

0 1 1 1 0 0 0 0 0 0 

Mittel haben Sie

0 Zero 
1 ONE 
1 TWO 
1 THREE 
0 FOUR 
etc... 

PS: Es ist ein großartiges Buch !!

+0

Vielen Dank für Ihre perfekte detaillierte Erklärung sowie ich konnte zuerst verstehen. Leider finde ich das Buch trotz ein Meisterwerk zu sein, habe ich einige dunkle Bereiche. – jsampedro