2013-05-06 7 views
8

Ich bin neu in der Programmierung und beginne mit Objective-C, habe aber beschlossen, zu den Grundlagen zurückzukehren, bevor ich weiterarbeite. Ich verbringe etwas Zeit mit C und kämpfe mich durch die Verwirrung der Zeiger. Meine Frage ist, wie K & R sagt, fgets ist implementiert (P165, 2. Ausgabe). Code unten ist direkt aus dem Text mit ein paar meiner Kommentare.fgets implementation (K & R)

1) Wir übergeben ein char * s an die fgets-Funktion, an deren Speicherort wir die Benutzereingabe speichern. Warum müssen die lokalen char * cs deklariert werden - und dann mit s initialisiert werden? Warum können wir innerhalb der if-Anweisung nicht direkt s manipulieren/hinzufügen? Da cs zu Punkt s initialisiert wird, werden die Zeichen nicht genau zu cs hinzugefügt?

2) Eingeschlossen mit dem obigen ... Wenn die Funktion zurückkehrt, wird ein Test durchgeführt, um zu sehen, ob cs == s ist. Warum ist das notwendig?

Ich denke, dass ich etwas sehr grundlegendes vermisse - ich habe SO und Google überprüft, aber kann es nicht ganz herausfinden. Vielen Dank!

+2

"beginnen mit Objective-C, aber haben beschlossen, zurück zu den Grundlagen zu gehen, bevor sie weiter voranschreiten" - ausgezeichnet, ** jeder Anfänger sollte das tun. ** –

+1

Ich habe gerade begonnen zu fühlen, wie ich eine Spur von Arten in Obj-C. Seit ich wieder bei C bin, fühle ich mich wieder wie ein kompletter Klutz, aber obwohl ich mich wiederholt gegen Segmentierungsfehler und seltsames Programmverhalten stemme, ist es definitiv die Mühe wert. – drjimmie1976

+0

Es ist es auf jeden Fall wert. Mastering C ist unausweichlich, um Objective-C zu verstehen. –

Antwort

7

Es ist wegen der Überprüfung der letzten Zeile, cs == s. Dieser Vergleich prüft den modifizierten Zeiger cs gegen das Original s, um zu sehen, ob wir irgendein Zeichen gelesen haben. Wenn nicht, geben wir NULL zurück.

Durch Verwendung von cs im gesamten ursprünglichen Zeiger s bleibt erhalten. Wenn s direkt manipuliert würde (*s++ anstelle von *cs++), müssten wir einen anderen Weg finden, um zu überprüfen, ob irgendwelche Zeichen gelesen wurden.

Man kann auch argumentieren, dass es eine gute Übung ist, Funktionsparameter in Ruhe zu lassen und sie als const zu behandeln. Einige Programmierer folgen dieser Praxis, um die Code-Klarheit zu verbessern.

+0

Vielen Dank John. Das macht die Absicht klarer, aber ein paar mehr Fragen, wenn ich ... wenn 'cs' mit 'cs = s' zugewiesen wird, dachte ich, dass die Zeiger jetzt auf genau den gleichen Bereich des Gedächtnisses zeigen; daher wäre die Ausführung von '* cs ++' genau gleich '* s ++'. Ist diese Annahme falsch? – drjimmie1976

+0

Entschuldigen Sie, dass mein Kommentar abgelaufen ist, und mache Kommentarmarkierung falsch. Deshalb habe ich die letzte Zeile nicht verstanden. Ich dachte, dass beide Zeiger identisch wären, wenn sie beide "sharen", dann wären sie identisch, wenn der Ausdruck c == cs evaluiert wurde. Danke im Voraus. – drjimmie1976

+0

@ GasMan14 Sie zeigen nach der Zuweisung auf die gleiche Adresse, das ist richtig. '* cs ++' ändert jedoch 's' nicht. Stellen Sie sicher, dass Sie den Vorrang verstehen: '* cs ++' ist gleich '* (cs ++)' not '(* cs) ++'. 'cs ++' inkrementiert 'cs', so dass es auf die nächste Adresse zeigt, dann auf die' * 'Dereferenzierungen, die adressieren. 's' wird nicht geändert, weil' s' und 'cs' zwei getrennte Variablen sind. Wenn die Anweisung stattdessen "(* cs) ++" wäre, dann würde * * den Wert von "* s" ändern. (Wohlgemerkt, nicht "s", sondern "s".) –