[Powered by Google Translate] [Review] [Quiz 0] [Lexi Ross, Tommy MacWilliam, Lucas Freitas, Joseph Ong] [Harvard University] [Dies ist CS50.] [CS50.TV] Hey, everyone. Willkommen in der Review-Sitzung für Quiz 0, die stattfindet am Mittwoch. Was wir heute Abend zu tun, bin ich mit 3 anderen TFs, und zusammen werden wir durch eine Überprüfung dessen, was wir im Laufe getan so weit gehen. Es wird nicht zu 100% umfassende, aber es sollte Ihnen eine bessere Vorstellung von dem, was Sie bereits nach unten und was Sie noch brauchen, um vor Mittwoch zu studieren. Und fühlen Sie sich frei, um Ihre Hand mit Fragen aufwerfen, wie wir zusammen sind, aber im Kopf behalten, dass wir auch ein wenig Zeit am Ende- wenn wir durch ein paar Minuten, um Ersatz-auf allgemeine Fragen zu tun, so man im Hinterkopf behalten, und so werden wir am Anfang mit Week 0 beginnen. [Quiz 0 Bewertung!] [Part 0] [Lexi Ross] Aber bevor wir das tun, lassen Sie uns darüber reden die Logistik des Quiz. [Logistik] [Quiz findet am Mittwoch 10/10 statt der Vortrag] [(Siehe http://cdn.cs50.net/2012/fall/quizzes/0/about0.pdf für Details)] Es ist am Mittwoch, 10. Oktober. Das ist an diesem Mittwoch, und wenn man auf diese URL hier das ist auch von CS50.net-gibt 's einen Link zu it- können Sie Informationen darüber, wo auf der Basis gehen Ihren Nachnamen oder Schule Zugehörigkeit sowie er erzählt, was genau das Quiz deckt und die Arten von Fragen, die Sie bekommen werden. Denken Sie daran, dass Sie auch die Möglichkeit haben, für das Quiz im Abschnitt zu überprüfen, so dass Ihre TFs sollten über einige Praxis Probleme gehen, und das ist eine andere gute Chance zu sehen, wo Sie noch brauchen, um zu studieren für das Quiz. Lassen Sie uns am Anfang mit Bits 'n' Bytes beginnen. Angemeldet etwas ist nur eine 0 oder eine 1, und ein Byte ist eine Sammlung von 8 dieser Bits. Lassen Sie uns an dieser Sammlung von Bits nach rechts hier. Wir sollten in der Lage sein, um herauszufinden, wie viele Bits sind. Wo wir zählen es gibt nur 8 von ihnen, acht 0 oder 1 Einheiten. Und da gibt es 8 Bits, also 1 Byte ist, und lasst uns wandeln es in hexadezimal. Hexadezimal ist die Basis 16, und es ist ziemlich einfach zu konvertieren eine Zahl in binäre, ist das, was das ist, um eine Zahl in hexadezimal. Alles, was wir tun, ist, dass wir schauen Gruppen von 4, und wir wandeln sie in die entsprechende Hexadezimalzahl. Wir beginnen mit dem am weitesten rechts Gruppe von 4, so 0011. Das wird ein 1 und ein 2 sein, so zusammen, dass macht 3. Und dann schauen wir uns den anderen Block von 4 aussehen. 1101. Das wird ein 1, ein 4 und ein 8 sein. Gemeinsam das wird, 13 zu sein, das macht D. Und wir werden daran erinnern, dass in hexadezimaler wir nicht einfach hingehen 0 bis 9 enthalten. Wir gehen von 0 bis F, also nach 9, 10 entspricht A, 11 bis B, et cetera wobei F 15. Hier 13 ist ein D, so wandeln sie in Dezimalzahlen alles, was wir tun, ist, dass wir eigentlich behandeln jede Position als einer Potenz von 2. Das ist ein 1, eine 2, Null 4s, Null 8s, ein 16, et cetera, und es ist ein wenig schwer zu in deinem Kopf zu berechnen, aber wenn wir gehen, um die nächste Folie können wir die Antwort darauf zu sehen. Im Grunde sind wir ganz von rechts zurück nach links, und wir Multiplizieren jede Ziffer durch die entsprechende Potenz von 2. Und denken Sie daran, für hexadezimale bezeichnen wir diese Zahlen mit 0x am Anfang so dass wir nicht zu verwechseln mit einer Dezimalzahl. Weiter auf, ist dies ein ASCII-Tabelle, und was wir ASCII verwenden für ist aus Zeichen in numerische Werte zuzuordnen. Angemeldet in der Kryptographie pset haben wir umfangreiche Nutzung des ASCII-Tabelle um verschiedene Methoden der Kryptographie, der Cäsar und die Vigenère Chiffre, um verschiedene Buchstaben umwandeln in einer Zeichenfolge gemäß der Taste durch den Benutzer gegeben. Lassen Sie uns ein wenig von ASCII Mathematik aussehen. Mit Blick auf 'P' + 1, im Charakter Formular Q wäre, und denken Sie daran, dass '5 '≠ 5. Und wie genau wollen wir zwischen diesen zwei Formen zu konvertieren? Es ist nicht wirklich zu hart. Um 5 erhalten wir subtrahieren '0 ' denn es gibt 5 Plätze zwischen 0 'und der '5. Um in die andere Richtung geht das einfach mit 0 zu gehen, so ist es ein bisschen wie regelmäßige Arithmetik. Denken Sie daran, dass, wenn etwas Zitate hat um ihn herum es ein Zeichen ist und entspricht damit dem Wert in der ASCII-Tabelle. Umzug in allgemeiner Informatik Themen. Wir haben gelernt, was ein Algorithmus ist und wie wir die Programmierung verwenden Algorithmen zu implementieren. Einige Beispiele von Algorithmen sind etwas ganz Einfaches wie Prüfen, ob eine gerade oder ungerade Zahl ist. Dafür erinnern wir uns mod die Nummer 2 und überprüfen, ob das Ergebnis 0 ist. Wenn dem so ist, ist es noch. Wenn nicht, ist es seltsam. Und das ist ein Beispiel für eine wirklich grundlegende Algorithmus. Ein wenig von einem mehr beteiligt ist man binäre Suche, die wir gehen über später in der Review-Sitzung. Und Programmierung ist der Begriff verwenden wir für die Aufnahme eines Algorithmus und Umwandeln desselben in den Computercode lesen kann. 2 Beispiele für die Programmierung Scratch, das ist, was wir in Woche 0 taten. Obwohl wir eigentlich gar nicht geben Sie den Code, es ist ein Weg zur Umsetzung Dieser Algorithmus, welches das Drucken der Nummern 1 bis 10 ist, und hier haben wir das Gleiche tun in der C-Programmiersprache. Dies sind funktionell gleichwertig, nur in verschiedenen Sprachen oder Syntax geschrieben. Wir haben dann gelernt, über boolesche Ausdrücke, und ein boolean ist ein Wert, der entweder wahr oder falsch ist, und hier oft boolesche Ausdrücke reingehen von Bedingungen, so if (x ≤ 5), gut, wir bereits eingestellt x = 5, so dass diese Bedingung wird als wahr ausgewertet. Und wenn es wahr ist, was auch immer-Code unter der Bedingung, wird durch den Computer ausgewertet werden, so dass die String-los zu druckenden auf die Standardausgabe und der Begriff Zustand bezieht sich auf alles, was in den Klammern der if-Anweisung. Erinnere mich an all die Betreiber. Angemeldet es && und | |, wenn wir versuchen zu kombinieren 2 oder mehrere Bedingungen, == Nicht = zu prüfen, ob 2 Dinge gleich sind. Beachten Sie, dass = für die Zuordnung ist, während == ist ein boolean Operator. ≤, ≥ und dann die letzten 2 sind selbsterklärend. Eine allgemeine Übersicht über boolesche Logik hier. Und boolean Ausdrücke sind auch in Schleifen wichtig, die wir gehen jetzt vorbei. Wir erfuhren von 3 Arten von Schleifen bisher CS50, for, while, und zu tun, während. Und es ist wichtig zu wissen, dass, während für die meisten Zwecke können wir tatsächlich nutzen jede Art von Schleife in der Regel Es gibt bestimmte Arten von Zwecke oder gemeinsame Muster in der Programmierung, die speziell für eine dieser Schleifen rufen dass es die effizienteste oder elegant, es auf diese Weise zu codieren. Lasst uns über das, was jeder dieser Schleifen um am häufigsten verwendeten neigt. In einer for-Schleife, die wir in der Regel bereits wissen, wie oft wir zu durchlaufen wollen. Das ist, was wir in die Lage versetzt. Für i = 0, i <10, zum Beispiel. Wir wissen bereits, dass wir etwas 10-mal tun wollen. Nun, für eine while-Schleife, in der Regel wir nicht unbedingt wissen, wie viele Male wir die Schleife ausgeführt werden soll. Aber wir wissen, irgendeine Art von Bedingung, dass wir es wollen immer wahr oder immer falsch sein. Zum Beispiel wird während eingestellt. Lassen Sie uns sagen, das ist eine boolsche Variable. Während das ist wahr, wir wollen, dass die Codes zu bewerten, so ein bisschen mehr erweiterbar, ein wenig allgemeiner als eine for-Schleife, aber jede for-Schleife kann auch zu einer while-Schleife umgewandelt werden. Schließlich tun while-Schleifen, die der schwierigste sein kann, um sofort zu begreifen, werden oft verwendet, wenn wir den Code zuerst auswerten wollen vor dem ersten Mal, wenn wir den Zustand. Eine gemeinsame Nutzung Fall für eine do while-Schleife ist, wenn Sie Benutzereingaben erhalten wollen, und Sie wissen, dass Sie den Benutzer zu fragen für die Eingabe mindestens einmal, aber wenn sie nicht geben Ihnen gute Eingang rechts weg Sie behalten möchten, fragen sie, bis sie Ihnen die guten Input. Das ist die häufigste Verwendung einer Do While-Schleife, und lasst uns an der tatsächlichen Struktur dieser Schleifen aussehen. Sie in der Regel immer dazu neigen, diese Muster zu folgen. Auf der for-Schleife im Inneren haben Sie 3 Komponenten: Initialisierung der Regel so etwas wie int i = 0, wo i ist der Zähler, Zustand, wo wir sagen wollen laufen diese for-Schleife, solange dieser Zustand noch besitzt, wie i <10, und schließlich, Update, das, wie wir Inkrement die Zählvariable an jedem Punkt in der Schleife. Eine gemeinsame Sache zu sehen gibt ist nur i + +, was bedeutet, erhöhen i um 1 jedesmal. Sie können auch etwas tun, wie i + = 2, was bedeutet, fügen 2 bis i jedes Mal, wenn Sie durch die Schlaufe. Und dann das tun dies nur auf jede Code, der tatsächlich läuft als Teil der Schleife. Und für eine while-Schleife, diesmal haben wir eigentlich die Initialisierung außerhalb der Schleife, so zum Beispiel, sagen wir, wir versuchen, die gleiche Art von Schleife als ich gerade beschrieben habe zu tun. Wir würden sagen, int i = 0, bevor die Schleife beginnt. Dann könnten wir sagen, während i <10 dies zu tun, so dass die gleiche Codeblock wie zuvor, und diesmal ist die Aktualisierung Teil des Codes, zum Beispiel i + +, tatsächlich geht im Inneren der Schleife. Und schließlich, für eine zu tun, während es ähnlich wie die while-Schleife ist, aber wir müssen uns daran erinnern, dass der Code einmal bewerten bevor die Bedingung geprüft wird, so macht es viel mehr Sinn wenn man es in der Reihenfolge der von oben nach unten. In einer do while-Schleife der Code evaluiert, bevor Sie an der während der Zustand auch aussehen, während eine while-Schleife, prüft es zuerst. Statements und Variablen. Wenn wir eine neue Variable erstellen möchten wollen wir zuerst zu initialisieren. Zum Beispiel, initialisiert int bar die Variable bar, aber es gibt es nicht einen Wert, so was ist bar den Wert jetzt? Wir wissen es nicht. Es könnte einige Müll Wert, der zuvor im Speicher wurde dort gespeichert sein, und wir wollen nicht, dass die Variable verwenden bis wir tatsächlich geben sie einen Wert, so erklären wir es hier. Dann initialisieren wir es bis 42 darunter. Nun, natürlich wissen wir dies getan werden kann auf einer Linie, int bar = 42 werden. Aber nur klar zu sein, die mehrere Schritte, los werden, die Erklärung und die Initialisierung werden separat hier passiert. Es geschieht auf eine Stufe, und das nächste, int baz = bar + 1, diese Aussage unter, dass Schritten baz, so dass am Ende dieser Code-Block wenn wir den Wert der baz gedruckt waren es 44 sein weil wir deklarieren und initialisieren es auf 1> bar sein, und dann erhöhen wir es einmal mehr mit dem + +. Wir gingen dieser hübschen kurz, aber es ist gut, einen allgemeinen haben Verständnis dessen, was Themen und Ereignisse sind. Wir hauptsächlich tat dies in Scratch, so können Sie von Threads als mehrere Codesequenzen denken laufen gleichzeitig. In Wirklichkeit ist es wahrscheinlich nicht laufen zur gleichen Zeit, aber irgendwie abstrakt können wir es auf diese Weise zu denken. In Scratch, zum Beispiel, hatten wir die vielfältigen Sprites. Man könnte die Ausführung unterschiedlicher Code zur gleichen Zeit. Man könnte zu Fuß, während der andere etwas zu sagen in einem anderen Teil des Bildschirms. Ereignisse sind eine weitere Möglichkeit der Trennung die Logik zwischen den verschiedenen Elementen des Codes, und im Scratch konnten wir Ereignisse simulieren mit dem Broadcast, und das ist eigentlich, wenn ich erhalten, nicht, wenn ich höre, aber im Wesentlichen ist es ein Weg, um Informationen zu übertragen von einem Sprite zu einem anderen. Zum Beispiel möchten Sie vielleicht zu Spiel zu übertragen vorbei, und wenn ein anderes Sprite erhält game over, antwortet er in einer bestimmten Weise. Es ist ein wichtiges Modell für die Programmierung zu verstehen. Nur um über die grundlegenden Woche 0 gehen, was wir in so weit gegangen, Lassen Sie uns in diesem einfachen C-Programm zu suchen. Der Text kann ein wenig klein von hier sein, aber ich werde über sie gehen wirklich schnell. Wir inklusive 2 Header-Dateien an der Spitze, cs50.h und stdio.h. Wir nehmen dann eine Konstante zu definieren als Limit auf 100 sein. Wir nehmen dann die Umsetzung unserer Hauptfunktion. Da wir nicht verwenden Befehlszeilenargumente hier brauchen wir für nichtig gesetzt wie die Argumente für main. Wir sehen int vor main. Das ist der Rückgabetyp, daher 0 zurück an der Unterseite. Und wir verwenden CS50-Bibliothek function get int um den Benutzer zur Eingabe fragen, und wir speichern sie in dieser Variablen x, so erklären wir x oben, und initialisieren wir es mit x = GetInt. Wir überprüfen dann, wenn der Benutzer gaben uns gute Eingang. Wenn es ≥ LIMIT ist wollen wir einen Fehlercode 1 zurück und drucken eine Fehlermeldung. Und schließlich, wenn der Benutzer hat uns gute Eingabe wir gehen, um die Zahl zu quadrieren und ausdrucken dieses Ergebnis. Nur um sicherzugehen, dass die alle Treffer Hause können Sie die Etiketten der verschiedenen Teile des Codes hier. Ich erwähnte Konstante, Header-Dateien. Oh, int x. Achten Sie darauf, sich daran zu erinnern, dass es eine lokale Variable. Das kontrastiert sie von einer globalen Variablen, die wir reden ein wenig später in der Review-Sitzung und wir sind dem Aufruf der Bibliotheksfunktion printf, so dass, wenn wir nicht die stdio.h Header-Datei enthalten wären wir nicht in der Lage sein printf nennen. Und ich glaube, der Pfeil, der ab hier wurde geschnitten wird, um die% d zeigt, die eine Format-String in printf. Er sagt, drucken Sie diese Variable als eine Zahl,% d. Und das ist es für Woche 0. Jetzt Lucas wird sich fortsetzen. Hey, guys. Mein Name ist Lucas. Ich bin im zweiten Jahr in der besten Haus auf dem Campus, Mather, und ich werde ein wenig darüber Woche 1 und 2,1 zu sprechen. [Woche 1 und 2,1!] [Lucas Freitas] Als Lexi sagte, wenn wir übersetzen den Code von Grund auf C begonnen Eines der Dinge, die wir bemerkt ist, dass man nicht nur Ihren Code schreiben, und führen Sie es mit einer grünen Flagge mehr. Eigentlich haben Sie einige Schritte, um Ihre C-Programm zu machen zu einer ausführbaren Datei. Im Grunde, was Sie tun, wenn Sie ein Programm schreiben, sind ist, dass Sie übersetzen Ihre Idee in einer Sprache, die ein Compiler verstehen können, so, wenn Sie ein Programm schreiben, in C was du tust ist tatsächlich etwas zu schreiben, dass Ihr Compiler wird zu verstehen, und dann der Compiler wird diesen Code zu übersetzen in etwas, dass Ihr Computer zu verstehen. Und die Sache ist, ist Ihr Computer wirklich sehr dumm. Ihr Computer kann nur verstehen, 0 und 1, so tatsächlich in den ersten Computer Menschen in der Regel programmiert mit 0 und 1, aber nicht mehr, Gott sei Dank. Wir müssen nicht die Sequenzen für 0 und 1 merken für eine for-Schleife oder einer while-Schleife und so weiter. Deshalb haben wir einen Compiler haben. Was für ein Compiler tut, ist es im Grunde übersetzt den C-Code, in unserem Fall, einer Sprache, die Computer verstehen wird, das ist der Objekt-Code, und der Compiler, dass wir mit wird als Klang, so ist dies eigentlich das Symbol für Klang. Wenn Sie Ihr Programm haben, müssen Sie 2 Dinge tun. Zuerst müssen Sie Ihr Programm zu kompilieren, und dann wirst du um das Programm auszuführen. Um Ihr Programm kompilieren Sie haben eine Menge von Optionen, um dies zu tun. Die erste besteht darin, clang program.c tun in welchem ​​Programm ist der Name des Programms. In diesem Fall können Sie sehen, dass sie nur sagen: "Hey, kompilieren mein Programm." Du bist nicht sagen: "Ich will diesen Namen für mein Programm" oder so etwas. Die zweite Option ist einen Namen zu geben Ihrem Programm. Man kann sagen, Klang-o und dann den Namen, die Sie die ausführbare Datei, die als und dann program.c benannt werden. Und Sie können auch das Programm make, und sehen, wie in den ersten 2 Fällen Ich lege. C, und im dritten ein Ich habe nur Programme? Ja, Sie sollten eigentlich nicht gestellt. C, wenn Sie nutzen. Andernfalls wird der Compiler ist eigentlich los, um dich zu schreien. Und auch, ich weiß nicht, ob euch erinnern, aber viele Male haben wir auch-LCS50 oder-lm. Das nennt man Verkettung. Es ist einfach sagt dem Compiler, dass Sie diese Bibliotheken genau dort zu verwenden, Wenn Sie also cs50.h verwenden wollen Sie haben tatsächlich zu geben clang program.c-LCS50. Wenn Sie das nicht tun, wird der Compiler nicht zu wissen, dass Sie mit diesen Funktionen in cs50.h. Und wenn Sie Ihr Programm haben Sie 2 Möglichkeiten wollen. Wenn Sie clang program.c hast du nicht einen Namen geben zu Ihrem Programm. Sie haben, um es auszuführen mit. / A.out. A.out ist ein Standard-Name, den Klang Ihres Programms gibt, wenn Sie nicht geben ihm einen Namen. Sonst wirst du. / Programm zu tun, wenn Sie einen Namen gab, um Ihr Programm, und auch, wenn Sie Programm den Namen hat, dass ein Programm gehen, um geht schon programmiert den gleichen Namen wie der c-Datei werden. Dann sprachen wir über Datentypen und Daten. Grundsätzlich Datentypen sind die gleiche Sache wie kleine Boxen verwenden sie um Werte zu speichern, so Datentypen sind eigentlich genauso wie Pokémons. Sie kommen in allen Größen und Ausführungen. Ich weiß nicht, ob diese Analogie macht Sinn. Die Datengröße tatsächlich abhängig von der Maschinen-Architektur. Alle Daten Größen, ich werde hier zeigen sind eigentlich für ein 32-Bit-Maschine, die bei unserem Gerät ist, aber wenn Sie tatsächlich Kodierung Ihrer Mac oder einem Windows auch Wahrscheinlich wirst du um eine 64-Bit-Rechner haben, so daran erinnern, dass die Daten Größen, ich werde hier zeigen sind für die 32-Bit-Maschine. Die erste, die wir sahen, war ein int, das ist ziemlich einfach. Sie verwenden int um eine ganze Zahl zu speichern. Wir sahen auch den Charakter, die char. Wenn Sie einen Brief oder ein kleines Symbol verwenden möchten Sie wahrscheinlich eine char verwenden. Ein char hat 1 Byte, das 8 Bits, wie Lexi das Mittel. Grundsätzlich haben wir eine ASCII-Tabelle, die 256 hat möglichen Kombinationen von 0 und 1, und dann, wenn Sie eine char geben, es wird übersetzt das Zeichen, dass Eingänge Sie eine Nummer, die Sie in der ASCII-Tabelle haben, wie Lexi sagte. Wir haben auch die Schwimmer, die wir verwenden, um Dezimalzahlen zu speichern. Wenn Sie 3,14 wählen möchten, zum Beispiel, wirst du einen Schwimmer verwenden oder eine doppelte, die mehr Präzision hat. Ein Schwimmer hat 4 Bytes. Eine doppelte verfügt über 8 Bytes, so dass der einzige Unterschied ist die Präzision. Wir haben auch eine lange, die für ganze Zahlen verwendet wird, und Sie können eine 32-Bit-Maschine zu sehen ein int und eine lange haben die gleiche Größe, so dass es nicht wirklich Sinn, eine lange Zeit in einem 32-Bit-Maschine zu verwenden. Aber wenn Sie einen Mac verwenden und 64-Bit-Rechner sind, eigentlich eine lange hat die Größe 8, so dass es hängt wirklich von der Architektur. Für die 32-Bit-Maschine ist es nicht sinnvoll, eine lange wirklich nutzen. Und dann eine lange langen, auf der anderen Seite hat 8 Byte, so ist es sehr gut, wenn man eine längere Zahl haben wollen. Und schließlich haben wir string, was ist eigentlich ein char *, das ist ein Zeiger auf eine char. Es ist sehr einfach zu denken, dass die Größe der Zeichenfolge wird wohl sein die Anzahl der Zeichen, dass Sie es haben, sondern tatsächlich die char * selbst hat die Größe von einem Zeiger auf eine char, der 4 Bytes ist. Die Größe eines char * 4 Byte. Es spielt keine Rolle, ob Sie ein kleines Wort oder einen Brief oder irgendetwas haben. Es wird 4 Bytes. Wir haben auch gelernt, ein wenig über Gießen, so wie Sie sehen können, wenn Sie zum Beispiel ein Programm, das sagt, int x = 3 und dann printf ("% d", x / 2) tun Sie Jungs wissen, was es wird auf dem Bildschirm zu drucken? Jemand? >> [Studenten] 2. 1. >> 1, yeah. Wenn Sie 3/2 zu tun, es wird 1,5 zu erhalten, aber da wir mit einem Integer sind es geht um die Dezimalstellen zu ignorieren, und du wirst bis 1 haben. Wenn Sie nicht möchten, dass das passiert, was Sie tun können, zum Beispiel, ist ein float deklarieren y = x. Dann x, die 3 früher wird jetzt 3,000 werden in y. Und dann können Sie ausdrucken y / 2. Eigentlich sollte ich eine 2. dort drüben. Es wird 3.00/2.00 tun, und du wirst bis 1,5 erhalten. Und wir haben dieses .2 f nur für 2 Dezimalstellen Einheiten in den Dezimalteil fragen. Wenn Sie .3 f haben, es wird tatsächlich 1,500. Wenn es 2 es geht um 1,50 sein. Wir haben auch diesen Fall hier. Wenn Sie das tun float x = 3,14 und dann printf x Sie gehen bis 3,14 erhalten. Und wenn Sie x = int x, was bedeutet, zu behandeln x als int und drucken Sie x jetzt Sie gehen bis 3,00 haben. Macht das Sinn? Weil du ersten Behandlung sind x als ganze Zahl, so dass Sie ignorieren die Dezimalstellen, und dann bist du Bedrucken x. Und schließlich können Sie dies auch, int x = 65, und dann erklären, eine char c = x, und dann, wenn Sie die c Drucken Sie tatsächlich gehen, um A, so dass im Grunde, was Sie hier tun wird die Übersetzung der Zahl in den Charakter, ebenso wie die ASCII-Tabelle tut. Wir sprachen auch über mathematische Operatoren. Die meisten von ihnen sind ziemlich eindeutig, so +, -, *, /, und auch wir sprachen über mod, die der Rest einer Division von 2 Zahlen. Wenn Sie 10% 3, zum Beispiel, es bedeutet zu teilen 10 durch 3, und was ist der Rest? Es wird 1 sein, so ist es eigentlich sehr nützlich für viele der Programme. Für Vigenère und Caesar Ich bin mir ziemlich sicher, dass alle von euch mod verwendet. Über mathematische Operatoren, sehr vorsichtig sein, wenn die Kombination * und /. Zum Beispiel, wenn Sie (3/2) * 2, was wirst du bekommen? [Studenten] 2. Ja, 2, da 3/2 ist werde 1,5 betragen, aber da du tust Operationen zwischen 2 Zahlen Sie tatsächlich gerade dabei, ein betrachten, und dann 1 * 2 wird 2 sein, so sehr, sehr vorsichtig wenn Rechnen mit ganzen Zahlen, weil erhalten Sie möglicherweise, dass 2 = 3 in diesem Fall. Und auch sehr vorsichtig sein Vorrang. Normalerweise sollten Sie Klammern verwenden, um sicher sein, dass Sie wissen, was du tust. Einige nützliche Shortcuts, ist natürlich ein i + + oder i + = 1 oder mit + =. Das ist das gleiche wie zu tun i = i + 1. Sie können auch i - oder i - = 1, das ist das gleiche wie i = i -1, etwas, das man Leute verwenden eine Menge in for-Schleifen, mindestens. Auch für *, wenn Sie * = und wenn Sie das tun, zum Beispiel, i * = 2 ist das dasselbe wie zu sagen i = i * 2, und dasselbe für die Teilung. Wenn Sie i / = 2 zu tun, es ist das gleiche wie i = i / 2. Nun zu den Funktionen. You guys gelernt, dass Funktionen eine sehr gute Strategie, um Code zu retten während der Programmierung sind, wenn Sie so wollen, um die gleiche Aufgabe zu erfüllen im Code immer und immer wieder, wahrscheinlich Sie eine Funktion verwenden nur damit du nicht zu kopieren und fügen Sie den Code immer und immer wieder. Eigentlich ist Haupt eine Funktion, und wenn ich Ihnen zeigen, das Format einer Funktion Sie gehen, um zu sehen, dass dies ziemlich offensichtlich ist. Wir verwenden auch Funktionen aus einigen Bibliotheken, beispielsweise printf, Getin, die aus der Bibliothek CS50 ist, und andere Funktionen wie toupper. Alle diese Funktionen sind eigentlich in anderen Bibliotheken implementiert, und wenn Sie setzen diese Leine Dateien im Anfang des Programms Sie sagen, können Sie mir den Code für diese Funktionen finden so dass ich nicht haben, um sie von mir zu implementieren? Und Sie können auch Ihre eigenen Funktionen, so dass, wenn Sie mit dem Programmieren beginnen Sie erkennen, dass Bibliotheken nicht alle Funktionen, die Sie benötigen. Für den letzten pset, zum Beispiel, schrieben wir zeichnen, Gerangel, und Lookup, und es ist sehr, sehr wichtig, um in der Lage sein, Funktionen zu schreiben weil sie nützlich sind, und wir nutzen sie die ganze Zeit in der Programmierung, und es spart eine Menge Code. Das Format einer Funktion ist dies ein. Wir haben Rückgabetyp in der Anfang. Was ist der Rückgabetyp? Es ist nur, wenn Ihre Funktion wird zurückkehren. Wenn Sie eine Funktion haben, zum Beispiel, Fakultät, das wird eine Fakultät einer Ganzzahl berechnen, wahrscheinlich, es wird eine ganze Zahl auch wieder. Dann wird der Rückgabetyp sein wird int. Printf hat tatsächlich einen Rückgabetyp void weil du nicht wieder nichts. Du bist nur gedruckt, was auf dem Bildschirm und Beenden der Funktion danach. Dann haben Sie den Namen der Funktion, die Sie wählen können. Sie sollten ein wenig vernünftig, wie nicht wählen Sie einen Namen wie xyz oder wie X2f. Versuchen Sie, einen Namen, die Sinn macht. Zum Beispiel, wenn es faktorielle ist, sagen faktorielle. Wenn es eine Funktion, die gehen, um etwas zu zeichnen ist es, nennen Sie es ziehen. Und dann haben wir die Parameter, die man auch als Argumente welche sind wie die Ressourcen, die Ihre Funktion muss aus dem Code zur Erfüllung ihrer Aufgabe. Wenn Sie die Fakultät einer Zahl zu berechnen Wahrscheinlich müssen Sie eine Nummer haben, um einen faktoriellen berechnen. Eines der Argumente, dass Sie gehen zu müssen sind die Zahl selber. Und dann wird es etwas zu tun und den Wert am Ende es sei denn, es ist eine void-Funktion. Mal sehen, ein Beispiel. Wenn ich will, um eine Funktion, die alle Zahlen addiert in einem Array von ganzen Zahlen zu schreiben, Zunächst wird die Rückgabetyp sein wird int denn ich habe ein Array von Ganzzahlen. Und dann werde ich den Namen der Funktion, wie sumArray haben, und dann es geht um das Array selbst zu nehmen, int nums, und dann die Länge des Arrays, damit ich weiß, wie viele Zahlen, die ich auf den Punkt haben. Dann muss ich eine Variable namens Summe, zum Beispiel auf 0 zu initialisieren, und jedes Mal, wenn ich ein Element im Array sollte ich es Summe addieren, also tat ich eine for-Schleife. Genau wie Lexi, tun Sie int i = 0, i 0 ist dann positiv ist. Wenn es = auf 0 ist dann ist es 0, und wenn es <0 ist dann ist es negativ. Und das andere tut, wenn sonst wenn, sonst. Der Unterschied zwischen beiden ist, dass dies tatsächlich ein werde überprüfen, ob> 0, <0 oder = 0 dreimal Wenn Sie also die Nummer 2 haben, zum Beispiel, es geht um hierher zu kommen und zu sagen if (x> 0), und es sich auf sage ja, so drucke ich positiv. Aber auch wenn ich weiß, dass es> 0 ist und es wird nicht auf 0 oder <0 sein Ich bin immer noch zu tun ist es 0, ist es <0, so bin ich eigentlich los Innenseite ifs, dass ich nicht haben weil ich schon weiß, dass es nicht zu einer dieser Bedingungen erfüllen. Ich kann die if, else if, else-Anweisung. Es ist im Grunde sagt, wenn x = 0 ich die positive drucken. Wenn es nicht ist, werde ich auch diesen Test. Wenn es 2 ist nicht werde ich das tun. Grundsätzlich, wenn ich x = 2 hätten, würden Sie sagen, if (x> 0), ja, so drucken Sie diese. Jetzt, wo ich weiß, dass es> 0 ist und dass sie sich vergewissert das erste, wenn Ich bin nicht mal diesen Code ausführen. Der Code läuft schneller, eigentlich 3 mal schneller, wenn Sie diese verwenden. Wir haben auch gelernt, über AND und OR. Ich werde mich nicht durch diese gehen, weil Lexi sprachen bereits darüber. Es ist nur die && und | | Operator. Das einzige, was ich sage ist, vorsichtig sein, wenn Sie 3 Bedingungen haben. Verwenden Sie Klammern, weil es sehr verwirrend, wenn Sie eine Erkrankung haben und eine andere oder ein anderes. Verwenden Sie Klammern, um nur sicher sein, dass Ihre Bedingungen Sinn machen weil in diesem Fall, zum Beispiel, können Sie sich vorstellen, dass es könnte die erste Bedingung und die eine oder andere sein oder die 2 Bedingungen in einem kombiniert und oder die dritte ein, so sollte man vorsichtig sein. Und schließlich sprachen wir über Schalter. Ein Schalter ist sehr nützlich, wenn Sie eine Variable haben. Lassen Sie uns sagen, dass Sie eine Variable wie n das kann 0, 1 oder 2 sein, und für jeden dieser Fälle Sie gehen, um eine Aufgabe zu erledigen. Man kann sagen, schalten Sie die Variable, und es zeigt, dass der Wert dann ist wie value1 Ich werde dies tun, und dann habe ich zu brechen, was bedeutet, dass ich nicht an einem der anderen Fälle betrachten weil wir bereits diesen Fall zufrieden und dann value2 und so weiter, und ich kann auch über eine Standard-Schalter. Das heißt, wenn sie nicht zu befriedigen keinem der Fälle, die ich hatte dass ich gehe, um etwas anderes zu tun, aber das ist optional. Das ist alles für mich. Lassen Sie uns nun Tommy. Alles klar, das wird Woche 3-ish sein. Dies sind einige der Themen, die wir werden abdeckt, crypto, Umfang, Arrays, et cetera werden. Just a quick Wort Krypto. Wir gehen nicht auf dieses Haus zu hämmern. Wir taten dies in pset 2, aber für das Quiz stellen Sie sicher, Sie kennen den Unterschied zwischen der Caesar-Chiffre und der Vigenère Chiffre, Wie diese beiden Chiffren Arbeit und wie es ist, zu verschlüsseln und Entschlüsseln von Text über die 2 Ziffern. Denken Sie daran, die Caesar-Chiffre einfach dreht jedes Zeichen durch den gleichen Betrag, dafür, dass Sie mod durch die Anzahl der Buchstaben im Alphabet. Und die Vigenère Chiffre, auf der anderen Seite dreht sich jedes Zeichen um einen anderen Betrag, so anstatt zu sagen Jeder Charakter gedreht 3 Vigenère dreht jedes Zeichen um einen unterschiedlichen Betrag abhängig von irgendeiner Schlüsselwort wo jeder Brief in dem Schlüsselwort repräsentiert eine unterschiedliche Menge die klare Text zu drehen. Lassen Sie uns zuerst über den Geltungsbereich von Variablen. Es gibt 2 verschiedene Arten von Variablen. Wir haben lokale Variablen, und diese gehen zu definieren außerhalb der Haupt-oder außerhalb einer Funktion oder Block, und diese werden überall zugänglich in Ihrem Programm. Wenn Sie eine Funktion haben und in dieser Funktion ist eine while-Schleife die große globale Variable ist überall zugänglich. Eine lokale Variable, auf der anderen Seite, ist Gültigkeitsbereich der Stelle, wo sie definiert ist. Wenn Sie eine Funktion hier zu haben, zum Beispiel, haben wir diese Funktion g, und Innenseite g es eine variable hier als y, und das bedeutet, dass diese eine lokale Variable ist. Auch wenn diese Variable heißt y Diese Variable wird als Y diese 2 Funktionen keine Ahnung, was jeweils anderen lokalen Variablen sind. Auf der anderen Seite, bis wir hier sagen, int x = 5, und dies ist nicht Gegenstand irgendeiner Funktion. Es ist außerhalb des Geltungsbereichs der wichtigsten, so ist dies eine globale Variable. Das bedeutet, dass innerhalb dieser 2 Funktionen, wenn ich x sagen - oder x + + Ich bin auf das gleiche x, wobei diese y und das y verschiedene Variablen. Das ist der Unterschied zwischen einer globalen Variable und eine lokale Variable. Soweit Design betrifft, manchmal ist es wahrscheinlich eine bessere Idee zu halten lokale Variablen, wenn Sie können möglicherweise da mit ein paar globale Variablen kann man wirklich verwirrend. Wenn Sie eine Reihe von Funktionen haben alle Änderung die gleiche Sache Sie vielleicht vergessen, was, wenn diese Funktion versehentlich verändert diese globale, und diese andere Funktion nicht darüber wissen, und es ist ziemlich verwirrend, da Sie mehr Code zu erhalten. Halten Sie lokale Variablen, wenn Sie können möglicherweise ist nur gutes Design. Arrays, denken Sie daran, einfach Listen von Elementen des gleichen Typs. Innerhalb von CI kann nicht über eine Liste wie 1, 2,0, hallo. Wir können einfach nicht tun. Wenn wir ein Array deklarieren in C alle Elemente müssen vom gleichen Typ sein. Hier habe ich eine Reihe von 3 Zahlen. Hier habe ich die Länge des Arrays, aber wenn ich mich nur Deklaration in dieser Syntax wo ich angeben, welche alle Elemente sind ich technisch nicht brauchen diese 3. Der Compiler ist intelligent genug, um herauszufinden, wie groß das Array sein sollte. Nun, wenn ich zu bekommen oder setzen Sie den Wert eines Arrays auswählen möchten Dies ist die Syntax zu tun. Dies wird tatsächlich modifizieren das zweite Element des Arrays weil erinnern, Nummerierung beginnt bei 0, nicht bei 1. Wenn ich diesen Wert lesen wollen, kann ich sagen, so etwas wie int x = array [1]. Oder wenn ich diesen Wert gesetzt werden soll, wie ich hier mache, Ich kann sagen, array [1] = 4. Diese Zeit Zugriff auf Elemente über ihren Index oder deren Position bzw. wo sie sich in dem Array, und dass Auflistung beginnt bei 0. Wir können auch Arrays von Arrays, und dies ist ein mehrdimensionales Array aufgerufen. Wenn wir einen mehrdimensionalen Arrays Das heißt, wir können so etwas wie Zeilen und Spalten, und dies ist nur eine Möglichkeit der Visualisierung dieser oder darüber nachzudenken. Wenn ich ein mehrdimensionales Array das heißt, ich werde anfangen brauchen mehr als 1 Index, weil, wenn ich ein Gitter nur sagen, welche Zeile Sie sich befinden nicht geben uns eine Nummer. Das ist wirklich nur gehen, um uns eine Liste von Zahlen. Lassen Sie uns sagen, ich habe dieses Array hier. Ich habe ein Array namens Grid, und ich sage es 2 Zeilen und 3 Spalten, und so ist dies ein Weg, zu visualisieren. Wenn ich sage, ich will das Element an [1] zu [2] das bedeutet, dass, weil diese Zeilen sind und dann Spalten Ich werde direkt zum 1 rudern, da ich 1 sagte. Dann werde ich hierher kommen bis Spalte 2, und ich werde, um den Wert 6. Sinn? Multi-dimensionale Arrays, denken Sie daran, sind technisch nur ein Array von Arrays. Wir können Arrays von Arrays von Arrays. Wir können weitermachen, aber wirklich ein Weg, um darüber nachzudenken, wie diese wird angelegt und was los ist, sie zu visualisieren in einem Raster wie diese. Wenn wir Arrays an Funktionen übergeben, werden sie sich zu verhalten ein wenig anders, als wenn wir an reguläre Variablen, Funktionen wie die Übergabe eines int oder float. Wenn wir an in ein int oder char oder eines dieser anderen Datentypen wir nahmen einen Blick auf, wenn die Funktion ändert der Wert dieser Variablen, die Veränderung ist nicht zu propagieren up an die aufrufende Funktion. Mit einer Anordnung, auf der anderen Seite, wird das geschehen. Wenn ich gehe in einem Array in einer Funktion und die Funktion ändert einige der Elemente, wenn ich komme zurück auf die Funktion, die sie aufgerufen mein Array wird nun anders zu sein, und das Vokabular für die ist Arrays per Referenz übergeben, wie wir später sehen werden. Dies wird, wie Zeiger Arbeit, wo diese grundlegenden Datentypen verwandt, Auf der anderen Seite werden als Wert übergeben. Wir können dass Sie eine Kopie einer Variablen und dann Leiten in der Kopie zu denken. Es spielt keine Rolle, was wir mit dieser Variablen zu tun. Die aufrufende Funktion nicht bewusst sein, dass es geändert wurde. Arrays sind nur ein bisschen anders in dieser Hinsicht. Zum Beispiel, wie wir gerade gesehen haben, Hauptsache einfach eine Funktion das kann in 2 Argumente. Das erste Argument der Funktion main ist argc, oder die Anzahl der Argumente, und das zweite Argument wird als argv, und das sind die tatsächlichen Werte dieser Argumente. Lassen Sie uns sagen, ich habe ein Programm namens this.c, und ich sage zu machen, und ich werde dies auf der Kommandozeile ausgeführt werden. Nun, in einigen Argumenten zu meinem Programm übergeben nannte dies, Ich könnte so etwas sagen wie. / Das ist cs 50. Dies ist, was wir David zu tun vorstellen jeden Tag am Terminal. Aber jetzt ist die wichtigste Funktion innerhalb des Programms hat diese Werte, so argc ist 4. Es könnte ein wenig verwirrend, weil wir wirklich nur auf der Durchreise sind in ist cs 50. Das ist nur 3. Aber denken Sie daran, dass das erste Element von argv oder das erste Argument ist der Name der Funktion selbst. Das heißt also, dass wir 4 Dinge hier haben, und das erste Element wird. / dies sein. Und dies wird als Zeichenfolge dargestellt werden. Dann werden die restlichen Elemente sind, was wir in nach dem Namen des Programms eingegeben. Also nur so nebenbei, wie wir sahen wohl in pset 2, erinnern, dass die Zeichenfolge 50 die Zahl 50 ist ≠. So können wir nicht sagen etwas wie: 'int x = argv 3. Das ist einfach nicht sinnvoll, denn dies ist ein String, und das ist eine ganze Zahl. Also, wenn Sie zwischen den 2 konvertieren möchten, denken Sie daran, wir sind zu gehen haben diese magische Funktion namens atoi. Das nimmt einen String und gibt die Zahl innerhalb dieser Zeichenkette repräsentiert. Also das ist eine einfache Fehler, auf das Quiz zu machen, nur denken, dass dies automatisch der richtige Typ sein. Aber wissen nur, dass diese immer Strings auch wenn die Zeichenfolge enthält nur eine ganze Zahl oder ein Zeichen oder einen Schwimmer. So, jetzt lassen Sie uns über Laufzeit reden. Wenn wir alle diese Algorithmen, die all diese verrückten Dinge zu tun haben, wird es wirklich sinnvoll, die Frage zu stellen: "Wie lange sie dauern?" Wir vertreten, dass mit einem so genannten asymptotischen Notation. So bedeutet dies, dass - nun, sagen wir, wir geben unser Algorithmus einige wirklich, wirklich, wirklich großen Eingang. Wir wollen die Frage stellen: "Wie lange wird es dauern? Wie viele Schritte wird es dauern, unser Algorithmus zu laufen in Abhängigkeit von der Größe des Eingangssignals? " So ist die erste Art, wie wir die Zeit beschreiben kann, ist mit großen O. Und das ist unser Worst-Case-Laufzeit. Wenn wir also ein Array sortieren möchten, und wir geben unser Algorithmus eine Reihe das ist in absteigender Reihenfolge, wenn es in aufsteigender Reihenfolge sein sollte, das wird sich im schlimmsten Fall zu sein. Dies ist unsere im oberen maximale Zeitdauer der Algorithmus nimmt gebunden. Auf der anderen Seite wird diese Ω werde besten Fall Laufzeit beschreiben. Also, wenn wir geben eine bereits sortierte Array zu einem Sortieralgorithmus, wie lange wird es dauern, sie zu sortieren? Und dies, dann beschreibt eine untere Schranke für Laufzeit. Also hier sind nur einige Wörter, die einige gemeinsame Laufzeiten beschreiben. Dies sind in aufsteigender Reihenfolge. Die schnellste Laufzeit haben wir genannt konstant. Das bedeutet, egal wie viele Elemente, die wir unseren Algorithmus geben, egal wie groß unser Angebot ist sortieren sie oder zu tun, was wir auf das Array zu tun wird immer die gleiche Menge an Zeit. So können wir, dass nur mit einer 1, die eine Konstante ist repräsentieren. Wir haben uns auch logarithmische Laufzeit. So etwas wie binäre Suche ist logarithmisch, wo wir schneiden das Problem in der Hälfte jedes Mal und dann die Dinge einfach höher zu von dort. Und wenn Sie jemals das Schreiben eines O jeder factorial Algorithmus sollten Sie wahrscheinlich nicht sehen dies als Ihren Job. Wenn wir Laufzeiten zu vergleichen ist es wichtig, im Hinterkopf behalten, diese Dinge. Also, wenn ich einen Algorithmus, der O (n) ist, und jemand anderes wurde ein Algorithmus von O (2n) sind tatsächlich asymptotisch äquivalent. Also, wenn wir uns vorstellen, n, um eine große Zahl wie eleventy Milliarden sein: so, wenn wir den Vergleich eleventy Milliarden so etwas wie eleventy Milliarden + 3, plötzlich, dass drei nicht wirklich einen großen Unterschied mehr. Das ist, warum wir beginnen bedenkt diese Dinge gleichwertig sind. So Dinge wie diese Konstanten hier gibt es 2 x dies oder das Hinzufügen eines 3, dies sind nur Konstanten, und diese werden würde sinken auf. Also das ist, warum alle 3 dieser Laufzeiten dasselbe wie zu sagen, sie sind O (n) sind. Ebenso, wenn wir 2 weitere Laufzeiten haben, sagen wir O (n ³ + 2n ²), können wir hinzufügen + N, + 7, und dann haben wir eine andere Laufzeit, die nur O ist (n ³). Auch diese dasselbe, da diese - diese nicht gleich sind. Dies sind die gleichen Dinge, sorry. Das sind also gleich, weil Diese n ³ wird diesen 2n ² dominieren. Was ist nicht dasselbe ist, wenn wir Zeiten wie O (n ³) und O ausgeführt haben (n ²) weil diese n ³ ist viel größer als dieser n ². Also, wenn wir Exponenten haben, plötzlich diese beginnt Rolle, aber wenn wir nur den Umgang mit Faktoren wie wir hier sind, dann ist es nicht die Materie, weil sie sich nur noch herausfallen. Werfen wir einen Blick auf einige der Algorithmen, die wir bisher gesehen haben und über ihre Laufzeit zu sprechen. Der erste Weg auf der Suche nach einer Nummer in einer Liste, die wir sahen, war lineare Suche. Und die Umsetzung der linearen Suche ist super einfach. Wir haben eine Liste, und wir werden auf jedem einzelnen Element in der Liste zu suchen bis wir die Anzahl finden wir suchen. Das heißt also, daß im schlimmsten Fall diese O (n). Und der schlechteste Fall hier sein könnte, wenn das Element das letzte Element, dann mit linearer Suche müssen wir bei jedem einzelnen Element zu betrachten bis wir das letzte zu bekommen, um zu wissen, dass es eigentlich in der Liste. Wir können nicht einfach aufgeben halbem Weg und sagen: "Es ist wahrscheinlich nicht dort." Mit lineare Suche haben wir an der ganzen Sache zu suchen. Die besten Fall Laufzeiten, eine auf der anderen Seite, ist konstant weil im besten Fall das Element, das wir suchen, ist nur der erste in der Liste. So, es wird nehmen uns genau 1 Schritt, egal wie groß die Liste ist wenn wir für das erste Element suchen jedesmal. Also, wenn Sie suchen, denken Sie daran, ist es nicht erforderlich, dass unsere Liste sortiert werden. Weil wir einfach gehen zu über jedes einzelne Element zu betrachten, und es ist nicht wirklich wichtig welcher Reihenfolge diese Elemente sind in. Eine intelligente Suchalgorithmus ist so etwas wie binäre Suche. Denken Sie daran, ist die Umsetzung der binären Suche, wenn Sie gehst halten Sie auf die Mitte der Liste. Und weil wir in der Mitte suchen, verlangen wir, dass die Liste sortiert ist sonst werden wir nicht wissen, wo die Mitte ist, und wir müssen schauen über die ganze Liste, um sie zu finden, und dann an diesem Punkt sind wir nur Zeit verschwenden. Also, wenn wir eine sortierte Liste und haben wir in der Mitte, wir gehen, um die Mitte zu vergleichen dem Element, das wir suchen. Ist sie zu hoch ist, dann können wir vergessen, die rechte Hälfte weil wir wissen, dass, wenn unsere Element ist bereits zu hoch und alles, was auf der rechten Seite dieses Elements ist sogar noch höher, dann brauchen wir nicht mehr dort zu suchen. Wo auf der anderen Seite, wenn unser Element zu niedrig ist, Wir wissen alles links dieses Elements ist auch zu gering, so dass es nicht wirklich Sinn, dort zu suchen, entweder. Auf diese Weise, mit jedem Schritt und jeder Zeit schauen wir in der Mitte der Liste, werden wir unser Problem in zwei Hälften geschnitten, weil plötzlich wissen wir, eine ganze Reihe von Zahlen, die nicht das, was wir suchen können. In Pseudocode würde dies so aussehen, und weil wir schneiden die Liste in der Hälfte jedes einzelne Mal, unseren worst-case Laufzeit Sprünge von linear auf logarithmisch. So haben wir plötzlich log-in Schritte, um ein Element in einer Liste zu finden. Das Best-Case-Laufzeiten, aber ist noch konstant denn jetzt, lasst uns einfach sagen, dass das Element, das wir suchen, ist immer die genaue Mitte der ursprünglichen Liste. So können wir unsere Liste so groß, wie wir wollen wachsen, aber wenn das Element wir suchen, ist in der Mitte, dann ist es nur noch zu nehmen uns ein Schritt. Also das ist, warum wir O (log n) und Ω (1) oder konstant sind. Lasst uns tatsächlich ausgeführt binäre Suche auf dieser Liste. Also lasst uns sagen, dass wir für das Element 164 suchen. Das erste, was wir tun werden, ist zu finden den Mittelpunkt dieser Liste. Es passiert einfach so, dass der Mittelpunkt wird fallen zwischen diesen 2 Zahlen, so lasst uns einfach willkürlich sagen, jedes Mal, wenn der Mittelpunkt liegt zwischen 2 Zahlen, lasst uns einfach aufrunden. Wir müssen nur sicherstellen, dass wir dies tun bei jedem Schritt des Weges. So werden wir zu runden, und wir gehen zu sagen, dass 161 der Mitte unserer Liste ist. So 161 <164, und jedes Element auf der linken Seite 161 ist auch <164, so wissen wir, dass es nicht geht, um uns überhaupt helfen damit zu beginnen, über hier, weil das Element wir nicht dabei sein kann suchen. Also, was wir tun können ist, können wir nur über diese ganze linke Hälfte der Liste vergessen, und jetzt nur von der rechten Seite des 161 weiter zu betrachten. Also noch einmal, das ist der Mittelpunkt; lasst uns einfach aufrunden. Jetzt 175 ist zu groß. So wissen wir, es ist nicht zu helfen, uns suchen hier oder hier, so können wir nur, dass wegwerfen, und schließlich werden wir die 164 getroffen. Haben Sie Fragen zum binäre Suche? Gehen wir von der Suche durch ein bereits sortierte Liste tatsächlich unter eine Liste von Zahlen in beliebiger Reihenfolge und macht diese Liste in aufsteigender Reihenfolge. Der erste Algorithmus, den wir betrachtet hieß bubble sort. Und das wäre einfacher der Algorithmen, die wir sahen. Bubble sort sagt, dass, wenn alle 2 Elemente innerhalb der Liste fehl am Platze sind, dh es ist eine höhere Zahl links von einer niedrigeren Anzahl, dann werden wir, um sie auszutauschen, weil das bedeutet, dass die Liste wird "Mehr sortiert", als es vorher war. Und wir gerade dabei, diesen Prozess wieder fortgesetzt und immer wieder bis schließlich die Elemente Art Blase an den richtigen Ort, und wir haben eine sortierte Liste. Die Laufzeit dies wird O (n ²). Warum? Nun, weil im schlimmsten Fall, werden wir jedes Element zu nehmen, und wir gehen, um am Ende den Vergleich mit jedem anderen Element in der Liste. Aber im besten Fall haben wir eine bereits sortierte Liste, bubble sort die gerade dabei, einmal durch zu gehen, sagen: "Nope. Ich machte keine Swaps, so bin ich fertig." Also haben wir ein best-case Laufzeit von Ω (n). Laufen wir bubble sort auf einer Liste. Oder zuerst herausfinden, lasst uns einfach irgendwann Pseudocode wirklich schnell zu suchen. Wir wollen sagen, wir wollen, um zu verfolgen, in jeder Iteration der Schleife, im Auge behalten, ob wir nicht verändert keine Elemente. So der Grund dafür ist, werden wir aufhören, wenn wir keine Elemente vertauscht. So am Anfang unserer Schleife haben wir nichts getauscht, so dass wir sagen, das ist falsch. Nun, wir gehen durch die Liste gehen und vergleichen Element i zu Element i + 1 und wenn es der Fall ist, dass es eine größere Zahl links von einer kleineren Anzahl, dann sind wir gerade dabei, sie zu tauschen. Und dann werden wir daran erinnern, dass wir ein Element ausgetauscht. Das bedeutet, dass wir durch die Liste gehen mindestens 1 mehr Zeit benötigen weil der Zustand, in dem wir anhielten, wenn die gesamte Liste bereits sortiert ist, dh wir haben keine Swaps. Also das ist, warum unsere Lage hier unten ist ", während einige Elemente vertauscht worden." So, jetzt lass uns einfach an dieser läuft auf einer Liste zu suchen. Ich habe die Liste 5,0,1,6,4. Bubble-Sort wird den ganzen Weg auf der linken Seite beginnen, und es wird zu vergleichen i die Elemente, so 0 bis i + 1, wobei das Element 1 ist. Es wird gesagt, gut 5> 0, aber im Moment 5 ist auf der linken Seite so brauche ich, um die 5 und die 0 zu tauschen. Als ich sie zu tauschen, plötzlich bekomme ich diese andere Liste. Jetzt 5> 1, so werden wir sie zu tauschen. 5 ist nicht> 6, so brauchen wir nicht, hier etwas zu tun. Aber 6> 4, so müssen wir tauschen. Auch hier müssen wir durch die ganze Liste, um schließlich zu entdecken laufen dass diese sind nicht in Ordnung, und wir tauschen sie, und an diesem Punkt müssen wir durch die Liste laufen 1 mehr Zeit um sicherzustellen, dass alles in seiner Ordnung ist, und an diesem Punkt bubble sort beendet wurde. Ein anderer Algorithmus für die Aufnahme einige Elemente und sortiert sie ist die Auswahl sort. Die Idee hinter Auswahl Art ist, dass wir gehen zum Aufbau einer sortierten Teil der Liste Ein Element zu einem Zeitpunkt. Und die Art und Weise wir, dass tun, ist durch den Aufbau der linken Segment der Liste. Und im Grunde jeden - auf jedem Schritt werden wir das kleinste Element, das wir verlassen haben nehmen das wurde noch nicht sortiert, und wir werden ihn in dieser sortierten Segment bewegen. Das heißt, wir müssen ständig finden die minimale unsortierten Element und dann, dass die kleinste Element und tauschen Sie ihn mit dem, was links am Element, das ist nicht sortiert. Die Laufzeit dieser wird O (n ²), da im schlimmsten Fall wir brauchen, um jedes einzelne Element mit jedem anderen Element zu vergleichen. Denn wir sagen, dass, wenn wir auf der linken Hälfte der Liste zu starten, müssen wir durch die gesamte rechte Segment gehen, um das kleinste Element finden. Und dann wieder, müssen wir gehen über die gesamte rechte Segment und keep going auf, dass immer und immer und immer wieder. Das wird n ² sein. Wir werden eine for-Schleife innerhalb einer anderen for-Schleife muss was darauf hindeutet, n ². Im besten Fall Gedanken, sagen wir, wir geben ihm eine bereits sortierte Liste; wir eigentlich nicht besser als n ². Weil Auswahl Art hat keine Möglichkeit zu wissen, dass das kleinste Element ist nur die, die ich gerade am suchen. Es muss noch dafür sorgen, dass dies tatsächlich das Minimum. Und der einzige Weg, um sicherzustellen, dass es das Minimum ist, mit diesem Algorithmus, ist es, an jedem einzelnen Element wieder anzusehen. Also wirklich, wenn Sie ihm - wenn Sie geben Auswahl sort eine bereits sortierte Liste, es wird nicht zu einem besseren zu tun, als ihm eine Liste, die nicht sortiert ist leer. By the way, wenn es der Fall zu sein passiert, dass etwas O (etwas) und das Omega von etwas, können wir nur kurz und bündig, dass es θ etwas sagen. Also, wenn Sie sehen, dass kommen überall, das ist, was das bedeutet nur. Wenn etwas Theta von n ² ist es sowohl big O (n ²) und Ω (n ²). So best case und worst case, ist es nicht einen Unterschied machen, Der Algorithmus wird dasselbe tun jedesmal. Also das ist, was Pseudocode zur Auswahl Art aussehen könnte. Wir sind im Grunde zu sagen, dass ich durchlaufen die Liste wollen, von links nach rechts, und bei jeder Iteration der Schleife, ich werde zu bewegen die minimale Element in dieser sortierten Teil der Liste. Und wenn ich etwas bewegen gibt, habe ich nie brauchen, um dieses Element noch einmal an. Denn sobald ich ein Element auszutauschen, auf der linken Segment der Liste, es sortiert weil wir alles tun, in aufsteigender Reihenfolge, indem Minima. Also sagten wir, okay, wir an der Position i sind, und wir müssen schauen alle Elemente nach rechts von i, um die Minimum zu finden. So daß heißt, wir wollen von i + 1 bis zum Ende der Liste zu suchen. Und jetzt, wenn das Element, das wir derzeit auf der Suche bei weniger als unseren Mindestbestellwert so weit, die denken Sie daran, wir beginnen das Minimum aus, um nur sein, unabhängig Element sind wir derzeit auf, ich nehme an, das ist das Minimum. Wenn ich ein Element, das kleiner als das ist zu finden, dann werde ich sagen, okay, gut, ich habe ein neues Minimum gefunden. Ich werde daran zu erinnern, wo das Minimum lag. So, jetzt, nachdem ich habe durch dieses Recht unsortierten Segment gegangen, Ich kann sagen, ich werde das kleinste Element mit dem Element, das in Position i vertauschen. Das wird für den Aufbau meiner Liste, meine sortierten Teil der Liste von links nach rechts, und wir wissen nicht immer müssen zu einem Element wieder zu sehen, wenn es in diesem Teil ist. Sobald wir es getauscht. Also lasst uns laufen Auswahl Art auf dieser Liste. Das blaue Element hier wird das i zu sein, und die rote Element wird die minimale Element sein. So i beginnt den ganzen Weg auf der linken Seite der Liste, so bei 5. Jetzt müssen wir die minimale unsortierten Element zu finden. Also sagen wir 0 <5, so 0 mein neues minimal ist. Aber ich kann es nicht bleiben, denn auch wenn wir erkennen können, dass 0 die kleinste ist, wir brauchen, um durch jedes andere Element der Liste, um sicherzustellen, laufen. So 1 ist größer, 6 größer ist, ist 4 größer. Das bedeutet, dass nach einem Blick auf all diese Elemente, ich habe bestimmt 0 ist der kleinste. Also werde ich die 5 und die 0 zu tauschen. Sobald ich das tauschen, werde ich eine neue Liste zu bekommen, und ich weiß, dass ich nie brauchen, um die 0 wieder zu sehen denn wenn ich tauschte es habe, habe ich sie sortiert und wir sind fertig. Jetzt ist es einfach so passiert, dass das blaue Element ist wieder die 5, und wir müssen in der 1 zu sehen, die 6 und die 4 bis daß 1 zu bestimmen ist die kleinste kleinste Element, so dass wir die 1 und die 5 tauschen. Auch hier müssen wir zu sehen - vergleichen Sie die 5 auf die 6 und 4, und wir werden die 4 und die 5 wechseln und schließlich zu vergleichen diese 2 Zahlen und tauschen sie, bis wir unsere sortierte Liste zu bekommen. Haben Sie Fragen zur Auswahl Art? Okay. Lasst uns bis zum letzten Thema hier zu bewegen, und das ist Rekursion. Rekursion, denken Sie daran, das ist wirklich Meta Sache, wo eine Funktion ruft wiederholt sich. So an einem gewissen Punkt, während unsere fuction wiederholt, die sich selbst, es muss irgendwann an dem wir aufhören, uns selbst zu sein. Denn wenn wir das nicht tun, dann sind wir gerade dabei, dies auch weiterhin immer tun, und unser Programm ist einfach nicht zu kündigen. Wir nennen diesen Zustand der Base-Case. Und die Base-Case sagt, anstatt den Aufruf einer Funktion wieder Ich werde einfach einen Wert zurückgeben. Also, wenn wir einen Wert zurückgegeben haben, haben wir aufgehört ruft uns, und der Rest der Anrufe, die wir bisher gemacht haben können auch zurück. Das Gegenteil von dem Basisfall ist die rekursive Fall. Und das ist, wenn wir einen weiteren Aufruf der Funktion, dass wir momentan in. machen wollen Und wir wahrscheinlich, wenn auch nicht immer, wollen verschiedene Argumente verwenden. Also, wenn wir eine Funktion namens f, und f hat gerade angerufen nehmen Sie 1 Argument, und wir halten gerade Aufruf f (1), f (1), f (1), und es passiert einfach so, dass das Argument 1 fällt in rekursiven Fall sind wir noch nie zu stoppen. Selbst wenn wir ein Base-Case haben, müssen wir sicherstellen, dass wir schließlich wirst, dass base case getroffen. Wir wollen nicht nur zu halten Aufenthalt in diesem rekursiven Fall. Im Allgemeinen, wenn wir uns anrufen, wir wahrscheinlich zu haben, ein anderes Argument jeder Zeit. Hier ist eine wirklich einfache rekursive Funktion. So wird dies berechnet die Fakultät einer Zahl. Top-hier haben wir unsere Basis Fall. In dem Fall, dass n ≤ 1, werden wir nicht zu nennen factorial wieder. Wir gehen zu stoppen, wir sind gerade dabei, einen Wert zurückzugeben. Ist dies nicht wahr ist, dann werden wir unsere rekursive Fall getroffen. Beachten Sie hier, dass wir nicht nur fordern factorial (n), denn das wäre nicht sehr hilfreich. Wir gehen zu nennen Fakultät etwas anderes. Und damit Sie sehen können, schließlich, wenn wir ein factorial (5) oder etwas passieren, wir gehen zu nennen factorial (4) und so weiter, und schließlich werden wir dieses base case getroffen. Also das sieht gut aus. Mal sehen, was passiert, wenn wir laufen tatsächlich diese. Dies ist der Stapel, und lassen Sie uns sagen, dass Haupt wird diese Funktion mit einem Argument (4) nennen. Also, wenn factorial sieht und = 4, factorial wird selbst anruft. Jetzt, plötzlich, haben wir factorial (3). So sind diese Funktionen werde weiter wachsen, bis wir schließlich unsere Basis bei getroffen. An diesem Punkt ist der Rückgabewert dieser die Rückkehr (nx der Rückgabewert this), der Rückgabewert ist nx der Rückgabewert dafür. Schließlich müssen wir eine gewisse Anzahl getroffen. An der Spitze hier, sagen wir return 1. Das bedeutet, dass, wenn wir diese Zahl zurück, können wir dies aus dem Stapel Pop. Also das factorial (1) durchgeführt wird. Wenn 1 zurückkehrt, dies factorial (1) gibt, diese Rückkehr zum 1. Der Rückgabewert dieser, erinnere, war nx der Rückgabewert dafür. So plötzlich, weiß dieser Kerl, dass ich 2 zurückkehren wollen. Also denken Sie daran, zurückzukehren Wert dies ist nur nx der Rückgabewert hier oben. So, jetzt können wir sagen, 3 x 2, und schließlich, hier können wir sagen, dies ist gerade dabei, 4 x 3 x 2 sein. Und sobald dieser wieder erhalten wir auf eine einzige Zahl innerhalb von main. Haben Sie Fragen zu Rekursion? Gut. Es gibt also mehr Zeit für die Fragen am Ende, aber jetzt Joseph deckt die restlichen Themen. [Joseph Ong] Alles klar. So, jetzt haben wir über Rekursionen gesprochen, Reden wir ein wenig über das, was Mergesort ist. Mergesort ist im Grunde eine andere Art der Sortierung eine Liste von Zahlen. Und wie es funktioniert, mit Mergesort haben Sie eine Liste, und was wir tun, ist wir sagen, lasst uns aufgeteilt dies in 2 Hälften. Wir zum ersten Mal ausgeführt Mergesort wieder auf der linken Hälfte, dann werden wir laufen Mergesort auf der rechten Hälfte, und das gibt uns jetzt 2 Hälften, die sortiert werden, und jetzt werden wir diese Hälften miteinander zu kombinieren. Es ist ein bisschen schwer, ohne ein Beispiel zu sehen, so dass wir durch die Bewegungen gehen und sehen, was passiert. So starten Sie mit dieser Liste, wir haben es aufgeteilt in 2 Hälften. Wir laufen Mergesort auf der linken Hälfte erste. Damit ist die linke Hälfte, und jetzt laufen wir ihnen durch diese Liste wieder welches wird in Mergesort vergangen, und dann schauen wir wieder, auf der linken Seite der Liste und wir laufen Mergesort auf sie. Jetzt erhält man bis in eine Liste von Nummern 2, und nun die linke Hälfte ist nur 1 Element lang, und wir können nicht Aufgeteilt eine Liste, die nur 1 Element in die Hälfte ist, so dass wir nur sagen, wenn wir 50 haben, das ist nur ein Element, es ist bereits sortiert. Sobald wir damit fertig sind, können wir sehen, dass wir fahren Sie mit der rechten Hälfte dieser Liste und 3 ist auch sortiert, und so jetzt, dass beide Hälften dieser Liste sortiert werden können wir diese Zahlen wieder miteinander zu verbinden. So betrachten wir 50 und 3; 3 ist kleiner als 50, so geht es in einer ersten und dann 50 hereinkommt Nun, das ist geschehen, wir gehen wieder auf dieser Liste und sortieren es rechte Hälfte. 42 ist eine eigene Nummer, so ist es bereits sortiert. So jetzt haben wir vergleichen diese 2 und 3 ist kleiner als 42, so dass wird in erster Stelle, Jetzt 42 wird in gesetzt, und 50 wird gesetzt in. Nun, das ist sortiert, gehen wir den ganzen Weg zurück an die Spitze, 1337 und 15. Nun, schauen wir jetzt auf der linken Hälfte dieser Liste 1337 ist an sich so ist es sortiert und gleichzeitig mit 15. So, jetzt kombinieren wir diese 2 Zahlen, um die ursprüngliche Liste, 15 <1337 zu sortieren, so ist es in erster geht, dann 1337 geht in. Und jetzt haben wir sortiert beide Hälften der ursprünglichen Liste oben. Und alles, was wir tun müssen, ist diese kombinieren. Wir schauen uns die ersten 2 Zahlen dieser Liste, 3 <15, so geht es in der Art Array zuerst. 15 <42, so geht es in. Jetzt, 42 <1337, das geht in. 50 <1337, so geht es in. Und feststellen, dass wir nahmen 2 Zahlen aus dieser Liste. So sind wir nicht nur abwechselnd zwischen den 2 Listen. Wir suchen nur am Anfang, und wir nehmen das Element das ist kleiner und dann setzen sie in unser Angebot. Jetzt haben wir alle die Hälften zusammengeführt und wir sind fertig. Haben Sie Fragen zu Mergesort? Ja? [Student] Wenn es Aufspaltung ist in verschiedene Gruppen, warum sie nicht einfach aufgeteilt es einmal und Sie haben 3 und 2 in einer Gruppe? [Rest der Frage unverständlich] Der Grund - so stellt sich die Frage, warum können wir nicht einfach verschmelzen sie zu diesem ersten Schritt, nachdem wir sie haben? Der Grund warum wir dies tun können, auf der linken die meisten Elemente beider Seiten beginnen, und nehmen Sie dann die kleinere und steckte es in, ist, dass wir, dass diese wissen, einzelnen Listen sind in sortierter Aufträge. Also, wenn ich an den äußersten linken Elemente der beiden Hälften suchen, Ich weiß, sie werden die kleinsten Elemente dieser Listen sein. So kann ich sie in die kleinste Element Flecken dieser großen Liste zu setzen. Auf der anderen Seite, wenn ich mir diese 2 Listen in der zweiten Ebene drüben, 50, 3, 42, 1337 und 15, sind diejenigen nicht sortiert. Also, wenn ich bei 50 und 1337 schauen, ich werde 50 in meiner Liste an erster Stelle. Aber das macht nicht wirklich Sinn, weil 3 das kleinste Element aus allen von ihnen ist. So ist die einzige Grund, warum wir diese Kombination Schritt tun können, ist, weil unsere Listen bereits sortiert sind. Deshalb haben wir, um den ganzen Weg nach unten haben denn wenn wir nur eine einzige Nummer haben, wissen Sie, dass eine einzelne Zahl an und für sich ist bereits eine sortierte Liste. Haben Sie Fragen? Nein? Komplexität? Nun, man kann sehen, dass bei jedem Schritt gibt es Endzahlen und wir teilen kann eine Liste in der Hälfte log n Zeiten, das ist, wo wir diese n x log n Komplexität erhalten. Und du wirst sehen, im besten Fall für Mergesort ist n log n, und es passiert einfach so, , dass der schlimmste Fall, oder die Ω drüben, ist auch n log n. Etwas im Auge zu behalten. Umzug auf, lasst uns gehen auf einige super grundlegenden Datei-I / O. Wenn Sie an Scramble sah, werden Sie feststellen, hatten wir eine Art von System wo man in eine Protokolldatei zu schreiben, wenn Sie durch den Code zu lesen. Mal sehen, wie Sie das tun. Nun, wir haben fprintf, die Sie kann nur als printf denken, aber gerade Drucken auf einem Datei anstelle und damit die f zu Beginn. Diese Art von Code bis hier, was sie tut, ist, wie Sie in Scramble gesehen haben könnte, geht es durch Ihre 2-dimensionalen Array Druck zeilenweise, was die Zahlen sind. In diesem Fall printf druckt Ihr Terminal oder was wir die Standard-Ausgabe des Abschnitts. Und jetzt, in diesem Fall ist alles, was wir zu tun haben, zu ersetzen printf mit fprintf, sagen, was Datei, die Sie drucken möchten, und in diesem Fall ist es nur druckt sie auf diese Datei statt es auszudrucken Ihr Terminal. Na, dann, dass die Frage aufwirft: Wo bekommen wir diese Art von Datei von, richtig? Wir passierten Anmeldung bei diesem fprintf fuction aber wir hatten keine Ahnung, woher es kam. Nun, in den frühen Code, was wir hatten, war diese Stück Code hier rüber, die im Grunde sagt, dass Öffnen Sie die Datei log.txt nennt. Was wir danach ist zu tun, müssen wir sicherstellen, dass die Datei tatsächlich erfolgreich geöffnet. So könnte es aus mehreren Gründen scheitern, Sie haben nicht genug Speicherplatz auf Ihrem Computer, zum Beispiel. So ist es immer wichtig, bevor Sie Vorgänge mit der Datei machen dass wir prüfen, ob die Datei erfolgreich geöffnet wurde. Also, was, dass ein, das ist ein Argument für fopen, na ja, können wir eine Datei in vielerlei Hinsicht zu öffnen. Was wir können, ist zu tun, können wir sie weitergeben w, was bedeutet, überschreiben Sie die Datei, wenn sie bereits existiert, Wir können das Bestehen einer a, die sie bis zum Ende der Datei angehängt, anstatt zu überschreiben, oder wir können r geben, was bedeutet, öffnen wir die Datei als schreibgeschützt. Also, wenn das Programm versucht, Änderungen an der Datei vornehmen, schreien sie und lassen Sie sie nicht tun. Schließlich, wenn wir mit der Datei gemacht, fertig machen Operationen darauf, Wir müssen sicherstellen, dass wir die Datei zu schließen. Und so am Ende des Programms, wirst du sie wieder vorbei Diese Datei, die Sie öffnen und schließen Sie es. Das ist also etwas wichtig, dass Sie sicherstellen, dass Sie zu tun haben. Also denken Sie daran können Sie eine Datei öffnen, dann können Sie die Datei zu schreiben, tun Operationen in der Datei, aber dann müssen Sie die Datei am Ende zu schließen. Haben Sie Fragen zu den grundlegenden Datei-I / O? Ja? [Studenten Frage unverständlich] Genau hier. Die Frage ist, wo diese Datei log.txt erscheinen? Nun, wenn man ihnen nur das log.txt, schafft er es im selben Verzeichnis wie die ausführbare Datei. Also, wenn du bist - >> [Studentische Frage unverständlich] Ja. In dem gleichen Ordner oder im gleichen Verzeichnis, wie Sie es nennen. Jetzt Speicher, Stack und Heap. Also, wie ist der Speicher in den Computer verlegt? Nun, Sie können Speicher als eine Art dieser Block hier vorstellen. Und in Erinnerung haben wir, was den Haufen dort stecken, und den Stapel, die unten ist dort abgerufen werden. Und die Heap wächst nach unten und der Stapel wächst nach oben. So wie Tommy erwähnt - oh, gut, und wir haben diese 4 Segmente, die ich in einem zweiten bekommen - Als Tommy vorhin gesagt, Sie wissen, wie seine Funktionen selbst nennen und rufen einander? Sie bauen diese Art von Stack-Frame. Nun, wenn Haupt Anrufe foo, foo wird auf den Stapel gelegt. Foo ruft bar, bar erhalten die auf den Stapel gelegt, und das wird auf dem Stapel nach setzen. Und als sie zurück, sie jeweils Aussteigen aus dem Stapel entnommen. Was jeder dieser Standorte und Speicher zu halten? Nun, enthält die oberste, die der Text-Segment ist, das Programm selber. So den Maschinen-Code, das ist es, wenn Sie kompilieren Sie Ihr Programm. Weiter, alle globalen Variablen initialisiert. So haben Sie globale Variablen in Ihrem Programm, und Sie sagen, wie, a = 5, das wird in diesem Segment setzen, und rechts unter, dass Sie haben keine initialisierte globale Daten, die nur INT a, aber nicht sagen, es ist gleich nichts. Verwirklichen Sie sind globale Variablen, so dass sie außerhalb der main. Dies bedeutet also keine globalen Variablen, die deklariert, aber werden nicht initialisiert. Also, was ist in der Halde? Speicher zugewiesen werden, indem malloc, die wir in ein wenig bekommen. Und schließlich, mit dem Stapel haben Sie keine lokalen Variablen und alle Funktionen, die Sie vielleicht in einem der ihren Parametern aufrufen. Die letzte Sache, die Sie nicht wirklich wissen, was die Umgebungsvariablen zu tun, aber wenn Sie das Programm ausführen, es ist etwas verbunden, wie Dies ist der Benutzername der Person, die das Programm lief. Und das geht zu Art werden an der Unterseite. Im Hinblick auf die Speicheradressen, die hexadezimalen Werte sind, die Werte an der Spitze beginnen bei 0, und sie gehen den ganzen Weg hinunter auf den Boden. In diesem Fall, wenn Sie auf der 32-Bit-System, die Adresse, an der Unterseite sein wird 0x, gefolgt von af, denn das ist 32 Bit, welches 8 Byte, und in diesem Fall 8 Byte entspricht 8 Hexadezimalzahlen. So hier unten wirst du haben, mögen, 0xffffff und dort wirst du 0 haben. Also, was sind Zeiger? Einige von Ihnen mögen dies nicht in Abschnitt behandelt zuvor. aber wir haben darüber in der Vorlesung zu gehen, so ist ein Zeiger nur ein Datentyp die Geschäfte, anstatt irgendeine Art von Wert wie 50, die Adresse des irgendeiner Stelle im Speicher speichert. Wie dieser Speicher [unverständlich]. Also in diesem Fall, was wir haben, ist, wir haben ein Zeiger auf einen Integer oder int *, und es enthält dieses hexadezimale Adresse 0xDEADBEEF. Also, was wir haben, ist, jetzt, diese Zeiger an irgendeiner Stelle im Speicher, und dass nur ein, sich der Wert 50 in dieser Speicherstelle. Auf einigen 32-Bit-Systemen auf allen 32-Bit-Systeme, nehmen Zeiger bis 32 Bits oder 4 Bytes. Aber beispielsweise auf einem 64-Bit-System sind Zeiger 64 Bits. Also das ist etwas, was Sie wollen, im Auge zu behalten werde. So auf einer Ende-Bit-System ist ein Zeiger Ende Bit lang. Zeiger sind eine Art schwer zu verdauen, ohne zusätzliche Dinge, also lasst uns durch ein Beispiel dynamische Speicherzuweisung gehen. Was dynamische Speicherzuweisung für Sie tut, oder wie wir es nennen malloc, es lässt Sie zuordnen irgendeine Art von Daten außerhalb des Sets. So werden diese Daten ist eine Art dauerhafter für die Dauer des Programms. Denn wie Sie wissen, wenn Sie erklären, x innerhalb einer Funktion, und dass Funktion zurückkehrt, Sie haben keinen Zugriff mehr auf die Daten, die in x gespeichert wurde. Was Zeigern wir tun, ist sie uns speichern Speicher oder Speicher-Werte in einem anderen Segment des Speichers, nämlich des Heap. Nun, wenn wir wieder außer Funktion, solange wir einen Zeiger haben an diesem Ort im Speicher, dann das, was wir tun können ist, können wir nur auf die Werte dort zu suchen. Lassen Sie uns ein Beispiel an: Das ist unser Speicher-Layout wieder. Und wir haben diese Funktion main. Was sie tut, ist - okay, so einfach, nicht wahr? - Int x = 5, das ist nur eine Variable auf dem Stack in main. Auf der anderen Seite, jetzt haben wir einen Zeiger deklarieren, die die Funktion giveMeThreeInts nennt. Und nun haben wir in dieser Funktion gehen und wir erstellen eine neue Stack-Frame für sie. Allerdings ist in diesem Stack-Frame, erklären wir int * temp, die in mallocs 3 Zahlen für uns. So Größe int wird uns, wie viele Bytes diesem int ist, und malloc gibt uns, dass viele Byte an Speicherplatz auf dem Heap. Also in diesem Fall haben wir genug Platz für 3 Zahlen erstellt, und der Haufen ist da oben, das ist, warum ich es gezeichnet haben höher. Sobald wir fertig sind, wir kommen wieder hier, brauchen Sie nur 3 ints zurückgekehrt, und es gibt die Adresse, in diesem Fall über wenn dieser Speicher ist. Und wir setzen pointer = Schalter, und dort haben wir nur einen weiteren Zeiger. Aber was diese Funktion kehrt hier gestapelt und verschwindet. So Temp verschwindet, aber wir behalten trotzdem die Adresse, wo diese 3 Zahlen sind innerhalb Netz. So in diesem Set sind die Zeiger scoped lokal für die gestapelten Rahmen, aber der Speicher, auf den sie sich beziehen, ist in der Halde. Macht das Sinn? [Student] Könnten Sie das wiederholen? >> [Joseph] Ja. Also, wenn ich wieder nur ein wenig gehen, sehen Sie, dass temporäre zugeordnet einige Speicher auf dem Heap up there. Also, wenn diese Funktion, giveMeThreeInts zurückkehrt, dieser Stapel hier wird verschwinden. Und mit ihm jede der Variablen, in diesem Fall, diese Zeiger, der in gestapelter Rahmen zugewiesen wurde. Das wird verschwinden, aber da wir Temp zurück und wir setzen pointer = temp, Zeiger ist nun den gleichen Speicher Speicherort wie Temperatur war zu zeigen. So, jetzt, auch wenn wir verlieren, temp, dass lokale Zeiger, wir immer noch die Speicheradresse, was es wurde innerhalb dieser Variablen Zeiger. Haben Sie Fragen? Das kann eine Art verwirrendes Thema sein, wenn man nicht über sie in Abschnitt gegangen. Wir können Ihre TF definitiv vorbei zu gehen und natürlich können wir Fragen beantworten am Ende der Überprüfung Session für diese. Aber dies ist eine Art komplexes Thema, und ich habe weitere Beispiele, die gehen zu zeigen, bis sich das hilft zu klären, was Zeiger tatsächlich sind. In diesem Fall sind Zeiger entspricht Arrays, so kann ich nur diesen Zeiger verwenden, als die gleiche Sache wie ein int-Array. Also bin ich in 0 Indizierung und das Ändern der ersten Ganzzahl 1, Ändern des zweiten ganzzahligen bis 2, und die dritte ganze Zahl bis 3 ist. So mehr auf Zeigern. Nun, Binky erinnern. In diesem Fall haben wir einen Zeiger zugeordnet, oder erklärten wir einen Zeiger, aber zunächst, wenn ich gerade erklärt einen Zeiger, ist es nicht zeigen, um überall im Speicher. Es ist nur Müll Werte darin. Also ich habe keine Ahnung, wo dieser Zeiger auf zeigt. Es hat eine Adresse, die nur mit 0 und 1 ist, wo es zunächst erklärt wurde gefüllt ist. Ich kann nichts mit, bis ich malloc dafür aufrufen und dann gibt es mir ein wenig Platz auf dem Heap, wo ich Werte setzen können innen. Dann wieder, ich weiß nicht, was drin ist dieser Speicher. Also das erste, was ich tun müssen, ist zu prüfen, ob das System genügend Speicher hatten zu geben, mich zurück 1 integer in erster Linie, weshalb ich das überprüfen möchte, ist. Wenn Zeiger ist null, das heißt, dass es nicht genug Platz oder eine andere Fehler aufgetreten ist, also sollte ich Ausfahrt aus meinem Programm.  Aber wenn es gelänge, jetzt kann ich mit diesem Zeiger und was * Zeiger tut, ist es folgt, wo die Adresse dorthin, wo dieser Wert ist, und setzt es gleich 1 ist. So hier, wir überprüfen, ob diese Erinnerung existierte. Sobald Sie wissen, es existiert, kann man hineinsteckt welchen Wert Sie hineinsteckt, in diesem Fall ein. Sobald wir damit fertig sind, müssen Sie, dass Zeiger befreien weil wir, um wieder auf das System, dass der Speicher, die Sie für in erster Linie gefragt, benötigen. Da der Computer nicht wissen, wann wir damit fertig sind. In diesem Fall werden wir explizit sagen Sie es durch, okay, wir sind mit dieser Erinnerung getan. Wenn ein anderer Prozess braucht es, ein anderes Programm braucht, fühlen Sie sich frei, gehen Sie vor und nehmen Sie es. Was wir auch tun, ist, können wir nur erhalten, die Adresse der lokalen Variablen auf dem Set. So int x innerhalb des gestapelten Rahmen main. Und wenn wir dieses kaufmännisches verwenden, dies und Betreiber, was sie tut, ist es dauert x und x ist nur einige Daten im Speicher, aber es hat eine Adresse. Es ist irgendwo befindet. So unter der Telefonnummer & x, was dieser tut, ist, es gibt uns die Adresse von x. Auf diese Weise machen wir Zeiger Punkt, wo x im Speicher befindet. Jetzt müssen wir nur noch so etwas wie * x, wir gehen bis 5 zurück. Der Stern heißt Dereferenzierung es. Sie folgen der Adresse ein und Sie erhalten den Wert von ihm dort gespeichert. Haben Sie Fragen? Ja? [Student] Wenn Sie das nicht tun die 3-spitzen Sache, dauert es noch kompilieren? Ja. Wenn Sie das nicht tun die 3-Zeiger Sache, es ist immer noch zu kompilieren, aber ich werde Ihnen zeigen, was passiert, in einem zweiten, und ohne das tun, das ist, was wir ein Speicherverlust nennen. Sie geben nicht auf das System Sichern seinem Speicher, so dass nach einer Weile das Programm wird zu akkumulieren Erinnerung, dass es nicht mit, und nichts anderes kann es benutzen. Wenn Sie jemals Firefox mit 1,5 Millionen Kilobyte auf Ihrem Computer gesehen haben, im Task-Manager ist das, was vor sich geht. Sie haben einen Speicherverlust in dem Programm, dass sie nicht die Handhabung. Also, wie funktioniert Zeigerarithmetik Arbeit? Nun, das ist Zeigerarithmetik Art wie die Indizierung in einem Array. In diesem Fall habe ich einen Zeiger, und was ich mache ist, dass ich einen Zeiger auf das erste Element dieses Arrays von 3 Zahlen, die ich zugewiesen. So, jetzt, was ich tue, Stern Mauszeiger ändert nur das erste Element in der Liste. Star Pointer +1 Punkte hier. So Mauszeiger über hier ist, Zeiger ein Ende ist hier, ist Zeiger 2 hier. Also nur die Zugabe von 1 ist die gleiche wie die sich entlang dieses Arrays. Was wir tun müssen, ist, wenn wir Zeiger ein bekommt man die Adresse hier rüber, und um den Wert in hier zu bekommen, setzen Sie einen Stern in der gesamten Ausdrucks um es dereferenzieren. Also, in diesem Fall, ich Einstellen der ersten Stelle in diesem Array Anspruch 1, zweiten Stelle bis 2 und dritten Stelle bis 3 ist. Dann, was ich tue hier ist, dass ich zum Ausdrucken unserer Zeiger +1, das gibt mir nur 2. Jetzt bin ich Inkrementieren Zeiger, so Zeiger gleich Zeiger +1, was bewegt sie sich vorwärts. Und jetzt, wenn ich ausdrucken Zeiger +1, ist Zeiger ein nun 3, die in diesem Fall drei druckt. Und um kostenlos etwas, der Zeiger, dass ich es geben muss am Anfang des Arrays, die ich zurück von malloc zeigen. Also, in diesem Fall, wenn ich 3 rechts hier nennen würde, wäre dies nicht richtig sein, denn es ist in der Mitte des Arrays. Ich habe zu subtrahieren, um zum ursprünglichen Standort zu erhalten die anfängliche erste Stelle vor, ich kann es zu befreien. So, hier ist ein komplizierteres Beispiel. In diesem Fall sind wir Zuteilung 7 Zeichen in einer Zeichen-Array. Und in diesem Fall, was wir tun ist, dass wir über die ersten 6 von ihnen Looping, und wir setzen sie Z. Also, für int i = 0, i> 6, i + +, So, Zeiger + i wird nur uns, in diesem Fall, Zeiger, Zeiger 1, 2 Zeiger, Zeiger 3, und so weiter und so fort in der Schleife. Was es tun werden, ist es kommt, dass die Adresse, dereferenziert es um den Wert zu erhalten, und Änderungen, die Wert auf einen Z. Dann am Ende vergessen, das ist eine Zeichenkette, nicht wahr? Alle Strings müssen mit dem null abschließende Zeichen enden. Also, was ich tue, ist in Zeiger 6 ich die null Endzeichen setzen in. Und jetzt, was ich im Grunde tun als hier printf Umsetzung für eine Zeichenfolge, nicht wahr? Also, wenn printf jetzt, wenn es das Ende eines Strings erreicht? Wenn es die null abschließende Zeichen trifft. Also, in diesem Fall, meine ursprünglichen Zeiger zeigt auf den Anfang dieses Arrays. Ich drucke das erste Zeichen aus. Ich bewege sie über ein. Ich drucke diesen Charakter aus. Ich bewege es vorbei. Und ich halte dies zu tun, bis ich das Ende zu erreichen. Und nun ist das Ende * Zeiger dereferenzieren dies und nutzen Sie die null abschließende Zeichen zurück. Und so meine while-Schleife läuft nur, wenn dieser Wert nicht die null abschließende Zeichen. So, jetzt beende ich aus dieser Schleife. Und so, wenn ich subtrahieren 6 von diesem Zeiger, Ich gehe den ganzen Weg zurück an den Anfang. Denken Sie daran, ich tue dies, weil ich an den Anfang zu gehen, um sie zu befreien. Also, ich weiß, das war eine Menge. Gibt es irgendwelche Fragen? Bitte, ja? [Studenten Frage unverständlich] Können Sie sagen, dass lauter? Entschuldigung. [Student] Auf der letzten Folie rechts, bevor Sie den Mauszeiger befreit, wo waren Sie tatsächlich ändern Sie den Wert des Zeigers? [Joseph] So, genau hier. >> [Student] Oh, okay. [Joseph] Also, ich habe einen Zeiger minus minus, rechts, was bewegt die Sache wieder ein, und dann bin ich frei, damit, weil diese Zeiger hat, um zum Anfang des Arrays hingewiesen werden. [Student] Aber das wäre nicht nötig hatten Sie nach dieser Zeile gestoppt werden. [Joseph] Also, wenn ich nach dieser aufgehört hatte, wäre dies als ein Speicherverlust werden, weil ich nicht laufen frei. [Student] I [unverständlich] nach den ersten drei Zeilen, wo Sie hatte Zeiger +1 [unverständlich]. [Joseph] Uh-huh. Also, was ist die Frage da? Entschuldigung. Nein nein. Geh, geh, bitte. [Student] So, du bist nicht ändern Sie den Wert von Zeigern. Sie hätte nicht Zeiger minus minus tun haben. [Joseph] Ja, genau. Also, wenn ich Zeiger 1 und Zeiger 2 zu tun, Ich mache das nicht Zeigers entspricht Zeiger +1. So bleibt der Zeiger gerade zu Beginn des Arrays verbunden. Es ist nur, wenn I plus zu tun und dass es setzt den Wert wieder in den Zeiger, dass es tatsächlich bewegt diese entlang. Gut. Noch Fragen? Auch wenn dies ist eine Art von überwältigender, wird dies in der Sitzung abgedeckt werden. Fragen Sie Ihren Unterricht Kollegen darüber, und wir können Fragen am Ende beantworten. Und in der Regel die wir nicht mögen, um dieses minus tun. Dies hat zu verlangen, mich zu verfolgen, wie viel ich in der Array-Offset. Also, in der Regel ist dies nur, wie Zeigerarithmetik Werke erklären. Aber was wir normalerweise tun möchte ist, dass wir gerne eine Kopie des Zeigers zu schaffen, und dann werden wir diese Kopie, wenn wir bewegen uns in die Zeichenkette. Also, in diesen Fall verwenden Sie die Kopie, um die gesamte Zeichenfolge zu drucken, aber wir wissen nicht wie Zeiger minus 6 zu tun oder zu verfolgen, wie viel wir zogen in diesem, nur weil wir wissen, dass unsere ursprünglichen Punkt noch an den Anfang der Liste hingewiesen und alles, was wir verändert war diese Kopie. So im Allgemeinen, zu verändern Kopien Ihrer ursprünglichen Zeiger. Versuchen Sie nicht, der, wie zu sortieren - tun nicht verändern ursprünglichen Exemplaren. Der Versuch, nur Kopien der ursprünglichen verändern. So stellen Sie fest, wenn wir den String in printf übergeben Sie müssen nicht um einen Stern vor sich legte, wie wir mit all den anderen dereferences getan, nicht wahr? Also, wenn Sie drucken die gesamte Zeichenfolge% s erwartet, ist eine Adresse, und in diesem Fall ein Zeiger oder in diesem Fall wie ein Array von Zeichen. Characters, char * s, und Arrays sind ein und dasselbe. Pointer ist Zeichen und Zeichen-Arrays sind ein und dasselbe. Und so ist alles, was wir zu tun haben, in Zeiger übergeben. Wir müssen nicht in gleicher * Zeiger oder so etwas passieren. So sind Arrays und Zeiger die gleiche Sache. Wenn du tust so etwas wie x [y] hier für ein Array, was es unter der Haube tut, ist es zu sagen, okay, es ist ein Zeichen-Array, es ist also ein Zeiger. Und so x sind die gleiche Sache, und so, was es tut, ist es fügt y nach x, das ist das gleiche wie vorwärts in Erinnerung, dass viel. Und jetzt x + y gibt uns irgendeine Art von Adresse, und wir dereferenzieren die Adresse oder folgen Sie dem Pfeil , wo dieser Ort im Speicher ist, und wir erhalten den Wert aus dieser Stelle im Speicher. So, so sind diese beiden genau die gleiche Sache. Es ist nur ein syntaktischer Zucker. Sie tun das gleiche. Sie sind einfach anders Syntaktik für einander. Also, gehen kann, was mit Zeigern falsch? Wie, eine Menge. Okay. Also, schlechte Dinge. Einige schlechte Dinge, die Sie tun können, werden nicht überprüft, wenn Ihr malloc Aufruf liefert null, nicht wahr? In diesem Fall bitte ich das System mir zu geben - was ist diese Zahl? Wie 2 Milliarden Mal 4, da die Größe eines ganzzahligen 4 Bytes ist. Ich frage es wie 8 Milliarde Bytes. Natürlich mein Computer ist nicht in der Lage sein, mir so viel Speicher zurück. Und wir haben nicht überprüfen, ob diese null ist, so dass, wenn wir zu dereferenzieren es dort zu versuchen - folgen Sie dem Pfeil, wo es wird - haben wir nicht, dass der Speicher. Dies ist, was wir Dereferenzierung eines Null-Zeiger aufrufen. Und dies im Wesentlichen verursacht Sie segfault. Dies ist eine der Möglichkeiten, wie Sie segfault. Andere schlechte Dinge, die Sie tun können - oh well. Das war Dereferenzierung eines NULL-Zeiger. Okay. Andere schlechte Dinge - ja, zu beheben, dass Sie nur ein Häkchen drin dass überprüft, ob der Zeiger NULL ist und verlassen Sie aus dem Programm, wenn es passiert, dass malloc gibt ein NULL-Zeiger. Das ist die xkcd Comic. Die Leute verstehen es jetzt. Irgendwie. So Speicher. Und ich ging über diese. Wir nennen malloc in einer Schleife, aber jedes Mal, wir rufen malloc wir verlieren den Überblick, wo diese Zeiger verweist, weil wir verprügeln sie. So gibt der erste Aufruf von malloc mich Speicher über hier. Meine Zeiger Zeiger auf diese. Nun, ich weiß nicht befreien sie, so dass ich jetzt rufen malloc wieder. Nun weist hier. Jetzt mein Gedächtnis zeigen hier. Pointing hier. Pointing hier. Aber ich habe den Überblick über die Adressen aller dem Speicher über hier, dass ich zugeteilt verloren. Und so jetzt habe ich keinen Bezug auf sie nicht mehr. Also, ich kann nicht befreien sie außerhalb dieser Schleife. Und so, um zu beheben etwas wie dieses, wenn Sie vergessen, um Speicher frei und Sie erhalten diesen Speicherverlust, Sie müssen den Speicher innerhalb dieser Schleife zu befreien, wenn Sie damit fertig sind. Nun, das ist, was passiert. Ich weiß, viele von euch hasse es. Aber jetzt - yay! Sie erhalten wie 44.000 Kilobyte. So befreien Sie es am Ende der Schleife und dass geht nur den Speicher frei jeder Zeit. Im Wesentlichen ist das Programm nicht zu einem Speicherverlust mehr. Und jetzt etwas, was Sie tun können, ist zu befreien etwas Speicher, die Sie für zweimal bitten. In diesem Fall müssen Sie malloc etwas, ändern Sie den Wert. Sie befreien es einmal, weil Sie sagten, Sie mit ihm fertig waren. Aber dann haben wir befreit ihn wieder. Dies ist etwas, das ziemlich schlecht ist. Es wird nicht zunächst segfault, aber nach einer Weile, was dies ist doppelt die Freigabe der korrumpiert Ihren Heap-Struktur, und du wirst ein wenig mehr darüber zu erfahren dies, wenn Sie eine Klasse wie CS61 nehmen möchten. Aber im Grunde nach einer Weile Ihren Computer wird verwirrt Über das, was Speicherplätze, wo und wo sie gespeichert - wo Daten im Speicher abgelegt. Und so befreiend einen Zeiger zweimal eine schlechte Sache ist, dass Sie nicht wollen, zu tun. Andere Dinge, die schief gehen können, ist nicht mit sizeof. Also, in diesem Fall, dass Sie malloc 8 Bytes, und das ist das Gleiche wie zwei Zahlen, nicht wahr? Also, das ist vollkommen sicher, aber ist es? Nun, wie Lucas sprach über auf verschiedenen Architekturen, Ganzzahlen sind unterschiedlich lang. So, auf das Gerät, dass Sie verwenden, sind ganze Zahlen etwa 4 Bytes, aber auf einem anderen System, das sie vielleicht 8 Byte sein oder sie könnte 16 Byte sein. Also, wenn ich nur diese Nummer hier, Dieses Programm könnte auf dem Gerät zu arbeiten, aber es ist nicht genug Speicher auf einem anderen System zuzuweisen. In diesem Fall ist das, was die sizeof Operator verwendet wird. Wenn wir nennen sizeof (int), was diese tut, ist  es gibt uns die Größe eines Integer auf dem System, dass das Programm läuft. Also, in diesem Fall wird sizeof (int) 4 auf etwas wie das Gerät zurückzukehren, und jetzt dieser Wille 4 * 2, die 8 ist, das ist genau die Menge an notwendigen Raum für zwei Ganzzahlen. Auf einem anderen System, wenn ein int ist wie 16 Byte oder 8 Byte, ist es nur geht, um genügend Bytes zurück, diesen Betrag zu speichern. Und schließlich Strukturen. Also, wenn Sie ein sudoku Bord im Speicher ablegen wollte, könnte, wie wir das tun? Sie können sich wie eine Variable für das erste, was zu denken, eine Variable für die zweite Sache, eine Variable für die dritte Sache, eine Variable für die vierte Sache - schlecht, oder? Also, das ist ein Verbesserung, die Sie oben auf dieser machen kann, um eine 9 x 9 Gitter machen. Das ist in Ordnung, aber was, wenn Sie wollte andere Dinge mit dem Sudoku Bord zu verknüpfen wie das, was die Schwierigkeit der Karte ist, oder, zum Beispiel, was Ihre Gäste ist, oder wie viel Zeit es genommen Sie dieses Board zu lösen? Nun, was Sie tun können, ist, können Sie eine Struktur erstellen. Was ich im Grunde sagen, ist, dass ich die Definition dieser Struktur über hier und ich bin Definieren eines Sudoku Bord, die aus einer Platine, die 9 ist x 9 besteht. Und was hat es hat es Zeiger auf den Namen der Ebene. Es hat auch x und y, die die Koordinaten, wo ich bin gerade sind. Es hat auch Zeit [unverständlich] verbracht, und es hat die Gesamtzahl der Züge, die ich bisher eingegeben. Und so in diesem Fall kann ich eine ganze Reihe von Daten in nur einer Konzernstruktur anstatt es wie herumfliegen wie verschiedene Variablen dass ich nicht wirklich im Auge behalten. Und das lässt uns haben nur nette Syntax für Art verweisen verschiedene Dinge in dieser Struktur. Ich kann nur tun board.board, und ich bekomme das Sudoku Bord zurück. Board.level, bekomme ich, wie hart es ist. Board.x und board.y mir die Koordinaten, wo ich vielleicht in der Bord sein. Und so bin ich Zugriff auf das, was wir Felder in der Struktur nennen. Dies definiert sudokuBoard, die eine Art, die ich habe ist. Und jetzt sind wir hier. Ich habe eine Variable namens "board" vom Typ sudokuBoard. Und so kann ich jetzt Zugriff auf alle Felder, die diese Struktur hier. Fragen über Strukturen? Ja? [Student] Für int x, y, erklärte sie beide auf einer Linie? >> [Joseph] Uh-huh. [Student] So könnte man nur tun, dass mit ihnen allen? Wie in x, y Komma mal, dass insgesamt? [Joseph] Ja, man könnte auf jeden Fall tun, aber der Grund, ich habe x-und y auf der gleichen Linie - und die Frage ist, warum können wir nur tun dies auf der gleichen Linie? Warum gehen wir nicht gerade auf all diese auf der gleichen Linie liegt x und y sind miteinander verwandt, und dies ist nur stilistisch richtig, in gewissem Sinne, weil es Gruppierung zwei Dinge auf der gleichen Linie dass wie Art auf dasselbe beziehen. Und ich aufgeteilt diese auseinander. Es ist nur ein Stil Sache. Es funktional macht überhaupt keinen Unterschied. Alle anderen Fragen über Strukturen? Sie können einen Pokédex mit einem struct definieren. Ein Pokémon hat eine Reihe und es hat einen Brief, ein Besitzer, ein Typ. Und dann, wenn Sie eine Reihe von Pokémon haben, können Sie machen einen Pokédex, nicht wahr? Okay, cool. Also Fragen über Strukturen. Das sind im Zusammenhang mit Strukturen. Schließlich GDB. Was bedeutet GDB können Sie tun? Damit können Sie Ihr Programm testen. Und wenn Sie nicht GDB verwendet haben, würde ich empfehlen gerade die kurzen und gerade gehen über das, was GDB ist, wie man mit ihr arbeiten, wie Sie es benutzen, und testen Sie es an einem Programm. Und so was GDB können Sie tun, ist es lässt Pause die [unverständlich] Ihr Programm und eine praktische Linie. Zum Beispiel möchte ich eine Pause Ausführung an wie Linie 3 von meinem Programm, und während ich in Zeile 3 bin ich ausdrucken können alle Werte, die es gibt. Und so wie wir es nennen, wie Pause in einer Linie wird nennen wir diese setzen einen Haltepunkt an dieser Linie und dann können wir drucken Sie die Variablen auf den Zustand des Programms zu diesem Zeitpunkt. Wir können dann von dort fort durch das Programm Zeile-für-Zeile. Und dann können wir im Zustand des Stapels zu der Zeit zu sehen. Und so, um zu benutzen GDB, was wir tun, wir nennen Klang auf der C-Datei, aber wir müssen weitergeben the-ggdb Flagge. Und wenn wir fertig sind mit, dass wir nur laufen gdb auf die resultierende Ausgabedatei. Und so erhalten Sie eine Masse von Texten wie diesem, aber wirklich alles, was Sie tun müssen, ist in Befehle an den Anfang geben. Break main setzt einen Haltepunkt an main. Liste 400 listet die Zeilen Code um Zeile 400. Und so in diesem Fall können Sie einfach umschauen und sagen, oh, Ich möchte einen Breakpoint in Zeile 397, die diese Zeile gesetzt, und Ihr Programm läuft in diesem Schritt und es geht zu brechen. Es ist zu pausieren dort vor sich geht, und Sie können drucken, zum Beispiel mit einem Wert von niedrig oder hoch. Und so gibt es eine Reihe von Befehlen, die Sie wissen müssen, und diese Slideshow gehen bis auf der Website, so wenn Sie nur wollen, um diese zu verweisen oder wie sie auf Ihrem Spickzettel, sich frei fühlen. Cool. Das war Quiz Bewertung 0, und wir werden bleiben, um, wenn Sie irgendwelche Fragen haben. Gut.  [Applaus] [CS50.TV]