[Powered by Google Translate] [§ 6] [Mehr Komfortable]
[Rob Bowden] [Harvard University]
[Dies ist CS50.] [CS50.TV]
>> Wir können unserer Sektion der Fragen leiten.
Ich habe die URL für den Raum vor.
Der Beginn des Abschnitts der Fragen sagen
anscheinend bin ich nicht ganz unsick-ist eine sehr einfache Frage
nur was valgrind?
Was bedeutet valgrind tun?
Wer will sagen, was valgrind tut?
[Student] Checks Speicherlecks.
Ja, das ist valgrind eine allgemeine Speicher checker.
It, am Ende erfahren Sie, ob Sie Speicherlecks haben,
das ist meist, was wir verwenden es für denn wenn du willst
gut in das Problem Satz oder wenn Sie wollen
Sie auf der großen Tafel, müssen Sie keine Speicherlecks überhaupt haben,
und im Fall müssen Sie einen Speicherverlust, dass Sie nicht finden können,
auch im Hinterkopf behalten, dass, wenn Sie eine Datei öffnen
und wenn man nicht schließen, ist das ein Speicherverlust.
>> Eine Menge Leute sind für einige Knoten suchen, dass sie nicht befreien
wenn wirklich, sie haben nicht schließen das Wörterbuch in der allererste Schritt.
Darüber hinaus erfahren Sie, wenn Sie ungültige müssen liest oder schreibt,
was bedeutet, wenn Sie versuchen, einen Wert
das ist über das Ende des Haufens und es nicht zu seg Fehler passieren
aber valgrind fängt es, wie sollte man eigentlich nicht dort schreiben,
und damit Sie sollten auf jeden Fall keine der von denjenigen.
Wie verwenden Sie Valgrind?
>> Es ist eine allgemeine Frage
Art ausführen und schauen Sie sich die Ausgabe.
Der Ausgang ist überwältigend viele Male.
Es macht auch Spaß, Fehler, wo, wenn Sie etwas schrecklich falsch, was
geschieht in einer Schleife, dann wird es irgendwann sagen: "Viel zu viele Fehler.
Ich werde aufhören zu zählen jetzt. "
Es ist im Grunde Textausgabe, die Sie analysieren müssen.
Am Ende wird es Ihnen sagen keine Speicherlecks, die Sie haben,
wie viele Blöcke, die kann nützlich sein, weil
wenn es einen Block unfreed ist, dann ist es in der Regel einfacher zu finden
als 1.000 Blöcke unfreed.
1.000 Blöcke unfreed bedeutet wahrscheinlich, du bist nicht befreien
Ihre verkettete Listen angemessen oder so etwas.
Das ist valgrind.
>> Jetzt haben wir unserer Sektion der Fragen,
die Sie brauchen nicht zu downloaden.
Sie können auf meinen Namen klicken und ziehen Sie sie in den Raum.
Jetzt auf mich klicken.
Revision 1 wird Stapel, die wir tun, das erste mal sein.
Revision 2 wird Warteschlange und Revision 3 wird das einfach verkettete Liste.
Beginnend mit unserem Stack.
Wie es hier heißt, ist ein Stapel eines der grundlegenden,
grundlegende Datenstrukturen der Informatik.
Die sehr prototypischen Beispiel ist
der Stapel von Ablagen in den Speisesaal.
Es ist im Grunde, wenn Sie an einem Stapel eingeführt werden,
wird jemand sagen: "Oh, wie ein Stapel von Tabletts."
Sie stapeln die Schalen auf.
Dann, wenn Sie gehen, um ein Fach zu ziehen,
das erste Fach, das immer gezogen hat ist die letzte, die auf den Stapel gelegt wurde.
Der Stack auch-wie es heißt hier-
haben wir das Segment des Speichers genannt Stack.
Und warum heißt es der Stapel?
>> Denn wie ein Stapel Datenstruktur,
es drückt und öffnet Stack-Frames auf dem Stack,
wo Stack-Frames sind wie ein spezieller Aufruf einer Funktion.
Und wie ein Stapel, werden Sie immer wieder
von einem Aufruf der Funktion, bevor Sie runter in die untere Stack-Frames wieder.
Sie können nicht Hauptrufnummer foo Anruf Bar und Bar zurück zur Hauptseite direkt.
Es bekam immer den richtigen Stapel schieben und knallen folgen.
Die beiden Operationen, wie ich schon sagte, sind Push-und Pop.
Das sind universelle Begriffe.
Sie sollten wissen, Push-und Pop in Bezug auf die Stapel, egal was.
Wir werden sehen, Warteschlangen sind irgendwie anders.
Es ist nicht wirklich eine universelle Begriff, aber Push-und Pop sind universell für Stacks.
Push ist nur auf den Stapel gelegt.
Pop ist nehmen Sie den Stapel.
Und wir sehen, hier haben wir unsere typedef struct stack,
so haben wir char ** Saiten.
Lassen Sie sich nicht Angst durch irgendwelche **.
Das wird am Ende wird ein Array von Strings
oder eine Anordnung von Zeigern auf Zeichen, wobei
Zeiger auf Zeichen neigen dazu, Strings sein.
Es muss nicht Strings sein, aber hier, sie gehen zu Strings sein.
>> Wir haben ein Array von Strings.
Wir haben eine Größe, die wie viele Elemente sind derzeit auf dem Stapel repräsentiert,
und dann haben wir die Kapazität, die, wie viele Elemente auf dem Stack zu sein.
Die Kapazität sollte starten als etwas, das größer ist als 1,
aber die Größe wird starten als 0 ist.
Nun gibt es grundsätzlich drei verschiedene Möglichkeiten, wie Sie aus einem Stapel denken kann.
Nun, es gibt wahrscheinlich mehr, aber die beiden wichtigsten Wege sind
Sie implementieren können, es mit einem Array, oder Sie können es umsetzen mit einer verketteten Liste.
Verkettete Listen sind irgendwie trivial zu Stapeln aus zu machen.
Es ist sehr einfach, einen Stapel mit verknüpften Listen zu machen,
so hier, wir gehen, um einen Stapel zu machen Verwendung von Arrays
und dann mit Arrays, gibt es auch zwei Möglichkeiten, wie Sie darüber denken.
Früher, als ich sagte, wir haben eine Kapazität für den Stack,
so können wir ein Element auf dem Stapel passen.
>> Der einzige Weg es passieren könnte, ist, sobald Sie 10 Elemente treffen, dann sind Sie fertig.
Sie wissen vielleicht, dass es eine Obergrenze von 10 Dinge in der Welt gebunden
dass Sie nie mehr als 10 Sachen auf dem Stapel,
in diesem Fall können Sie eine Obergrenze für die Größe Ihres Stacks gebunden.
Oder Sie könnten Ihren Stack unbegrenzt sein kann,
aber wenn du eine Reihe bist, bedeutet das, dass jedes Mal, wenn Sie 10 Elemente treffen,
dann sind Sie gehen zu müssen, zu 20 Elementen wachsen, und wenn man 20 Elemente treffen,
Sie gehen zu müssen, um das Array zu 30 Elementen oder 40 Elementen wachsen.
Sie gehen zu müssen, um die Kapazität, die, was wir hier zu tun ist, zu erhöhen.
Jedes einzelne Mal, erreichen wir die maximale Größe der Stapel,
wenn wir etwas anderes auf schieben, wir gehen zu müssen, um die Kapazität zu erhöhen.
Hier haben wir Vorstoß als bool push (char * str) erklärt.
Char * str ist die Zeichenkette, die wir auf den Stapel schieben,
und bool sagt nur, ob wir erfolgreich war oder fehlgeschlagen ist.
>> Wie können wir scheitern?
Was ist der einzige Umstand, dass Sie sich vorstellen können
wo wir müssten wieder falsch?
Yeah.
[Student] Wenn er voll ist und wir mit einem begrenzten Umsetzung.
Ja, so wie definieren wir-antwortete er
wenn es voll und wir verwenden eine beschränkte Umsetzung.
Dann werden wir auf jeden Fall wieder falsch.
Sobald wir 10 Dinge, traf im Array, können wir nicht für 11, so dass wir false zurück.
Was, wenn es unbegrenzt ist? Yeah.
Wenn Sie sich nicht erweitern das Array aus irgendeinem Grund.
Ja, das ist so viel Speicher eine begrenzte Ressource,
und schließlich, wenn wir pushen Dinge auf den Stapel immer und immer wieder,
wir gehen, um zu versuchen und weisen eine größere Array passen
die größere Kapazität und malloc oder was auch immer wir verwenden wird false zurück.
Nun, malloc null zurück.
>> Denken Sie daran, jedes einzelne Mal, wenn Sie immer rufen malloc, sollten Sie prüfen, ob es
gibt null oder anderes, das ist ein Richtigkeit Abzug.
Da wollen wir eine unbegrenzte Stapel haben,
der einzige Fall, wir werden wieder falsch sind, wenn wir versuchen,
Erhöhung der Kapazität und malloc oder was auch immer false zurück.
Dann pop hat keine Argumente,
und es gibt die Zeichenfolge, die auf dem oberen Ende des Stapels ist.
Was auch immer wurde zuletzt auf dem Stapel abgelegt ist, was Pop kehrt zurück,
und es auch entfernt es aus dem Stapel.
Und feststellen, dass es null zurückgibt, wenn es nichts auf dem Stapel.
Es ist immer möglich, dass der Stack leer ist.
In Java, wenn Sie zu, dass, oder anderen Sprachen verwendet,
versucht, aus einem leeren Stapel Pop könnte eine Ausnahme verursachen oder so etwas.
>> Aber in C ist null Art von einem Großteil der Fälle, wie wir diese Probleme in den Griff.
Wiederkehrende null ist, wie wir gehen zu bedeuten, dass der Stapel leer war.
Wir haben Code, Ihren Stack-Funktionalität testen wird zur Verfügung gestellt,
Umsetzung push und pop.
Dies wird nicht viel Code.
Ich will, eigentlich, bevor wir das tun, Wink mit dem Zaunpfahl-
wenn Sie es nicht gesehen haben, ist malloc nicht die einzige Funktion
das ordnet Speicher auf dem Heap für Sie.
Es gibt eine Familie von alloc Funktionen.
Die erste ist malloc, die Sie gewohnt sind.
Dann gibt es calloc, die die gleiche Sache wie malloc tut,
aber es wird auf Null alles für Sie heraus.
Wenn Sie jemals wollte alles auf null gesetzt, nachdem mallocing etwas
Sie sollten nur verwendet haben calloc in erster Linie anstelle des Schreibens
eine for-Schleife auf Null aus den gesamten Block des Speichers.
>> Realloc ist wie malloc und hat eine Menge von Sonderfällen
aber im Grunde, was realloc tut, ist
es braucht einen Zeiger, der bereits zugeteilt worden war.
Realloc ist die Funktion, die Sie werden die Aufmerksamkeit auf hier.
Es dauert einen Zeiger, der bereits von malloc zurückgegeben worden.
Angenommen, Sie verlangen von malloc einen Zeiger von 10 Byte.
Später merkt man, Sie wollten 20 Byte,
so rufen Sie realloc auf diesem Zeiger mit 20 Bytes,
und realloc wird automatisch über alles für Sie zu kopieren.
Wenn Sie gerade angerufen malloc wieder, wie ich einen Block von 10 Byte haben.
Jetzt brauche ich einen Block von 20 Bytes,
also wenn ich malloc 20 Bytes, dann muss ich manuell kopieren über die 10 Bytes aus der ersten Sache
in die zweite Sache, und dann frei die erste Sache.
Realloc wird das für Sie erledigen.
>> Beachten Sie die Signatur wird void * sein,
welches nur einen Zeiger auf den Speicherblock,
dann void * ptr.
Sie können von void * als generischer Zeiger denken.
Im Allgemeinen werden Sie nie Umgang mit void *,
aber malloc ist wieder ein void *, und dann ist es wie verwendet
dies ist eigentlich los, um ein char * sein.
Der bisherige void *, der von malloc zurückgegeben worden waren
wird nun auf realloc weitergegeben werden, und dann deine Größe
ist die neue Anzahl von Bytes, die Sie zuweisen möchten, so dass Ihre neue Kapazitäten.
Ich gebe Ihnen ein paar Minuten, und tun es in unserem Raum.
Beginnen Sie mit Revision 1.
Ich werde Sie nach hoffentlich stoppen genug Zeit, um Push zu implementieren,
und dann werde ich Ihnen eine Pause zu Pop zu tun.
Aber es ist wirklich nicht so viel Code.
Die meisten Code ist wahrscheinlich der Ausbau Zeug, die Erweiterung der Kapazität.
Okay, kein Druck vollständig durchgeführt werden,
aber so lange, wie Sie, wie Sie auf dem richtigen Weg sind zu fühlen, das ist gut.
>> Hat jemand Code, den sie sich wohl fühlen mit mir nach oben ziehen?
Ja, ich will, aber hat jemand einen Code Ich ziehe können?
Okay, können Sie beginnen, speichern Sie es, was es ist?
Ich vergesse immer, diesen Schritt.
Okay, Blick auf push,
wollen Sie Ihren Code erklären?
[Student] Zunächst erhöhte ich die Größe.
Ich denke, vielleicht sollte ich, daß-sowieso, erhöhte ich die Größe,
und ich sehe, wenn es weniger als die Kapazität ist.
Und wenn es weniger als die Kapazität ist, habe ich auf das Array, dass wir bereits hinzuzufügen.
Und wenn es nicht ist, multiplizieren ich die Kapazität von 2,
und ich umzuschichten die Saiten array etwas mit einer größeren Kapazität Größe jetzt.
Und dann, wenn das fehlschlägt, sage ich den Benutzer und false zurück,
und wenn es gut geht, dann habe ich den String in der neuen Stelle.
>> [Rob B.] Beachten Sie auch, dass wir eine schöne bitweisen Operator welche hier
um 2 multiplizieren.
Denken Sie daran, Linksverschiebung immer zu mit 2 multipliziert werden.
Verschiebung nach rechts durch 2 so lange unterteilt, wie erinnern Sie sich, dass es bedeutet,
durch 2 teilen, wie in einem ganzzahligen durch 2 geteilt.
Es könnte abschneiden ein 1 hier oder dort.
Aber Verschiebung um 1 nach links wird immer mit 2 multipliziert werden,
wenn Sie overflow die Grenzen des integer, und dann wird es nicht sein.
Eine Randnotiz.
Ich mag zu tun, das ist nicht zu ändern die Codierung irgendeiner Weise,
aber Ich mag so etwas wie dies zu tun.
Tatsächlich wird es etwas länger.
Vielleicht ist dies nicht die ideale Tasche, dies zu zeigen,
aber Ich mag um das Gesamtbild in diesen Blöcken of-
okay, wenn dies geschieht, wenn, dann werde ich etwas tun,
und anschließend die Funktion durchgeführt wird.
Ich brauche nicht, um dann blättern meinen Augen den ganzen Weg hinunter die Funktion
zu sehen, was passiert nach dem anderen.
Es ist, wenn dies geschieht, wenn, dann habe ich nur zurückgeben.
Es hat auch die schöne Zusatznutzen alles darüber hinaus
wird nun verschoben einmal links.
Ich weiß nicht mehr zu, wenn Sie jemals in der Nähe lächerlich langen Linien müssen,
dann werden diese 4 Bytes helfen kann, und auch der weiter links etwas ist,
desto weniger überfordert fühlen Sie sich, wenn wie-okay, ich mich zu erinnern haben,
Ich bin derzeit in einer while-Schleife innerhalb eines anderes in einer for-Schleife.
Anywhere können Sie diese Rückkehr sofort tun, ich mag.
Es ist völlig optional und nicht in irgendeiner Weise zu erwarten.
>> [Student] Sollte es eine groß sein - in den fehlersicheren Zustand?
Die fehlersicheren Zustand hier haben wir versäumt, realloc, also ja.
Beachten Sie, wie in den fehlersicheren Zustand, vermutlich
wenn wir free stuff später, sind wir immer zum Scheitern verurteilt
egal wie oft wir etwas drücken versuchen.
Wenn wir Druck zu halten, halten wir Inkrementieren Größe,
obwohl wir nicht setzen alles auf den Stapel.
Normalerweise haben wir nicht erhöhen die Größe, bis
nachdem wir erfolgreich legte sie auf den Stapel.
Wir würden es tun, sagen, entweder hier und hier.
Und dann, anstatt zu sagen s.size ≤ Kapazität, ist es weniger als die Kapazität,
nur weil wir, wo alles war bewegt.
>> Und denken Sie daran, der einzige Ort, dass wir möglicherweise return false
Hier, wo realloc zurückgegebene null,
und wenn Sie zufällig Standardfehler erinnern,
Vielleicht sollten Sie überlegen, diesen einen Fall, wo Sie ein Standard-Fehler drucken möchten,
so fprintf stderr statt nur Drucken direkt an die Standardausgabe.
Auch das ist nicht eine Erwartung, aber wenn es ein Fehler,
Geben printf, dann möchten Sie vielleicht, um es zu Standardfehler anstelle von Standard auszudrucken.
>> Wer noch etwas anderes zu beachten? Ja.
[Student] Können Sie über die [unverständlich] gehen?
[Rob B.] Ja, die eigentliche binariness es oder einfach nur was es ist?
[Student] So multiplizieren Sie ihn mit 2?
[Rob B.] Ja, im Grunde.
In binären Land, wir haben immer unsere Reihe von Ziffern.
Verschieben dieser nach links 1 Grunde fügt es hier auf der rechten Seite.
Zurück zu dieser, nur erinnern, dass alles in binärer
eine Potenz von 2, so stellt dies der 2 bis 0,
Das 2 zu 1, das 2 zum 2.
Durch Einfügen einer 0 auf der rechten Seite jetzt haben wir nur verschieben alles vorbei.
Was früher 2 sein, um die 0 2 ist nun auf die 1, 2 wird auf die 2.
Die rechte Seite, die wir eingefügt
wird notwendigerweise auf 0,
das macht Sinn.
Wenn Sie vermehren sich immer eine Zahl durch 2, ist es nicht zu Ende gehen bis ungerade,
so dass die 2 auf 0 statt 0 sein sollte,
und dies ist, was ich die Hälfte gewarnt vor, wenn Sie geschehen zu verschieben müssen
über die Anzahl der Bits in einer ganzen Zahl,
dann ist dies ein wird am Ende gehen aus.
Das ist die einzige Sorge, wenn Sie mit sehr großen Kapazitäten zu tun passieren.
Aber an diesem Punkt, dann sind Sie mit einer Reihe von Milliarden von Dingen zu tun haben,
die möglicherweise nicht in den Speicher sowieso passen.
>> Jetzt können wir zu Pop, die sogar leichter zu bekommen.
Man könnte sie es mögen, wenn Sie eine ganze Reihe Pop passieren,
und jetzt bist du bei halber Kapazität wieder.
Sie könnten realloc die Menge an Speicher haben Sie schrumpfen,
aber Sie haben keine Sorgen zu machen, ist so die einzige realloc Fall sein wird
wachsenden Speicher niemals schrumpfenden Speicher,
was geht, um pop super einfach.
Jetzt Warteschlangen, die gehen wie Stacks sein sollen,
aber die Reihenfolge, dass Sie die Dinge nehmen umgekehrt.
Das prototypische Beispiel einer Warteschlange ist eine Linie,
so dass ich denke, wenn Sie Englisch waren, hätte ich gesagt,
ein prototypisches Beispiel einer Warteschlange ist eine Warteschlange.
So wie eine Linie, wenn Sie die erste Person in der Linie,
Sie erwarten, dass die erste Person aus der Leitung sein.
Wenn Sie die letzte Person im Einklang sind, wirst du die letzte Person gewartet werden.
Wir nennen das FIFO-Muster, während Stapel war LIFO-Muster.
Diese Worte sind ziemlich universal.
>> Wie stapelt und im Gegensatz zu Arrays, Warteschlangen in der Regel keinen Zugang zu Elementen in der Mitte.
Hier ein Stapel, haben wir Push-und Pop.
Hier passieren wir nannten sie haben Enqueue und dequeue.
Ich habe auch gehört, wie sie genannt Verschiebung und unshift.
Ich habe Leute sagen hören Push-und Pop auch Warteschlangen gelten.
Ich habe gehört, einfügen, entfernen,
so push und pop, wenn Sie über Stacks sprechen, Sie drängen und knallen.
Wenn Sie über Warteschlangen sprechen, könnten Sie holen die Wörter, die Sie verwenden möchten
zum Einsetzen und Herausnehmen, und es gibt keinen Konsens darüber, was es aufgerufen werden soll.
Aber hier haben wir Enqueue und dequeue.
Nun sieht die Struktur fast identisch zu dem Stapel Struct.
Aber wir haben den Überblick über Kopf zu bewahren.
Ich denke, es sagt hier unten, aber warum brauchen wir den Kopf?
Die Prototypen sind im Grunde identisch mit push und pop.
Sie können es als Push-und Pop denken.
Der einzige Unterschied ist Pop kehrt zurück-statt des letzten, es ist wieder die erste.
2, 1, 3, 4, oder so etwas.
Und hier ist der Anfang.
Unsere Warteschlange vollständig gefüllt ist, so gibt es vier Elemente.
Das Ende unserer Warteschlange aktuell 2,
und jetzt gehen wir auf etwas anderes einfügen.
>> Wenn wir wollen, dass etwas anderes, was wir getan haben für den Stack-Version einfügen
ist haben wir unser Block des Speichers.
Was ist das Problem mit diesem?
[Student] bewegen Sie den 2.
Was ich sagte, bevor über das Ende der Warteschlange,
dies nicht sinnvoll, dass wir beginnen bei 1,
dann wollen wir dequeue 1, dann dequeue 3, dann dequeue 4,
dann dequeue 2, dann aus der Warteschlange entfernt diese.
Wir können nicht realloc jetzt
oder zumindest muss man realloc in einer anderen Weise zu nutzen.
Aber man sollte wohl nicht einfach realloc.
Sie gehen zu müssen, um manuell kopieren Sie Ihr Gedächtnis.
>> Es gibt zwei Funktionen in den Speicher kopieren.
Es gibt bezüglich memcopy und memmove.
Ich bin derzeit Lesen der Manpages zu sehen, welche Sie gehen zu wollen, zu verwenden.
Okay, bezüglich memcopy, ist der Unterschied
dass bezüglich memcopy und memmove, ein behandelt den Fall richtig
wo Sie in eine Region, die Region überschneiden passiert Kopieren
Sie zu kopieren.
Bezüglich memcopy nicht umgehen. Memmove tut.
Sie können das Problem wie-denken
sagen wir, ich will diesen Kerl zu kopieren,
diese vier zu diesem Kerl vorbei.
Am Ende, was das Array aussehen sollte
nachdem die Kopie 2, 1, 2, 1, 3, 4, und dann ein paar Sachen am Ende.
Aber dies ist abhängig von der Reihenfolge, in der wir tatsächlich zu kopieren,
denn wenn wir nicht die Tatsache berücksichtigen, dass die Region sind wir in Kopie
Überschneidungen die wir zu kopieren sind,
dann könnten wir wie Start hier tun, kopieren Sie die 2 in den Ort, den wir gehen wollen,
dann bewegen wir Zeiger vorwärts.
>> Jetzt werden wir hier und hier zu sein, und jetzt wollen wir zu kopieren
dieser Kerl über diesen Kerl und bewegen unsere Zeiger vorwärts.
Was werden wir am Ende immer für 2, 1, 2, 1, 2, 1
anstelle der entsprechenden 2, 1, 2, 1, 3, 4, weil
2, 1 overrode die ursprüngliche 3, 4.
Memmove übernimmt das richtig.
In diesem Fall, im Grunde nur immer memmove
weil es handhabt es richtig.
Es wird allgemein führt keine schlimmer.
Die Idee ist, anstelle vom Beginn und Kopieren auf diese Weise
wie wir gerade hier, beginnt es ab dem Ende und kopiert in,
und in diesem Fall, können Sie nie ein Problem.
Es wird keine Leistung verloren.
Immer memmove. Nie über bezüglich memcopy kümmern.
Und das ist, wo Sie gehen zu müssen separat memmove sind
das verpackte-around Teil Ihrer Warteschlange.
Keine Sorge, wenn nicht vollständig durchgeführt.
Das ist schwieriger als Stapel, Push und Pop.
>> Wer noch keine Codes mit denen wir arbeiten können?
Auch wenn völlig unvollständig?
[Student] Ja, es ist völlig unvollständig, though.
Vollständig unvollständig ist in Ordnung, solange wir können, speichern Sie die Revision?
Ich vergesse, dass jede einzelne Zeit.
Okay, zu ignorieren, was passiert, wenn wir die Dinge ändern müssen.
Völlig ignorieren resize.
Erklären Sie diesen Code.
Ich zunächst überprüft wird, ob die Größe geringer ist als die Kopie zunächst
und dann nach, dass ich Insert-Ich nehme den Kopf + Größe,
und I sicherzustellen, dass es umschlingt die Kapazität des Arrays,
und ich legen Sie die neue Zeichenfolge an dieser Position.
Dann erhöhe ich die Größe und true zurückgeben.
>> [Rob B.] Dies ist definitiv einer jener Fälle, wo Sie gehen zu wollen, werden mit mod sind.
Jede Art von Fall, wo man Umwickeln haben, wenn man sich Einwickeln denken,
die sofortige Gedanke sollte mod sein.
Als schnelle Optimierung / Ihr Code eine Zeile kürzer,
Sie bemerken, dass die Zeile unmittelbar im Anschluss an diese ein
ist nur die Größe + +, so dass Sie zusammenführen, in dieser Linie, Größe + +.
Jetzt hier unten, haben wir den Fall
wo wir nicht über genügend Speicher,
so erhöhen wir unsere Kapazität um 2.
Ich denke, man könnte das gleiche Problem hier, aber wir können es jetzt zu ignorieren,
wo, wenn Sie nicht auf Ihre Kapazität zu erhöhen,
dann sind Sie gehen zu wollen, um Ihre Kapazität um 2 wieder ab.
Noch ein kurzer Hinweis ist wie Sie tun können, + =,
können Sie auch tun << =.
Fast alles kann gehen, bevor entspricht, + =, | =, & =, << =.
Char * neu ist unsere neue Block des Speichers.
Oh, hier drüben.
>> Was tun die Menschen über die Art unserer neuen Block des Speichers denken?
[Student] Es sollte char ** sein.
Denken wir zurück an unseren struct hier oben,
Strings ist, was wir Umschichtung.
Wir machen eine gesamte neue dynamische Speicher für die Elemente in der Warteschlange.
Was wir auf Ihre Saiten werden Zuweisung ist das, was wir gerade mallocing,
und so neue wird ein char ** sein.
Es wird ein Array von Strings sein.
Was ist dann der Fall, unter denen wir false zurück sind?
[Student] Sollten wir tun das char *?
[Rob B.] Ja, guten Ruf.
[Student] Was war das?
[Rob B.] Wir wollten Größe char * zu tun, weil wir nicht länger-
dies wäre eigentlich ein sehr großes Problem sein, weil sizeof (char) 1 wäre.
Sizeof char * wird 4 sein,
so eine Menge Zeit, wenn Sie mit ints tun haben,
Sie neigen dazu, weg mit ihm, weil Größe int und Größe des int *
auf einem 32-Bit-System gehen, um die gleiche Sache zu sein.
Aber hier, sizeof (char) und sizeof (char *) werden nun dasselbe sein.
>> Was ist der Umstand, wo wir wieder falsch?
[Student] Neu ist null.
Ja, wenn neue null ist, kehren wir falsch,
und ich werde zu werfen hier unten
[Student] [unverständlich]
[Rob B.] Ja, das ist in Ordnung.
Sie könnten entweder 2 mal Nutzlast oder Schicht 1 und dann nur setzte es hier oder was auch immer.
Wir machen es wie wir sie hatten.
Kapazität >> = 1.
Und du wirst nie über den Verlust der 1 Platz Sorgen
weil dich verlassen verschoben um 1, so ist der 1 Platz ist notwendigerweise eine 0,
so Rechtsverschiebung um 1, du bist immer noch in Ordnung zu sein.
[Student] Müssen Sie, dass vor der Rückkehr zu tun?
[Rob B.] Ja, macht das überhaupt keinen Sinn.
>> Jetzt gehen wir davon aus, um am Ende wieder treu Ende sind.
Die Art und Weise wir diese memmoves erleben
wir müssen, wie wir sie tun vorsichtig.
Hat jemand irgendwelche Vorschläge, wie wir sie?
Hier ist unser Start.
Zwangsläufig, wollen wir wieder am Anfang beginnen
und kopieren Dinge von dort, 1, 3, 4, 2.
Wie machst du das?
Zuerst habe ich auf der Manpage memmove wieder anzusehen.
Memmove ist Reihenfolge der Argumente immer wichtig.
Wir wollen unser Ziel erste, Quelle Sekunden, Größe Drittel.
Es gibt eine Vielzahl von Funktionen, die Quell-und Ziel umzukehren.
Destination, Quelle neigt dazu, im Einklang etwas.
Move, was ist es zurück?
Es gibt einen Zeiger zum Ziel, aus welchem ​​Grund möchten Sie vielleicht, dass.
Ich kann Bild lesen, aber wir wollen in unserem Ziel zu bewegen.
>> Was ist unser Ziel los zu werden?
[Student] Neu.
[Rob B.] Ja, und wo sind wir Kopieren von?
Die erste Sache, die wir kopieren, ist dies 1, 3, 4.
Was ist dass für diese 1, 3, 4.
Wie lautet die Adresse des 1?
Wie ist die Adresse dieses 1?
[Student] [unverständlich]
[Rob B.] Head + die Adresse des ersten Elements.
Wie bekommen wir das erste Element im Array?
[Student] Queue.
[Rob B.] Ja, q.strings.
Denken Sie daran, hier ist unser Kopf 1.
So ein Mist. Ich denke, es ist magisch
Hier ist unser Kopf 1. Ich werde meine Farbe zu ändern.
Und hier ist Saiten.
Dies können wir entweder schreiben sie, als wir über hier getan hat
mit Köpfen + q.strings.
Eine Menge Leute auch schreiben it & q.strings [head].
Dies ist nicht wirklich weniger effizient.
Man könnte daran denken, wie Sie Dereferenzierung es werden und dann immer die Adresse,
aber der Compiler wird es zu dem, was wir vorher hatten übersetzen sowieso q.strings + Kopf.
Wie auch immer Sie möchten, daran zu denken.
>> Und wie viele Bytes wollen wir kopieren?
[Student] Kapazität - Kopf.
Kapazität - Kopf.
Und dann könnte man immer schreiben, ein Beispiel
um herauszufinden, ob das stimmt.
[Student] Es muss durch 2 dann aufgeteilt werden.
Yeah, so dass ich denke, wir könnten Größe zu verwenden.
Wir haben immer noch groß ist-
Verwendung Größe haben wir eine Größe gleich 4 ist.
Unsere Größe ist 4. Unser Kopf ist 1.
Wir wollen diese 3 Elemente kopieren.
Das ist die Plausibilitätsprüfung, dass die Größe - Kopf ist richtig 3.
Und immer wieder hier, wie wir schon sagten,
wenn wir ausgelastet, dann müssten wir durch 2 dividieren
weil wir bereits unsere Kapazitäten sind gewachsen, so dass anstelle, werden wir Größe zu verwenden.
Dass Kopien dieser Abschnitt.
Nun müssen wir den anderen Teil, dem Abschnitt, der von dem Start verbleibt kopieren.
>> Das wird in welcher Position memmove?
[Student] Plus size - Kopf.
Ja, so haben wir bereits in der Größe kopiert - Kopf Bytes,
und so, wo wir wollen die restlichen Bytes kopieren ist neu
und dann deine Größe minus-gut, die Anzahl der Bytes haben wir bereits kopiert in.
Und dann, wo wir das Kopieren von?
[Student] Q.strings [0].
[Rob B.] Ja, q.strings.
Wir könnten entweder & q.strings [0].
Dies ist deutlich weniger häufig als diese.
Wenn es nur geht auf 0, dann werden Sie neigen dazu, q.strings sehen.
Das ist, wo wir vom Kopieren sind.
Wie viele Bytes bleibt uns zu kopieren? >> [Student] 10.
Right.
[Student] Haben wir bis 5 vermehren - 10 mal so groß wie der Bytes oder so etwas?
Ja, so ist dies, wo-was genau wir kopieren?
[Student] [unverständlich]
Was ist die Art der Sache sind wir kopieren?
[Student] [unverständlich]
Yeah, so der char * s, die wir kopieren, wissen wir nicht, wo die herkommen.
Nun, wo sie auf den Hinweis, wie die Saiten, landen wir schieben es auf der Warteschlange
oder Einreihen in die Warteschlange.
Wo die herkommen, haben wir keine Ahnung.
Wir brauchen nur den Überblick über die char * s sich zu behalten.
Wir wollen nicht auf Größe kopieren - Kopf Bytes.
Wir wollen die Größe kopieren - Kopf char * s,
so werden wir dies durch sizeof (char *) zu multiplizieren.
Same hier unten, Kopf * sizeof (char *).
>> [Student] Was [unverständlich]?
Das hier?
[Student] Nein, unten, dass die Größe - Kopf.
[Rob B.] Das hier?
Pointer-Arithmetik.
Wie Zeigerarithmetik funktionieren wird ist
sie automatisch multipliziert mit der Größe des Typs, der wir es zu tun.
Genau wie hier, neue + (Größe - Kopf)
entspricht genau & new [size - Kopf]
bis wir erwarten, dass um korrekt zu arbeiten,
denn wenn wir mit einem int-Array zu tun haben, dann tun wir nicht Index int-
oder wenn sie von der Größe von 5 ist, und Sie wollen, dass die vierte Element, dann werden wir Index in der
int array [4].
Sie dont-[4] * Größe der int.
Das erledigt das automatisch, und dieser Fall
ist buchstäblich gleichwertig, so dass die Klammer-Syntax
ist gerade dabei, dies umgesetzt, sobald Sie zu kompilieren.
Das ist etwas, das Sie brauchen, um vorsichtig sein, dass
beim Hinzufügen size - Kopf
Sie hinzufügen nicht ein Byte.
Sie fügen ein char *, was kann ein Byte oder was auch immer.
>> Weitere Fragen?
Okay, ist dequeue einfacher sein.
Ich gebe dir eine Minute zu implementieren.
Oh, und ich denke, das ist die gleiche Situation, wo
was die Enqueue Fall, wenn wir Einreihen null,
vielleicht können wir damit umgehen wollen, vielleicht tun wir nicht.
Wir werden es nicht wieder tun hier, aber wie unser Stack Fall.
Wenn wir null einreihen, könnten wir wollen es zu ignorieren.
Wer noch etwas Code Ich ziehe können?
[Student] Ich habe nur dequeue.
Version 2 ist, dass-okay.
Sie wollen zu erklären?
[Student] Erstens, stellen Sie sicher, es ist etwas in der Warteschlange
und dass die Größe wird um 1.
Sie müssen das tun, und dann wieder den Kopf
und bewegen Sie den Kopf ein.
Okay, so gibt es eine Ecke Fall müssen wir berücksichtigen. Yeah.
[Student] Wenn Ihr Kopf ist das letzte Element,
dann müssen Sie nicht möchten Kopf außerhalb des Feldes zu verweisen.
>> Ja, dies so bald wie Kopf trifft das Ende unserer Array
wenn wir aus der Warteschlange entfernt, sollte unser Kopf zurück auf 0 modded werden.
Leider können wir nicht tun, dass in einem Schritt.
Ich denke, die Art, wie ich wohl beheben würde es
dies wird ein char * sein, was wir zurückkehren,
was auch immer Ihre Variablenname sein will.
Dann wollen wir den Kopf durch unsere Fähigkeit mod
und dann wieder ret.
Eine Menge Leute hier, sie tun könnten-
Dies ist der Fall-Sie sehen, wie Menschen tun, wenn Kopf
ist größer als die Kapazität, tun Kopf - Kapazität.
Und das ist nur arbeiten um was mod ist.
Leiter mod = Kapazität ist viel sauberer
einer Umwicklung als ob der Kopf größer ist als die Kapazität Kopf - Kapazität.
>> Haben Sie Fragen?
Okay, das ist das letzte, was wir noch haben uns verlinkten Liste.
Sie könnten einige der verketteten Liste Verhalten verwendet werden, wenn Sie getan haben
verkettete Listen in Ihrem Hash-Tabellen, wenn Sie eine Hash-Tabelle hat.
Ich empfehle dabei eine Hash-Tabelle.
Vielleicht haben Sie bereits getan haben ein Trie
sondern versucht sind schwieriger.
In der Theorie sind sie asymptotisch besser.
Aber gerade in der großen Tafel schauen,
und versucht nie besser, und sie benötigen mehr Speicher.
Alles über versucht, endet als schlimmer für mehr Arbeit.
Es ist, was David Malan-Lösung ist immer
er ist immer Beiträge seiner Trie-Lösung, und mal sehen, wo er derzeit.
Was war er unter, David J?
Er ist Nr. 18, so ist das nicht furchtbar schlecht,
und das wird zu einem der besten versucht man sich denken kann
oder einer der besten versucht eines Trie.
Ist es nicht sogar seine ursprüngliche Lösung?
Ich fühle mich wie Trie-Lösungen zu sein in diesem Bereich der RAM-Auslastung neigen.
>> Nach unten bis ganz nach oben, und RAM-Auslastung ist in den einstelligen Bereich.
Nach unten zum Boden, und dann sehen, beginnen versucht,
wo man absolut riesig RAM-Auslastung zu erhalten,
und versucht sind schwieriger.
Nicht ganz lohnt sich aber eine lehrreiche Erfahrung, wenn Sie tat es.
Das letzte, was ist unser verketteten Liste,
und diese drei Dinge, Stapel, Warteschlangen und verkettete Listen,
jede künftige was Sie jemals tun in der Informatik
nehme an, Sie haben die Vertrautheit mit diesen Dingen.
Sie sind nur so fundamental für alles.
>> Verkettete Listen, und hier haben wir eine einfach verkettete Liste wird unsere Umsetzung.
Was macht einfach verkettete bedeutet zu doppelt verkettete dagegen? Ja.
[Student] Es wird nur auf das nächste Zeiger anstatt den Zeiger,
wie die vorangehende und die eine danach.
Ja, so in Bildformat, was habe ich nur tun?
Ich habe zwei Dinge. Ich habe Bild und Bild.
In Bildformat, unsere einfach verkettete Listen,
unvermeidlich, haben wir eine Art von Zeiger auf der Spitze unserer Liste,
und dann innerhalb unserer Liste, wir haben nur Zeiger,
und vielleicht deutet dies auf null.
Es wird auf die typische Zeichnung einer einfach verketteten Liste.
Eine doppelt verkettete Liste, können Sie rückwärts gehen.
Wenn ich dir einen beliebigen Knoten in der Liste, dann können Sie zwangsläufig zu bekommen
einem anderen Knoten in der Liste, wenn es sich um eine doppelt verknüpfte Liste.
Aber wenn ich dir den dritten Knoten in der Liste und es ist eine einfach verkettete Liste
keine Möglichkeit, jemals gehst, um den ersten und zweiten Knoten zu bekommen.
Und es gibt Vorteile und Nachteile, und ein offensichtlich ein
wird Sie nehmen mehr Größe, und Sie haben den Überblick, wo diese Dinge jetzt zeigen zu halten.
Aber wir haben nur kümmern uns um einfach verkettete.
>> Ein paar Dinge, die wir gehen zu müssen, zu implementieren sind.
Ihre typedef struct node, int i: struct node * next; Knoten.
Das typedef sollte in Ihrem Verstand gebrannt werden.
Quiz 1 werden gerne geben einen typedef einer verketteten Liste Knoten
und Sie sollten in der Lage sein, sofort, dass sich kritzeln
ohne auch nur daran zu denken.
Ich denke, ein paar Fragen, warum brauchen wir struct hier?
Warum können wir nicht sagen, node *?
[Student] [unverständlich]
Yeah.
Die einzige Sache, die einen Knoten definiert als ein Ding
ist die typedef selber.
Aber ab diesem Punkt, wenn wir solche Analyse sind durch diese struct node Definition
wir haben unsere typedef noch nicht fertig, so da die typedef ist noch nicht abgeschlossen,
Knoten nicht existiert.
Aber struct node tut, dieser Knoten und hier
Dies könnte auch etwas anderes bezeichnet werden.
Dies könnte man n werden.
Man könnte es linked list node werden.
Es könnte alles abgerufen werden.
Aber diese struct Knoten muss als die gleiche Sache wie dieser struct node werden.
Was Sie nennen dies muss auch hier sein,
und so, dass auch die Antwort auf die zweite Stelle des betreffenden
weshalb-eine Menge Zeit, wenn Sie Strukturen und Typdefinitionen von Strukturen zu sehen,
Sie werden sehen, anonymen Strukturen, wo man einfach sehen typedef struct,
Umsetzung der struct, Wörterbuch, oder was auch immer.
>> Warum hier brauchen wir den Knoten sagen?
Warum kann es nicht eine anonyme struct sein?
Es ist fast die gleiche Antwort.
[Student] Sie müssen es innerhalb der Struktur beziehen.
Ja, innerhalb der Struktur, müssen Sie auf die Struktur selbst beziehen.
Wenn Sie nicht geben dem struct einen Namen, wenn es eine anonyme struct ist, können Sie nicht darauf beziehen.
Und last but not least-diese sollten alle etwas einfach,
und sie soll Ihnen helfen, zu realisieren, wenn Sie dies schreibe gerade nach unten
dass Sie etwas falsch machen, wenn diese Art von Dingen keinen Sinn machen.
Last but not least, warum dies zu struct node * sein?
Warum kann es nicht einfach werden Knoten nächsten struct?
[Student] Pointer auf die nächste struct.
Das ist unvermeidlich, was wir wollen.
Warum konnte es nie struct node nächste sein?
Warum muss es zu struct node * nächste sein? Yeah.
[Student] Es ist wie eine Endlosschleife.
Yeah.
[Student] Es wäre alles in einem sein.
Ja, nur, wie wir Größe oder etwas zu tun, zu denken.
Größe einer Struktur ist im Grunde + oder - einige Muster hier oder dort.
Es ist im Grunde werde die Summe der Größen der Dinge in der struct sein.
Das hier, ohne etwas zu ändern, wird die Größe einfach sein.
Größe der struct node wird auf die Größe der i + Größe der nächste sein.
Größe von i wird 4 sein. Größe der nächsten wird 4 sein.
Größe der struct node wird 8 sein.
Wenn wir nicht die *, denken sizeof,
dann sizeof (i) wird 4 sein.
Größe der struct node nächsten wird die Größe von i + Größe struct node nächsten
+ Größe der i + Größe struct node nächsten.
Es wäre eine unendliche Rekursion von Knoten sein.
Deshalb ist dies, wie die Dinge zu sein haben.
>> Wieder auf jeden Fall merken, dass,
oder zumindest zu verstehen reicht es, dass man in der Lage sein
Vernunft durch, was es aussehen sollte.
Die Dinge, die wir umsetzen wollen sind.
Wenn die Länge der Liste-
Sie könnten betrügen und halten um ein
globale Länge oder etwas, aber wir werden nicht zu tun.
Wir werden, um die Länge der Liste zählen.
Wir haben enthält, so das ist im Grunde wie eine Suche,
so haben wir eine verkettete Liste von Zahlen, um zu sehen, wenn diese Zahl ist in der verknüpften Liste.
Prepend wird am Anfang der Liste eingefügt.
Append wird am Ende einfügen.
Insert_sorted wird in die sortierte Position in der Liste einzufügen.
Insert_sorted Art setzt voraus, dass Sie nie prepend verwendet oder anhängen in schlechte Wege.
>> Insert_sorted, wenn Sie die Umsetzung insert_sorted-sind
sagen wir, wir haben unsere verketteten Liste.
Dies ist, was es derzeit aussieht, 2, 4, 5.
Ich möchte 3 einzufügen, so lange, wie die Liste selbst ist bereits sortiert,
es ist leicht zu finden, wo 3 gehört.
Ich beginne bei 2.
Okay, das ist 3 größer als 2 ist, so möchte ich weitermachen.
Oh, das ist 4 zu groß, damit ich weiß, 3 wird zu gehen zwischen 2 und 4,
und ich habe auf Zeiger und all das Zeug zu beheben.
Aber wenn wir nicht unbedingt verwenden insert_sorted,
wie sagen wir einfach, ich voranstellen 6,
dann meine verkettete Liste wird dies geworden.
Es macht jetzt keinen Sinn, so dass für insert_sorted, können Sie einfach davon ausgehen,
dass die Liste sortiert ist, obwohl Operationen existieren
das kann dazu führen, dass nicht sortiert werden, und das ist es.
Finden Sie einen hilfreichen Einsatz-so das sind die wichtigsten Dinge, die Sie gehen zu müssen, zu implementieren sind.
>> Denn jetzt, eine Minute auf Länge zu tun und enthält
und diejenigen, sollte relativ schnell.
Kurz vor Feierabend, so jemand etwas für die Länge oder enthält?
Sie werden fast identisch sein.
[Student] Länge.
Mal sehen, Revision.
Okay.
Sie wollen zu erklären?
[Student] Ich habe gerade einen Zeiger erstellen, Knoten und initialisiert es zuerst, die unsere globale Variable ist,
und dann habe ich zu überprüfen, um zu sehen, wenn es null ist, damit ich nicht bekommen, eine seg Fehler und 0 zurückgeben, wenn das der Fall ist.
Ansonsten halten I durchlaufen, Spur von in Integer
wie oft habe ich das nächste Element der Liste zugreifen
und in der gleichen Inkrementierungsvorgang auch auf, dass die tatsächliche Element,
und dann habe ich kontinuierlich machen das Kontrollkästchen, um zu sehen, wenn es null ist,
und wenn es null ist, dann ist es bricht und gibt nur die Anzahl der Elemente habe ich zugegriffen.
>> [Rob B.] Hat jemand irgendwelche Kommentare zu irgendetwas?
Das sieht gut Richtigkeit klug.
[Student] Ich glaube nicht, benötigen Sie den Knoten == null.
Ja, so, wenn der Knoten == null return 0.
Aber wenn der Knoten == null dann-oh, es ist ein Richtigkeit Thema.
Es war einfach nur du wieder i, aber es ist nicht im Lieferumfang gerade jetzt.
Sie müssen nur int i, so i = 0.
Aber wenn der Knoten null ist, dann habe ich noch gehen auf 0 sein,
und wir werden auf 0 zurückgesetzt, so ist dieser Fall identisch.
Ein weiteres gemeinsames Sache ist, die Erklärung zu halten
der Knoten innerhalb der for-Schleife.
Man könnte sagen, oh, nein.
Belassen wir es wie dieses.
Wahrscheinlich würde ich int i = 0 hier zu setzen,
dann node * node = erste hier.
Und das ist wahrscheinlich how-loszuwerden dies jetzt.
Dies ist wahrscheinlich, wie ich es geschrieben habe.
Sie könnten auch Aussagen auf sie wie diese.
Diese for-Schleife-Struktur hier
sollte fast so natürlich, Sie als für int i = 0
i kleiner als die Länge des Arrays i + +.
Wenn es das ist, wie Sie über ein Array zu durchlaufen, ist dies, wie Sie über eine verknüpfte Liste durchlaufen.
>> Dies sollte zur zweiten Natur an einem gewissen Punkt.
Mit dem im Verstand, das wird fast die gleiche Sache.
Sie gehen zu wollen, durchlaufen eine verkettete Liste.
Wenn der Knoten-Ich habe keine Ahnung, was der Wert genannt wird.
Node i.
Wenn der Wert an diesem Knoten = i return true, und das ist es.
Beachten Sie, dass der einzige Weg, den wir je return false
ist, wenn wir iterieren über den gesamten verketteten Liste und nie wieder wahr,
so dass das, was hier geschieht.
As a side note, wir wahrscheinlich nicht bekommen anzuhängen oder voranzustellen.
>> Schnelle letzten Ton.
Wenn Sie das Schlüsselwort static sehen, so sagen wir static int count = 0,
dann tun wir count + +, können Sie grundsätzlich daran denken, wie eine globale Variable
obwohl ich gerade sagte, dies sei nicht, wie wir das auf die Länge zu implementieren.
Ich tue dies hier, und dann zählen + +.
Jede Art, wie wir einen Knoten in unser verlinkten Liste, die wir Inkrementieren unserer Zählung sind eindringen kann.
Der Punkt dabei ist, was das Schlüsselwort static bedeutet.
Wenn ich gerade int count = 0, die eine regelmäßige alte globale Variable sein würde.
Was static int count bedeutet, dass es eine globale Variable für diese Datei ist.
Es ist unmöglich, eine andere Datei,
wie denken pset 5, wenn Sie begonnen haben.
Sie haben sowohl speller.c, und Sie haben dictionary.c,
und wenn man nur erklären, eine Sache global, dann ist alles in speller.c
in dictionary.c und umgekehrt zugegriffen werden.
Globale Variablen sind zugänglich von jedem. C-Datei,
aber statische Variablen sind nur innerhalb der Datei selbst,
so Innenseite Rechtschreibprüfung oder innerhalb dictionary.c,
Dies ist eine Art, wie ich meine Variable für die Größe meines Array deklarieren
oder die Größe meines Anzahl der Wörter im Wörterbuch.
Da will ich nicht, um eine globale Variable zu deklarieren, dass jemand auf Zugang,
Eigentlich habe ich nur darum kümmern für meine eigenen Zwecke.
>> Die gute Sache daran ist auch die ganze Namenskollision Zeug.
Wenn eine andere Datei versucht, eine globale Variable namens Graf zu verwenden, gehen die Dinge sehr, sehr falsch,
so dass diese schön hält die Dinge sicher, und nur Sie können darauf zugreifen,
und niemand anderes kann, und wenn jemand anderes deklariert eine globale Variable namens count,
dann wird es nicht mit dem statischen Variable namens Graf stören.
Das ist, was statisch ist. Es ist eine Datei globalen Variablen.
>> Fragen über alles?
All set. Bye.
[CS50.TV]