[Musik spielt] DAVID J. MALAN: Alles klar. [Gelächter] Willkommen zurück. Dies ist CS50. Und das ist das Ende der Woche fünf. Und bis jetzt haben wir ziemlich viel genommen für selbstverständlich, dass es existiert diese Compiler Clang, dass Sie wurde durch diese Aufrufen anderen Tool namens Machen Sie, dass irgendwie magisch verwandelt Ihren Quellcode in Objekt-Code, die Nullen und Einsen dass Ihr Computer CPU, zentrale Verarbeitungseinheit, eigentlich versteht. Aber es stellt sich heraus, es gibt eine Zahl, die ist los unter der Haube in zwischen Eingang und Ausgang. Und ich möchte vorschlagen, dass wir Fleisch dass in einem kleinen Detail in diese vier Schritte haben etwas namens Pre-Processing, etwas genannt compiling, die wir gesehen haben, etwas namens Montage und etwas namens Verlinkung nicht erkennbar. Also bis jetzt in einigen unserer Programme, wir hatten scharfe enthält. Vor kurzem hatten wir etwas scharf definiert für Konstanten. So stellt sich heraus, dass die Dinge, die werden mit dem Hash-Symbol oder vorangestellt das Pfund-Symbol sind Pre-Prozessor Richtlinien. Das ist nur eine andere Art zu sagen, es ist eine Codezeile, die eigentlich umgewandelt in etwas anderes, bevor die Computer sogar versuchen, konvertieren Sie Ihre Programm in Nullen und Einsen. So enthält scharfe Standard I / O. H, ziemlich genau bedeutet gehen voraus, greifen die Inhalte der Dateien stdio.h und fügen Sie sie genau dort. Also keine Nullen und Einsen an diesem Punkt noch. Es ist wirklich nur eine Substitution. Und das ist während des sogenannten getan Vorverarbeitungsstufe, wenn man tatsächlich laufen Clang oder speziell Stellen Sie in den meisten Fällen. Also all das passiert ist zunächst automatisch so weit. Dann kommt die Zusammenstellung Schritt. Aber wir haben vereinfacht Zusammenstellung. Kompilieren eines Programms wirklich bedeutet nehmen Sie es von so etwas wie C, die Quellcode haben wir geschrieben, unten etwas Versammlung aufgerufen. Assembler ist eine untere Ebene Sprache, die, Gott sei Dank, werden wir nicht haben viel zu veranlassen schreiben in diesem Semester. Aber es ist auf der untersten Ebene in der Sinne, dass man buchstäblich mit dem Schreiben beginnen addieren und subtrahieren und multiplizieren und laden aus dem Speicher und in den Speicher zu speichern, die sehr grundlegende Hinweise, dass ein Computer, unter der Haube, tatsächlich versteht. Schließlich nimmt der Montage diese Sprache zu den Nullen und Einsen, die wir waren beschreibt so weit. Und wahrlich schließlich gibt es noch die sogenannten Verknüpfung Phase, die wir werden sehen in nur einem Augenblick, das verbindet Ihre Nullen und Einsen mit Nullen und Wieder andere Menschen vor Sie erstellt haben. So betrachten diese super einfaches Programm. Es war von Woche 1. Es sagte nur Hallo Welt, auf dem Bildschirm. Wir liefen durch diese Schall. Oder wir rannten sie durch Stellen das lief Schall. Und zu der Zeit, wo ausgegeben einige Nullen und Einsen. Aber es stellt sich heraus, es gibt ein Zwischenschritt. Wenn ich hier gehen - oops, nicht will ihn noch sehen. Wenn ich gehe hier um mein Gerät und ich eröffnen hello.c, hier ist, dass dasselbe Programm. Und was ich in meinem Terminal tun Fenster hier ist, ich bin zu gehen laufen Clang anstatt Stellen, die automatisiert alle vier diese Schritte für uns. Und ich werde tun Klang-S und dann hello.c und geben Sie dann. Und ich bekomme einen blinkenden Eingabeaufforderung wieder ist das gut. Und nun in eine etwas größere Fenster, Ich werde zu öffnen gedit hier. Und ich werde zu öffnen, eine Datei, die, stellt sich heraus, heißt dies hello.s enthält, dass Assembler Ich bezog mich auf früher. Und das ist, was heißt Montage Sprache, recht niedrigen Niveau Anweisungen, dass Ihr Intel CPU oder was auch immer es ist, dass drin ist versteht. Und mov ist für unterwegs. Anruf ist für Aufruf, einen sehr niedrigen Level-Funktion. sub ist für subtrahieren. Also, wenn Sie eine bestimmte CPU im Inneren Ihres Computers, was macht es deutlich, im Vergleich zu anderen CPUs auf die Markt, welche Anweisungen es versteht und oft wie effizient es ist, wie schnell es bei der Ausführung einige ist dieser Anleitung. Jetzt für weitere Informationen hierzu, können Sie nächsten Herbst CS61 an der Hochschule. Hier haben wir aber zum Beispiel einige Kennungen, die vertraut aussehen könnte. hello.c ist der Name des Programms. . Text - es gibt nicht viel von Interesse gibt gerade jetzt daran erinnern, dass der Text Segment ab Montag, ist, wo in Speicher Ihr Programm tatsächlich endet. Also das ist zumindest vage vertraut dort. Dabei ist natürlich eine Erwähnung von unsere Funktion. Scrollen nach unten, siehe diese Dinge genannten Registern, sehr kleine Stücke von Speicher in Ihrer eigentlichen CPU. Und wenn ich nach unten scrollen, auch weiter, sehe ich eine Art indirekte Erwähnung von ASCII. Und es ist in der Tat, dass die String, hallo, Komma, Welt. So lange Rede, kurzer Sinn, dies war geschieht für Sie, automatisch, unter der Haube all dieser Zeit. Und was ist schon passiert ist wirklich einmal Sie haben Clang laufen, oder durch Machen Sie, Sie zuerst zu erreichen, aus dem Quellcode, der sogenannte Assembler. Dann Clang ist die Umwandlung dieser Versammlung Sprache auf Nullen und Einsen. Und dies ist die Folie, die wir begonnen unsere Diskussion in Woche 0 auf - und dann Woche 1 auf. Und schließlich, diese Nullen und Einsen mit den Nullen und Einsen in Kombination von diesen Bibliotheken haben wir genommen wie für Standard-I / O oder gewährt String-Bibliothek oder sogar der CS50-Bibliothek. So ist dieses Bild zu malen mehr visuell, haben wir hello.c. Und natürlich wird die printf funktionieren zu sagen, hallo Welt. Die Zusammenstellung Schritt dauert es bis zu dass wir gerade gesehen haben Datei hello.s, auch obwohl das ist in der Regel gelöscht automatisch für Sie. Aber das ist die Assembler-Code in der mittleren Stufe. Und dann, wenn wir montieren die Montage Sprache, so zu sprechen, das ist, wenn Sie bekommen die Nullen und Einsen. Deshalb haben wir uns in effektiv erkennen heute auf was wir bisher für selbstverständlich nehmen, bedeutet, sich Quellcode Code widersprechen. Aber schließlich, jetzt, da gleiche Bild - lasst es schieben, um über auf der linken Seite. Und beachten Sie, dass in der Spitze gibt Ich erwähnte stdio.h. Das ist eine Datei, die wir aufgenommen in fast allen der Programme, die wir geschrieben haben. Und das ist die Datei, deren Inhalt Kopie eingefügt bekommen, effektiv oben auf Ihrem Code. Aber es stellt sich heraus, dass auf einem Computer System irgendwo, gibt es vermutlich ein stdio.c Datei, dass jemand Jahren schrieb her, dass implementiert alle die Funktionen, die deklariert wurden in stdio.h. Jetzt in der Realität ist es wahrscheinlich nicht auf Ihrem Mac oder PC oder sogar in der CS50-Appliance ist eine rohe C-Code. Jemand es bereits zusammengestellt und enthalten . O Datei für Objekt-Code oder. Ein Datei, die zu einer gemeinsam genutzten Bibliothek bezieht Das ist bereits vorinstalliert und für Sie vorab zusammengestellt. Aber nehmen wir an, dass es in der Tat existiert auf unserem Computer stdio.c parallel mit Schall. Ihr Code ist kompilierten und montiert. stdio.c 's Code wird kompiliert und montiert, so dass diese letzte Schritt, hier unten, wir müssen irgendwie Link, so zu sprechen, Ihre Nullen und Einsen mit seinem Nullen und Einsen in einem einfaches Programm, das letztendlich rief nur hallo. Also das ist alles von der Magie, ist wurden bisher geschieht. Und wird auch weiterhin diese nehmen Prozesse für selbstverständlich halten, sondern erkennen, es gibt eine Menge von saftigen Details geht es unter. Und das ist, was macht Ihr Computer mit Intel inside besonders ausgeprägt. Also in diesem Sinne, wenn Sie möchten, besuchen Sie uns für das Mittagessen an diesem Freitag, tun zu gehen zu den üblichen Ort cs50.net/rsvp, 01.15 an diesem Freitag. Und nun ein paar Ankündigungen. So haben wir eine gute Nachricht. Und wir haben einige schlechte Nachrichten. Beginnen Sie mit einigen guten Nachrichten hier. [Stöhnt] In Ordnung. Nun, es ist technisch ein Feiertag, so es ist nicht so sehr ein Geschenk von uns. Aber dann die schlechten Nachrichten natürlich. [Stöhnt] Ich verbrachte viel Zeit auf diesen Animationen. [Gelächter] Es wird eine Überprüfung Session am kommenden Montag. Es wird um 5:30 Uhr sein. Wir werden Sie über all diese Details erinnern per E-Mail über den Verlauf der Website in nur ein paar Tage Zeit. Es wird gefilmt und zur Verfügung gestellt werden kurz danach. Also, wenn Sie nicht an diesem Montag Nacht-Slot, keine Sorge. Abschnitte in der kommenden Woche wird auch konzentrieren sich auf eine Bewertung für das Quiz. Wenn Ihr Abschnitt ist am Montag, das ist Tat Universität Urlaub, werden wir noch in Abschnitt erfüllen. Wenn man einfach nicht machen, dass Abschnitt, weil du gehst entfernt, ist das in Ordnung. Nehmen Sie an einem Sonntag oder Dienstag oder Abschnitt tune-in, um Jasons Abschnitt, das ist online verfügbar. Also, noch mehr schlechte Nachrichten. So nach dem Lehrplan, wir haben Vortrag am kommenden Freitag. Aber die gute Nachricht - klar, verbrachte ich viel Zeit zu diesem Thema. [Gelächter] Wir werden am kommenden Freitag die Vorträge abzubrechen. Also das wird ein Fest für uns sein, damit Sie kann wirklich eine schöne Abwechslung in zwischen dieser Woche bis zwei Wochen damit. Also keine Vorlesungen nächste Woche, nur ein winziger kleines Quiz, für das Sie sollte zunehmend aufgeregt. So lasst uns nun unsere Aufmerksamkeit auf etwas, das ist in der Tat mehr visuelle und spannender zu gestalten und die Bühne für das, was ist los, um am Horizont in nur ein paar Wochen Zeit. Nach dem ersten Quiz, wir drehen die Schwerpunkt unseres Problems Sätze zu einem anderen Domain-spezifisches Problem, dass der Forensik oder Sicherheit im Allgemeinen. In der Tat, die Tradition mit diesem Problem Set ist für mich einer der Lehrbeauftragter oder CAs zu Fuß über Campus unter ein paar Fotos von erkennbar, aber nicht offensichtlich Menschen, Orte oder Dinge, dann jedes Jahr habe ich irgendwie versehentlich gelöscht oder korrumpieren die digitale Medien-Karte das ist in unserer Kamera. Aber keine große Sache. Ich kann gehen und stecken die in meinem Computer. Ich kann eine forensische Bild von ihm, so zu sprechen, durch Kopieren der Nullen und diejenigen aus dieser Speicherkarte, ob es ist ein SD-Card oder Compact-Flash-Karte oder was du bist vertraut mit. Und dann können wir Hand, die sich. Und so ist die Herausforderung für die Zukunft, unter anderem Dinge für Sie, wird es sein, zu schreiben C-Code, der eine ganze Reihe von erholt JPEGs für mich und enthüllt werden jene Menschen, Orte oder Dinge. Und wir werden auch zu sprechen, in dieses Problem gesetzt und in den kommenden Tagen, über Grafiken im Allgemeinen. Wir haben sie genutzt, einen Kurs, für ausbrechen. Aber du hast irgendwie für selbstverständlich existiert diese hohe Vorstellungen Rechtecke und Ovale. Aber unter der Haube es Pixel. Und Sie mussten mit dem Nachdenken über diese. Oder du wirst für p-Satz 4 haben zu denken, über die Lücke zwischen Ihrem Ziegel, wie schnell du Ball wird über Bewegung der Bildschirm für die ausbrechen. So gibt es diese Vorstellung von der Punkte auf dem Bildschirm, das ist ins Spiel kommen schon. Nun, was Sie sehen, obwohl, ist das, was erhalten Sie auf einem Computer-Bildschirm. Wenn Sie jemals etwas Gutes oder beobachtete schlechte TV, stehen die Chancen sie ziemlich viel behandeln das Publikum wie technophob , die nicht wirklich wissen viel über Computer. Und so ist es sehr einfach für die Polizei Detektiv zu sagen, können Sie sauber, dass Sie sich für mich? Oder verbessern, nicht wahr? Verbessern Sie ist wie das Modewort in die meisten jedes Verbrechen verwandten Show. Und die Realität ist, wenn Sie eine sehr nehmen verschwommene Bild eines Verdächtigen zu tun etwas schlecht, kann man nicht nur verbessern es. Sie können nicht in unendlich vergrößern. Sie können nicht in der Glitzern von jemandem sehen Auge, die die verpflichtet bestimmtes Verbrechen, trotz der Prävalenz dieser im Fernsehen. Und so mit, dass wir uns zu motivieren, dass kommenden Problem mit einem Blick auf gesetzt einige Shows, mit denen Sie Vielleicht kennen. [VIDEO PLAYBACK] -OK. Jetzt wollen wir einen guten Blick auf Sie zu besorgen. -Halten Sie es. Führen Sie das zurück. -Warten Sie eine Minute. Gehen Sie nach rechts. -Es. Frieren Sie, dass. -Full screen. -OK. Frieren Sie, dass. -Ziehen Sie auf, dass, wird ya? Vektor-in an diesem Kerl durch das Hinterrad. Zoom-in direkt hier an dieser Stelle. -Mit der richtigen Ausrüstung, die abgebildete vergrößert und geschärft werden. -Was ist das? -Es ist eine Verbesserung Programm. -Können Sie sich klar, dass Sie überhaupt? -Ich weiß es nicht. Lassen Sie uns zu verbessern es. Enhance-Abschnitt A-6. -I erweitert das Detail und - -Ich denke, es ist genug, um zu verbessern. Lassen Sie es auf meinem Bildschirm. -Erhöhen Sie die Reflexion in ihrem Auge. -Lassen Sie uns diese durchlaufen Video-Enhancement. -Edgar, können Sie verbessern das? -Warte. -Ich habe auf dieser Reflexion gearbeitet. -Jemand Reflexion. -Reflection. -Es ist ein Spiegelbild von dem Gesicht des Mannes. -Die Reflexion. -Es ist eine Reflexion. In auf dem Spiegel-Zoom. -Sie können eine Reflexion. -Können Sie das Image von hier? -Können Sie erweitern ihn hier richtig? -Können Sie es verbessern? -Können Sie es verbessern? -Können wir verbessern das? -Können Sie es verbessern? Auf einem zweiten Halten, werde ich verbessern. In an der Tür-Zoom. -X10. -Zoom. [Gelächter] -Verschieben in. -Warten, zu stoppen. -Stopp. -Pause zu. -Drehen eines 75 Grad um die vertikale bitte. [Gelächter] -Beenden und zurück zum Teil über der Tür wieder. -Haben Sie ein Image Enhancer Das kann Bitmap? -Vielleicht können wir die Pradeep Sen Verfahren in das Fenster sehen. -Diese Software ist Stand der Technik. Das Symbol-Wert ist ausgeschaltet. -Mit der richtigen Kombination von Algorithmen. -Er Beleuchtung Algorithmen getroffen werden, um die nächste Stufe, und ich kann sie zu benutzen Verbesserung dieses Foto. -Lock auf und vergrößern die z-Achse. -Enhance. -Enhance. -Enhance. Einfrieren und zu verbessern. [END VIDEO PLAYBACK] DAVID J. MALAN: So Problem Set 5 ist es, was vor uns liegt. So werden wir bald ein besseres Verständnis wann und warum man und unsere nicht in der gleichen Art und Weise zu verbessern. Aber zunächst wollen wir unsere Aufmerksamkeit zurück einige der Bausteine ​​wir werden müssen in der Lage sein, diese Geschichte zu erzählen. So erinnern, dass wir dieses Bild auf zog Montag und ein wenig der vergangenen Woche. Und dies beschreibt das Layout der Dinge in den Arbeitsspeicher Ihres Computers, wenn laufen einige Programm. Der Tech-Segment bis oben, Rückruf bezieht sich den tatsächlichen Nullen und Einsen das komponieren Ihrem Programm. Es gibt, darunter, einige initialisiert oder initialisierte Daten, die typischerweise bezieht sich auf Dinge wie Konstanten oder Strings oder globale Variablen, die haben wurde im Vorfeld erklärt. Es ist der Haufen, aber wir kommen zurück zu, dass in einem Bit. Und dann ist da noch der Stapel. Ähnlich wie ein Stapel von Ablagen in der Cafeteria, das ist, wo bekommt Speicher geschichtet und geschichtet, wenn Sie tun, was in einem Programm? Was ist der Stapel für den Einsatz? Ja? Aufruf der Funktion. Jedes Mal, wenn Sie eine Funktion aufrufen, ist es gegeben, Splitter der Erinnerung für seine lokale Variablen oder seine Parameter. Und bildhaft, sehen wir, dass mit jedem aufeinanderfolgenden Funktion aufgerufen, wenn A Anrufe Anrufe B C D fordert, sie auf den Stapel geschichtet bekommen. Und innerhalb jeder dieser Scheiben Speicher ist im Wesentlichen eine einzigartige Rahmen für die Funktion, die natürlich, Problematisch ist, wenn Sie übergeben wollen von einer Funktion zur anderen ein Stück von Daten, dass Sie es wollen zu mutieren oder zu ändern. Also, was war unsere Lösung ermöglicht Eine Funktion von einem Stapel dargestellt Rahmen, um das Gedächtnis nach innen ändern von einem anderen Stack-Frame? Wie diese beiden miteinander reden? So mittels Zeigern oder Adressen, was wiederum nur beschreiben, wo in Speicher, durch einen bestimmten Biß-Nummer, die insbesondere Wert gefunden werden kann. So erinnern wir letztes Mal auch fortgesetzt die Geschichte und sah ein ziemlich buggy Programm. Und dieses Programm ist buggy für ein paar Gründe, aber die eine ist besorgniserregend weil es nicht auf das, was zu überprüfen? Ja, doch fehlt es an den Eingang zu überprüfen. Es tut uns leid? Wenn es mehr als 12 Zeichen. So sehr intelligent, wenn Sie anrufen memcopy, die, wie der Name schon sagt, nur Kopien Speicher aus dem zweiten Argument in seine erste Argument. Das dritte Argument, sehr intelligent ist überprüft, um sicherzustellen, dass Sie nicht kopieren mehr als, in diesem Fall die Länge der Bar, die Anzahl der Zeichen, in das Ziel ist, die diese Array C. Aber das Problem ist, dass das, was wenn C selbst ist nicht groß genug zu umgehen? Du wirst die Nummer kopieren Bytes, die Sie schon immer gegeben. Aber was tun Sie tatsächlich mehr Bytes als Sie haben Platz für? Nun, dieses Programm nur sehr töricht blind weiter zu nehmen, was es ist gegeben ist, hallo Backslash 0 toll, wenn String ist kurz genug, wie fünf Zeichen. Aber wenn es tatsächlich 12 Zeichen oder 1.200 Zeichen, sahen wir letzte Mal dass Sie nur gehen, um ganz Speicher überschreiben, dass nicht Ihnen gehören. Und am schlimmsten Fall, wenn Sie überschreiben, dass Rotanteil es, dass wir das genannt Rückkehr-Adresse - dies ist nur, wo der Computer automatisch für Sie, hinter der Szenen, Biesen entfernt ein 32-Bit-Wert, es erinnert an welche Adresse es sollte zurück, wenn foo, diese andere Funktion, erfolgt die Ausführung. Es ist ein Brotkrümel von möglichen zu dem es zurückkehrt. Wenn Sie überschreiben, dass möglicherweise auch wenn Sie der Bösewicht sind, kann, könnte potentiell übernehmen jemandes Computer. Und du wirst ganz sicher Absturz in den meisten Fällen. Jetzt wurde dieses Problem nur verschärft als wir kamen ins Gespräch über das Gedächtnis Management im Allgemeinen. Und malloc, für Speicherzuweisung, ist ein Funktion, die wir verwenden können, um zuteilen Speicher, wenn wir nicht im Voraus wissen, dass wir vielleicht brauchen einige. So, zum Beispiel, wenn ich gehe zurück an das Gerät hier. Und ich eröffnen vom letzten Mal hello2.c, erinnern dieses Programm hier, das sah ein wenig so etwas wie dieses, nur drei Linien - Ihren Namen, dann string name, auf der linken Seite, gleich getstring. Und dann haben wir drucken es aus, den Namen des Benutzers. Also das war ein super einfaches Programm. Um klar zu sein, lass mich gehen und machen hallo-2. Ich werde dot Schrägstrich hallo-2 zu tun. Nennen Sie Ihren Namen - David. Enter. Hallo David. Es scheint OK zu arbeiten. Aber was wirklich vor sich geht unter Haube hier? Lassen Sie uns zunächst schälen einigen Schichten. String ist nur ein Synonym wir haben realisiert für was? Char Stern. So machen wir es ein wenig mehr arkanen aber technisch korrekt, dass diese ist ein char Stern, was bedeutet, dass Name, ja, das ist eine Variable. Aber welchen Namen speichert die Adresse ein char, die ein wenig seltsam fühlt weil ich immer wieder einen String. Ich gehe zurück bekommen mehrere Zeichen kein char. Aber natürlich, Sie benötigen nur die erste char die Adresse zu erinnern, wo die ganze Reihe ist, weil warum? Wie kann man herausfinden, wo das Ende des die Zeichenfolge ist zu wissen, den Anfang? Der Backslash Null. Also mit diesen beiden Hinweisen Sie herausfinden, vor dem Beginn und dem Ende der jede Zeichenfolge sind, so lange wie sie sind ordnungsgemäß an dieses null gebildet Terminator, dass Backslash Null. Aber dies ruft getstring. Und es stellt sich heraus, dass getstring all dieser Zeit war Art von Betrug für uns. Es mache diese Arbeit, um sicher zu sein, immer einen String vom Benutzer. Aber wo ist die Erinnerung worden herkommt? Wenn wir zurück zu dem Bild hier und gelten die Definition von nur Moment vor, dass der Stapel ist, wo Speicher geht, wenn Funktionen aufgerufen werden, nach dieser Logik, wenn Sie getstring nennen, und dann habe ich in geben D-A-V-I-D eingeben, wo ist D-A-V-I-D Schrägstrich Null gespeichert, basierend auf dem Geschichte haben wir uns gesagt, bis jetzt? Es scheint in sein der Stapel, nicht wahr? Wenn Sie den String rufen Sie bekommen ein kleines Stück vom Speicher auf dem Stack. So liegt es nahe, dass D-A-V-I-D Backslash Null gespeichert es in den Stapel. Aber warten Sie eine Minute, GetString Renditen dass string, so zu sprechen, was bedeutet, es ist Fach aus der Cafeteria wird vom Stack genommen. Wir sagten letzte Mal, dass, sobald ein Funktion zurück, und nehmen Sie die Tablett, so zu sprechen, vom Stapel, was können Sie über den Resten davon ausgehen, dass der Speicher? Ich Art von Grenzziehung sie als Fragezeichen weil sie wirksam geworden unbekannte Werte. Sie können wiederverwendet werden, wenn einige werden nächste Funktion aufgerufen wird. Mit anderen Worten, wenn wir passieren zu speichern - Ich werde ziehen schnell ein Bild hier des Stapels. Wenn wir passieren zu zeichnen den Boden meiner Memory-Segment, und wir sagen dass dies der Ort der Erinnerung besetzt durch Haupt-und vielleicht arg c und arg v und alles, was in dem Programm, wenn getstring genannt wird, vermutlich getstring bekommt ein Teil des Speichers hier. Und dann D-A-V-I-D irgendwie landet in dieser Funktion. Und ich werde vereinfachen. Aber lassen Sie uns davon ausgehen, dass ihre D-A-V-I-D Backslash Null. So dass diese viele Bytes in verwendet der Rahmen für getstring. Aber sobald getstring Renditen, wir sagte letzte Mal, dass dieser Speicher über hier wird alles - woops! - alles wird effektiv gelöscht. Und wir können dies nun denken als Fragezeichen Noten denn wer weiß, was los ist, um von dieser Erinnerung geworden. In der Tat, ich bin sehr oft Funktionen aufrufen andere als getstring. Und sobald ich einige andere nennen Funktion als getstring, vielleicht nicht in Dieses spezielle Programm wir sahen an, aber einige andere, sicherlich eine andere Funktion könnte am Ende wird gegeben Diese nächste Stelle in dem Stapel. So kann es nicht so, dass getstring speichert sein D-A-V-I-D auf dem Stapel, weil ich würde verlieren sofort Zugriff darauf. Aber wir wissen, dass sie GetString gibt nur was? Es ist nicht wieder zu mir sechs Zeichen. Wie ist es wirklich wieder haben schließen wir beim letzten Mal? Die Adresse des ersten. Also irgendwie, wenn Sie getstring genannt, es Zuweisung eines Teil des Speichers für der String, der Benutzer Art und dann Rückkehr-Adresse von ihm. Und es stellt sich heraus, dass, wenn Sie wollen funktionieren, um Speicher in dieses zuweisen Weg und Rückkehr zu der Person, die als diese Funktion wird die Adresse dass Teil des Speichers, Sie absolut kann es nicht in den Stapel an der Boden, denn es ist nur funktionell werde nicht verkaufen sehr zu schnell, so können Sie wahrscheinlich erraten, wo wir sind wahrscheinlich zu werfen Stattdessen wird die sogenannte Heap. So zwischen der Unterseite des Speichers Layout und die Oberseite des Speichers Layout gibt eine ganze Reihe von Segmenten. Einer ist der Stapel, und rechts darüber ist die Heap. Und Heap ist nur eine andere Brocken Speicher, der nicht für Funktionen wird benutzt wenn sie aufgerufen wird. Es ist für die längerfristige Speicher verwendet, wenn Sie wollen eine Funktion, einige greifen Speicher und in der Lage sein zu hängen, um es ohne die Kontrolle zu verlieren über sie. Nun könnte man vielleicht sofort sehen, dass dies nicht notwendigerweise mit perfektem Design. Als Ihr Programmspeicher auf zugeteilt der Stapel, oder wie Sie es nennen und mehr mehr Funktionen oder wie Sie zuweisen Speicher auf dem Heap mit malloc off als getstring tut, was deutlich scheint unvermeidlich Problem sein? Richtig. Ebenso wie die Tatsache, dass diese Pfeile sind zueinander zeigen Das verheißt nichts Gutes. Und in der Tat konnten wir sehr schnell abstürzen ein Programm in einer beliebigen Anzahl von Möglichkeiten. In der Tat, ich glaube, wir haben könnten dies getan versehentlich einmal. Oder wenn nicht, lass es uns tun bewusst jetzt. Lassen Sie mich gehen und schreiben Super schnell ein Programm namens dontdothis.c. Und jetzt gehe ich in hier und Sie sind scharf stdio.h. Lassen Sie uns erklären function foo nimmt keine Argumente, ist die bezeichnet sowie von Leere. Und das einzige, was foo zu tun ist, ist Aufruf foo, das ist wahrscheinlich nicht der klügste Idee, aber so zu sein. Ent wichtigsten nichtig. Nun ist die einzige Sache wichtigsten wird zu tun ist, foo auch telefonisch. Und nur zum Spaß, ich werde gehen vor hier und printf sagen "Hallo aus foo. " OK. Also wenn ich keine Fehler machen, Machen dontdothis dot Schrägstrich. Und lasst es uns in einem größeren Fenster - dot Schrägstrich dontdothis. Komm. Uh oh. Offenbar können Sie dies tun. Verdammt. OK. Warten. Stand by. Haben wir - Wir haben es mit Nutzen. [Seufzt] Ich weiß, aber ich denke, dass wir nur gelöscht, dass. Äh, ja. Verdammt. Lösen Sie dieses Rob. Was? Es ist sehr einfach. Ja, wandten wir uns Optimierung aus. OK, Stand bye. Jetzt fühle ich mich besser. OK. In Ordnung. Also lasst uns diese neu kompilieren - Machen Sie dontdothis. Möglicherweise müssen Sie diese umbenennen dothis.c in nur einem Augenblick. Dort gehen wir. Vielen Dank. OK. Also die Tatsache, dass ich Druck etwas aus war eigentlich nur Verlangsamung des Prozesses, durch den wir würde diesen Punkt erreicht haben. OK. Puh! Also, was ist eigentlich los? Der Grund da, nur so nebenbei, ist etwas zu tun in Bezug auf die Ein-und Ausgang tendenziell langsamer, weil Sie haben, um die Zeichen zu schreiben Bildschirm ist zu blättern. So lange Rede, kurzer Sinn, ich hatte eigentlich passiert so ungeduldig, müssten wir gesehen dieses Endergebnis auch. Nun, ich habe Ritt der Druck-ups, sehen wir es sofort. Also, warum ist das passiert. Nun, die einfache Erklärung, natürlich, ist, dass foo wahrscheinlich sollte nicht werden, die sich selbst. Jetzt im allgemeinen, dies Rekursion. Und wir dachten, ein paar Wochen Vor rekursiv ist gut. Rekursion ist diese magische Art und Weise der sich selbst auszudrücken Super lapidar. Und es funktioniert einfach. Aber es ist ein wesentliches Merkmal aller die rekursive Programme, die wir gesprochen haben über und sah so weit, die war, dass sie, was hatte? Ein Basis-Fall, der einige hart codiert war Fall, dass in einigen Situationen die nicht nennen foo, was eindeutig hier nicht der Fall. Also, was ist wirklich passiert in Bezug auf diesem Bild? Nun, wenn der Haupt ruft foo, es bekommt ein Stück Erinnerung. Wenn foo foo aufruft, bekommt es ein Stück Erinnerung. Wenn foo foo aufruft, bekommt sie eine Scheibe. Es wird eine Scheibe. Es wird eine Scheibe. Da foo wird nie wiederkommen. Wir sind nie Löschen einer von denen Rahmen aus dem Stapel. Daher freuen wir uns über den Haufen blasen, nicht zu erwähnen, wer weiß, was sonst, und wir überschreiten die Grenzen unserer so genannte Segment des Speichers. Fehler Es gehen Segmentierung falsch. So ist die Lösung gibt es offensichtlich nicht tun. Aber das größere Implikation ist, dass, ja, es ist absolut einige Grenze, auch wenn es nicht gut definiert, so wie viele Funktionen, die Sie bei einem Anruf können Programm, wie oft eine Funktion kann sich nennen. Also auch wenn wir predigten Rekursion als dieser möglicherweise magische Sache ein vor einigen Wochen für den Sigma Funktion, und wenn wir die Daten Strukturen und CS50, sehen Sie andere Anwendungen für sie, ist es nicht unbedingt die beste Sache. Denn wenn eine Funktion nennt sich, nennt sich, auch wenn es eine Basis Fall, wenn Sie nicht, dass base Fall getroffen für 1.000 oder 10.000 Anrufe Anrufe durch dass die Zeit, die Dir vielleicht aus dem Zimmer laufen haben auf Ihrem sogenannten Stack und Hit einige andere Segmente des Speichers. Also es ist auch ein Design trade-off zwischen Eleganz und zwischen Robustheit Ihren speziellen Umsetzung. So gibt es einen anderen Nachteil oder andere gotcha, was wir haben wurden bisher tun. Als ich anrief getstring - lass mich gehen zurück in hallo-2. Beachten Sie, dass ich rufe getstring, das ist wieder eine Adresse. Und wir behaupten heute, dass Adresse ist aus dem Haufen. Und jetzt bin ich den Ausdruck der String an dieser Adresse. Aber wir haben nie genannt Gegenteil von getstring. Wir hatten noch nie eine Funktion wie CALLL ungetstring, wo man die Hand zurück dass der Speicher. Aber ehrlich gesagt wir wahrscheinlich hätte sein sollen. Denn wenn wir immer wieder die Computer für das Gedächtnis, durch jemanden wie getstring aber nie geben es zurück, sicherlich Das ist auch verpflichtet, zu führen Probleme, wobei wir über genügend Arbeitsspeicher ausgeführt. Und in der Tat können wir für diese aussehen Probleme mit dem neuen Werkzeug, dessen Nutzung ist ein wenig kryptisch zu geben. Aber lassen Sie mich gehen Sie vor und spritzen es auf dem Bildschirm in nur einem Augenblick. Ich werde weitermachen und laufen Walgrind mit Parameter, dessen erste Befehl Argument ist der Name dieses Programms hallo-2. Und leider ist es Ausgang ist grausam Komplex ohne guten Grund. Wir sehen also, die den Schlamassel. David ist mein Name angeben. Also das ist das Programm tatsächlich läuft. Und jetzt bekommen wir diesen Ausgang. So Valgrind ist ähnlich im Geiste GDB. Es ist nicht per se ein Debugger. Aber es ist ein Speicher checker. Es ist ein Programm, das Ihren laufen wird programmieren und Ihnen sagen, wenn Sie ein gefragt Computer-Speicher und nie gab es zurück, wodurch bedeutet, dass Sie haben ein Speicherverlust. Und Speicherlecks sind in der Regel schlecht. Und Sie ist Nutzer von Computern haben wohl gefühlt, egal ob Sie eine haben Mac oder ein PC. Haben Sie schon einmal verwendet Ihr Computer für während und nicht in mehreren neu gestartet Tage, oder Sie haben gerade eine Menge Programme laufen, und das verdammte Ding verlangsamt zum Erliegen, oder zumindest es ist super ärgerlich zu bedienen, weil alles gerade super langsam. Nun, das kann eine beliebige Anzahl von Gründen. Es könnte eine Endlosschleife, eine Wanze in sein jemand den Code, oder einfach, es könnte bedeuten, dass Sie mit mehr Speicher, oder versuchen, als Ihre Computer tatsächlich hat. Und vielleicht gibt es einen Fehler in einem gewissen Programm dass immer wieder gefragt für das Gedächtnis. Browser für Jahre waren berüchtigt für Dazu fordern mehr und mehr Speicher aber nie reichte es zurück. Sicherlich, wenn man nur eine endliche Menge an Speicher, können Sie nicht fragen unendlich viele Male für etwas von diesem Speicher. Und was Sie hier sehen, obwohl wieder Valgrind der Ausgang ist unnötig komplex, um auf einen Blick Erstens ist dies der interessante Teil. Heap - im Einsatz bei der Ausfahrt. Also hier ist, wie viel Speicher war in Verwendung in dem Haufen am Zeit mein Programm verlassen - offenbar sechs Bytes in einem Block. Also werde ich meine Hände winken an, was ein Block ist. Denken Sie daran, nur ein Stück, ein mehr technische Wort für Stück. Aber sechs Bytes - was sind die sechs Bytes, die waren noch im Einsatz? Genau. D-A-V-I-D Backslash Null, fünf Buchstaben Namen plus die Nullabschlusszeichen. Also das Programm bemerkt, dass ich Valgrind bat um sechs Bytes, offenbar durch Weg getstring, aber nie gab sie zurück. Und in der Tat, könnte dies nicht so sein, offensichtlich, wenn mein Programm nicht drei Linien, aber es ist 300 Zeilen. So können wir tatsächlich geben einen anderen Befehl Argument zu Walgrind machen es ausführlich. Es ist ein wenig ärgerlich, sich zu erinnern. Aber wenn ich es tue - mal sehen. Leck - War es undicht - auch ich kann mich nicht erinnern was es ist, aus der Hand. - Leck-check gleich voll. Yep, danke. - Leck-check gleich voll. Enter. Das gleiche Programm läuft. Geben Sie in David wieder. Jetzt sehe ich ein wenig mehr Details. Aber unter dem Haufen Zusammenfassung, die ist identisch mit vier - ah, Das ist ganz nett. Jetzt Valgrind ist eigentlich auf der Suche ein wenig härter in meinem Code. Und es ist, dass es scheint, malloc in Zeile - wir verkleinern. In Zeile - sehen wir nicht, welche Linie es ist. Aber malloc ist der erste Täter. Es ist ein Blog in malloc. Alles klar? OK, nein. Right? Ich rief GetString. getstring anscheinend ruft malloc. Also, was Codezeile ist offenbar Schuld an mit zugeordnet diese Erinnerung? Lassen Sie uns annehmen, daß, wer schrieb malloc hat schon lange genug, dass es nicht ihre Schuld. So ist es wahrscheinlich meine. GetString in cs50.c - so ist das ein Datei irgendwo auf dem Computer - in Zeile 286 scheint die Ursache sein. Nun nehmen wir an, dass CS50 wurde um für anständige Menge an Zeit, so auch wir sind unfehlbar. Und so ist es wahrscheinlich nicht in GetString dass der Fehler liegt, sondern vielmehr in hallo-2.c Linie 18. Werfen wir also einen Blick auf was die Linie 18 war. Oh. Irgendwie ist diese Linie nicht unbedingt Buggy, per se, aber es ist der Grund, hinter dieser Speicherverlust. So super einfach, was würden intuitiv werden hier die Lösung? Wenn wir für das Gedächtnis gefragt sind, waren nie ihn zurück zu geben, und das scheint eine sein Problem, weil im Laufe der Zeit mein Computer könnte über genügend Arbeitsspeicher ausgeführt, verlangsamen könnte nach unten, vielleicht schlimme Dinge passieren, gut, was ist die einfache intuitive Lösung? Gib es zurück. Wie wollen Sie, dass der Speicher frei? Nun, zum Glück ist es ganz einfach nur sagen freien Namen. Und wir haben das noch nie gemacht. Aber man kann im Wesentlichen aus denken frei als das Gegenteil von malloc. kostenlos ist das Gegenteil von Zuweisen von Speicher. So, jetzt lassen Sie mich diese neu zu kompilieren. Machen Sie hallo-2. Lassen Sie mich führen Sie es erneut. hallo-2 David. So scheint es in Arbeit genau die gleiche Weise. Aber wenn ich zurück zu Walgrind und erneut ausführen dass derselbe Befehl auf meinem neu kompilierte Programm, Typisierung in meinem Namen nach wie vor - schön. Heap Zusammenfassung - im Einsatz bei der Ausfahrt - Null-Bytes in Null-Blöcke. Und das ist super nett, alle Heapblöcke befreit wurden. Keine Undichtigkeiten sind möglich. So kommen, nicht mit Problem Set 4, aber mit Problem Set 5, die Forensik und weiter, auch dies wird ein sich Maß für die Richtigkeit Ihrer Programm, ob Sie oder nicht über Speicherlecks. Aber zum Glück können Sie nicht nur die Vernunft durch sie intuitiv, denen ist wohl einfach für kleine Programme aber schwieriger für größere Programme, Walgrind, für jene größeren Programmen kann Ihnen dabei helfen, Das besondere Problem. Aber es gibt ein anderes Problem , die entstehen könnten. Lassen Sie mich öffnen Sie diese Datei hier, das ist, wiederum ein etwas einfaches Beispiel. Aber lassen Sie uns auf das, was konzentrieren dieses Programm macht. Dies nennt man memory.c. Wir veröffentlichen diese im Laufe des Tages in der zip der heutigen Quellcode. Und merke, dass ich eine Funktion namens haben f, die keine Argumente und nimmt nichts zurückgibt. In Zeile 20, ich bin anscheinend die Vereinbarkeit eines Zeiger auf eine int und nannte es x. Ich Zuordnung ist die Rückkehr Wert von malloc. Und nur klar zu sein, wie viele Bytes Uhr Ich wahrscheinlich immer wieder von malloc in dieser Situation? Wahrscheinlich 40. Wo bekommt man das her? Nun, wenn Sie sich erinnern, dass ein int ist oft 4 Bytes, zumindest ist es in der Gerät ist 10 mal 4 40 offensichtlich. So malloc wird wieder eine Adresse ein Teil des Speichers und Speicherung dass adressieren letztlich in x. So klar zu sein, was dann geschieht? Nun, lassen Sie mich zurück schalten zu unserem Bild hier. Lassen Sie mich nicht nur zeichnen die Unterseite meines Arbeitsspeicher des Computers, lass mich gehen Sie vor und ziehen das ganze Rechteck, dass stellt alle meine RAM. Wir sagen, dass der Stapel ist auf der Unterseite. Und es gibt eine Textstelle in die Daten nicht initialisiert. Aber ich werde einfach zu abstrakt solche andere Dinge weg, als Punkt, Punkt Punkt. Ich bin gerade dabei, dies zu beziehen als Haufen an der Spitze. Und dann am unteren Rand des Bildes, Zur Hauptseite stellen, ich werde um ihm eine Scheiben-Speicher auf den Stapel. Für f, werde ich ihm eine Scheibe der Speicher auf dem Stapel. Nun bekam ich zu meinem konsultieren Quellcode wieder. Was sind die lokalen Variablen für die wichtigsten? Offenbar nichts, so dass Scheibe ist effektiv leer oder gar nicht so groß wie ich es gezeichnet. Aber in f, habe ich eine lokale Variable die aufgerufen wird, x. Also werde ich weitermachen und geben f ein Teil des Speichers, nannte es x. Und jetzt malloc von 10 mal 4, So malloc 40, wo das ist Speicher aus? Wir haben nicht ein Bild gezeichnet wie dies vor. Aber nehmen wir an, dass es effektiv ist kommen von hier, so dass man, zwei, drei, vier, fünf. Und jetzt brauche ich 40 von diesen. Also werde ich nur tun, Punkt, Punkt, Punkt zu schlagen dass es noch mehr Speicher auf dem Rückweg von der Halde. Nun, was ist die Adresse? Wir wählen unsere willkürlichen Adresse wie immer - Ox123, obwohl es wahrscheinlich etwas ganz anderes sein. Das ist die Adresse des ersten Bytes in Erinnerung, die ich frage für malloc. Also kurz gesagt, wenn die Leitung 20 führt, was ist buchstäblich gespeichert Innenseite x hier? Ox123. Ox123. Und das Ox ist uninteressant. Es bedeutet nur, hier ist ein Hexadezimalzahl. Aber was ist Schlüssel ist, dass das, was ich habe store in x, die eine lokale Variable. Aber seine Datentyp wieder eine Adresse einer int. Nun, ich werde Ox123 speichern. Aber noch einmal, wenn das ein wenig zu ist unnötig kompliziert, wenn ich blättern zurück, können wir diese abstrakten weg ganz vernünftig und einfach sagen, dass x eine Zeiger auf diesen Teil des Speichers. OK. Nun ist die Frage auf der Hand ist die folgende - Linie 21, es stellt sich heraus, ist buggy. Warum? Es tut uns leid? Es muss nicht - sagen, dass noch einmal. Nun, ist es nicht kostenlos. Also das ist der zweite aber. So gibt es eine andere, sondern speziell in Zeile 21. Genau. Diese einfache Codezeile ist nur ein Pufferüberlauf, ein Pufferüberlauf. Ein Puffer bedeutet nur einen Teil des Speichers. Aber das Teil des Speichers ist von der Größe 10, 10 ganze Zahlen sind, das heißt, wenn wir Index in es mit der syntaktischen Zucker von Array-Notation, das Quadrat Klammern, haben Sie Zugriff auf x 0 x Halter Halterung 1 x, Halterung Punkt, Punkt, Punkt. x Halterung 9 ist die größte. Also, wenn ich x Bügel 10, wo Ich bin eigentlich los in Erinnerung? Nun, wenn ich 10 int - wir eigentlich ziehen alle dieser hier. Das war also die ersten fünf. Hier sind die anderen fünf ints. So x Klammer 0 ist hier. x Halterung 1 ist hier. x Halterung 9 ist hier. x Halterung 10 ist hier, was bedeutet, ich sage, in Zeile 21, um den Computer in der Zahl wo? Die Zahl 0 wo? Nun, es ist 0, ja. Aber gerade die Tatsache, dass seine 0 ist eine Art Zufall. Es könnte die Nummer 50, für alles, was wir kümmern. Aber wir versuchen, es zu x Halterung setzen 10, die, wenn dies Fragezeichen gezeichnet wird, die ist nicht eine gute Sache. Dieses Programm könnte sehr gut Absturz als Folge. Nun, lassen Sie uns gehen und sehen, ob diese ist in der Tat, was passiert. Als Speicher, da die Datei heißt memory.c. Fahren wir fort und führen der Programmspeicher. Also wir Glück haben, tatsächlich, wie es scheint. Wir hatten Glück. Aber lasst uns sehen, ob wir laufen jetzt Valgrind. Auf den ersten Blick könnte mein Programm zu sein scheinen vollkommen richtig. Aber lassen Sie mich laufen Walgrind mit der - Leck-check gleich voll auf das Gedächtnis. Und wenn ich jetzt laufen diese - interessant. Ungültige der Größe 4 schreiben an Zeile 21 memory.c. Zeile 21 von memory.c ist welche? Oh, interessant. Aber warten. Größe 4, was ist das gemeint? Ich habe nur einen zu schreiben, aber es ist der Größe 4. Warum ist es 4? Es ist, weil es ein int, das ist ist wiederum vier Bytes. So einen Bug gefunden Walgrind, dass ich, mit einem Blick auf meinen Code, tat es nicht. Und vielleicht Ihre TF würde oder nicht. Was aber sicher festgestellt, dass Walgrind wir haben einen Fehler gibt, machte auch obwohl wir hatten Glück, und der Computer beschlossen, eh, ich werde nicht zum Absturz nur weil Sie berührt ein Byte, ein int im Wert von Speicher, die Sie nicht tatsächlich besitzen. Nun, was ist hier buggy. Adresse - dies ist ein verrückt aussehenden Adresse in hexadezimal. Das bedeutet nur, irgendwo in der Halde ist Null-Bytes nach einem Block der Größe 40 zugeordnet ist. Lassen Sie mich hier vergrößern und sehen, ob Das ist ein wenig mehr hilfreich. Interessante. 40 Bytes sind definitiv verloren in Verlust-Rekord 1 von 1. Auch hier ist mehr Wörter als nützlich. Aber auf den markierten Linien basieren, wo soll ich wahrscheinlich mein Fokus Aufmerksamkeit für einen anderen bug? Sieht aus wie eine Linie 20 von memory.c. Also, wenn wir zurück in die Linie 20, das ist die eine, die Sie zuvor festgelegt haben. Und es ist nicht unbedingt Buggy. Aber wir haben diese umgekehrt ihre Auswirkungen. Also wie kann ich wenigstens korrigieren einer dieser Fehler? Was könnte ich nach Zeile 21 zu tun? Ich tun konnte, frei von x, so ist zurück zu geben, dass der Speicher. Und wie kann ich diesen Fehler beheben? Ich sollte auf jeden Fall gehen nicht weiter als 0 ist. Also lassen Sie mich versuchen und starten Sie diese. Sorry, auf jeden Fall gehen nicht weiter als 9. Als Erinnerung. Lassen Sie mich erneut Walgrind in einem größeren Fenster. Und jetzt schauen. Nizza. Alle Heapblöcke befreit wurden. Keine Undichtigkeiten sind möglich. Und bis hier oben gibt es keine Erwähnung mehr der unwirksamen rechts. Nur um gierig, und lassen Sie uns sehen, ob eine weitere Demonstration geht nicht wie beabsichtigt - Ich habe Glück vor einem Augenblick. Und die Tatsache, dass diese 0 ist, ist vielleicht unnötig irreführend. Lass uns einfach tun 50, ein etwas willkürlich Zahl, stellen Speicher dot Schrägstrich Speicher - noch Glück. Nichts ist abstürzt. Angenommen, ich nur etwas tun wirklich dumm, und ich tue 100. Lassen Sie mich Remake Speicher, dot Schrägstrich Speicher - hatte Glück wieder. Wie etwa 1.000? ints darüber hinaus, etwa, , wo ich sein sollte? Als Speicher - verdammt. [Gelächter] OK. Lassen Sie uns nicht um mehr durcheinander bringen. Führen Speicher. Dort gehen wir. In Ordnung. So scheinbar Sie Index 100.000 ints über, wo Sie sollten in gewesen sein Speicher, passieren schlimme Dinge. Also das ist offensichtlich nicht eine harte, schnelle Regel. Ich war irgendwie mit Studie und Irrtum, um dorthin zu gelangen. Aber das liegt daran, dass lange Rede kurzer Sinn, Arbeitsspeicher Ihres Computers wird auch geteilt in diesen Dingen Segmente genannt. Und manchmal, der Computer tatsächlich hat Ihnen ein wenig mehr Speicher als Sie verlangen. Aber für Effizienz, es ist nur einfacher, bekommen mehr Speicher, sondern nur sagen, dass Sie immer einen Teil davon. Und wenn Sie Glück haben manchmal, daher könnten Sie in der Lage sein zu berühren Speicher, die nicht Ihnen gehören. Sie haben keine Garantie, dass das, was Wert Sie setzen es wird dort bleiben, weil der Computer immer noch denkt, dass es nicht Ihnen, aber es ist nicht notwendigerweise ein anderes Segment des Speichers in der Trefferliste Computer und induzieren einen Fehler wie dieser hier. In Ordnung. Noch Fragen dann auf der Speicherkarte? In Ordnung. Werfen Sie einen Blick hier, dann bei etwas, was wir schon immer unter gewährt seit geraumer Zeit, die ist in dieser Datei namens cs50.h. So ist dies eine Datei. Dies sind nur ein ganzes Bündel Kommentare bis oben. Und Sie könnten auf diese Option, wenn ausgesehen haben Sie stocherte auf das Gerät. Aber es stellt sich heraus, dass die ganze Zeit, wenn wir verwendet, um eine Zeichenfolge als nutzen Synonym sind die Mittel, mit denen wir erklärt das Synonym war mit diesem Schlüsselwort typedef, für Typ-Definition. Und wir sind im Wesentlichen sagen, machen String Ein Synonym für char Stern. Dass die Mittel, durch die der Stapel erstellt diese Stützräder bekannt als die Zeichenkette. Jetzt ist hier nur ein Prototyp für getchar. Wir könnten es schon einmal gesehen haben, aber das ist in der Tat, was sie tut. getchar nimmt keine Argumente, gibt einen char. getDouble nimmt keine Argumente, gibt eine doppelte. GetFloat nimmt keine Argumente, kehrt einen Schwimmer, und so weiter. getint ist hier. getlonglong ist hier. Und getstring ist hier. Und das ist es. Dieser violette Linie ist ein weiterer Präprozessor Richtlinie wegen der hashtag am Anfang. In Ordnung. So, jetzt lass mich in cs50.c. gehen Und wir werden nicht zu lange sprechen zu diesem Thema. Aber um Ihnen einen Einblick von dem, was wurde auf alles gehen Zeit, lassen Sie mich zu gehen - lass es uns tun getchar. So getchar ist meist Kommentare. Aber es sieht so aus. Also das ist die eigentliche Funktion getchar, dass wir waren nehmen für selbstverständlich vorhanden. Und auch wenn wir nicht dieses eine dass oft, wenn überhaupt, dann ist es zumindest relativ einfach. So lohnt es sich ein kurzen Blick auf hier. So getchar hat eine Endlosschleife, bewusst so offensichtlich. Dann ruft sie - und das ist eine Art von schön Wiederverwendung von Code, den wir uns selbst schrieb. Er fordert getstring. Denn was bedeutet es bedeuten einen char zu bekommen? Nun, könnte man genauso gut versuchen, eine zu bekommen ganze Reihe von Text aus dem Benutzer-und dann einfach auf einen Blick dieser Zeichen. In Zeile 60, ist hier ein wenig Bit einer Plausibilitätsprüfung. Wenn getstring zurückgegeben null, lasst uns nicht gehen. Irgendetwas ist schiefgegangen. Nun, das ist etwas ärgerlich, aber herkömmlichen in C char max wahrscheinlich stellt dar, was gerade basierend auf seinen Namen? Es ist eine Konstante. Es ist wie der numerische Wert des größten char Ihnen darstellen kann einem Biss, das ist wahrscheinlich die Zahl 255, die die größte Zahl, die Sie ist acht Bits repräsentieren, beginnend bei Null. Also habe ich diese, in dieser Funktion, wenn Schreiben Sie diesen Code, nur weil wenn etwas falsch, aber in getchar ihren Zweck im Leben ist, eine Rückkehr char, musst du irgendwie in der Lage sein um dem Benutzer zu signalisieren, dass etwas schief gelaufen ist. Wir können nicht null zurück. Es stellt sich heraus, dass ein Zeiger ist null. Und wieder hat getchar einen char zurückzukehren. Also die Konvention, wenn etwas schief falsch, Sie, der Programmierer, oder in In diesem Fall, mich mit der Bibliothek, hatte ich ein einfach willkürlich entscheiden, ob etwas schief geht, bin ich zu gehen Rückkehr der Nummer 255, das ist wirklich bedeutet, dass wir nicht können, kann der Benutzer nicht geben der Charakter vertreten durch die Nummer 255, denn wir hatten ein stehlen als sog. Sentinel Wert ein Problem darstellen. Jetzt stellt sich heraus, dass das Zeichen 255 ist nicht etwas, das Sie auf eingeben können Ihrer Tastatur, so ist es keine große Sache. Der Benutzer bemerkt nicht, dass Ich habe diesen Charakter gestohlen. Aber wenn Sie jemals in man-Seiten auf eine zu sehen Computersystem einige Verweis auf eine alle Kappen konstant wie diese, die sagt, in Fällen der Fehler dieser konstanten Kraft zurückgegeben werden, das ist alles einige Menschen haben Jahren wurde willkürlich beschlossen senden Sie dieses besondere Wert und nennen es eine Konstante im Fall etwas schief geht. Nun ist die Magie passiert hier unten. Zuerst bin ich in Zeile 67 erklärt zwei Zeichen, C1 und C2. Und dann in Zeile 68, es ist eigentlich eine Codezeile, die erinnert an ist unser Freund printf, da es bedeutet Prozent Cs in Anführungszeichen haben. Aber beachten Sie, was hier passiert. sscanf-String-Scan - bedeutet, scannen eine formatierte string, ergo sscanf. Was bedeutet das? Es heißt, Sie gehen, um eine Zeichenfolge sscanf. Und was auch immer ist Linie der Benutzer in. Sie passieren einen Format-String wie sscanf dies, dass scanf sagt, was sind Sie hoffen, dass der Benutzer eingegeben hat in. Dann übergeben Sie in den Adressen von zwei Stücke von Speicher, in diesem Fall denn ich habe zwei Platzhalter. Also werde ich, um ihm die Adresse von C1 und C2 der Adresse. Und daran erinnern, dass Sie eine Funktion geben, die Adresse einer Variablen, was ist die Implikation? Was kann diese Funktion nicht als Ergebnis von ihm die Adresse eines Variable, im Gegensatz die Variable selbst? Er kann sich ändern, nicht wahr? Wenn Sie hatte jemanden eine Karte zu einem physischen Adresse können sie hingehen und tun was sie an dieser Adresse wollen. Gleiche Idee hier. Wenn wir den Ball zu sscanf, die Adresse von zwei Brocken von Speicher, auch diese winzigen kleine Stücke von Speicher, C1 und C2, aber wir sagen, dass es die Adresse von ihnen, sscanf können es ändern. So sscanf seinen Zweck im Leben, wenn wir lesen Die man-Seite ist zu lesen, was die Benutzer eingetippt, Hoffnung für die Benutzer mit eingegeben in einem Charakter und vielleicht ein anderer Charakter, und was der Benutzer eingegeben, geht das erste Zeichen hier geht das zweite Zeichen hier. Jetzt, als beiseite, dieses, und Sie würden nur wissen das aus der Dokumentation, die Tatsache, dass ich ein Leerzeichen setzen dort bedeutet nur, dass ich mich nicht, wenn der Benutzer trifft der Leertaste ein paar mal, bevor er oder sie nimmt eine Charakter, werde ich ignorieren einem weißen Raum. So, dass weiß ich aus die Dokumentation. Die Tatsache, dass es eine zweite% c gefolgt von Leerraum ist eigentlich gewollt. Ich möchte in der Lage sein zu erkennen, ob der Benutzer up oder verschraubt nicht mit. Also hoffe ich, dass der Benutzer nur getippt in einem Zeichen, daher hoffe ich, das sscanf wird nur gehen, um die Rückkehr Wert 1, weil wieder, wenn ich lese die Dokumentation, sscanf seinen Zweck in Lebensziel ist es, die Anzahl der zurück Variablen, die gefüllt waren mit Benutzereingaben. Ich ging in zwei Variablen Adressen, C1 und C2. Ich hoffe aber, dass nur einer der ihnen getötet wird, denn wenn sscanf den Wert 2, was ist vermutlich die Implikation logisch? Dass der Benutzer nicht nur geben Sie mir eine Charakter, wie ich sagte ihm oder ihr. Wahrscheinlich bei getippt mindestens zwei Buchstaben. Also, wenn ich stattdessen nicht die zweite % C, ich hatte gerade eine, die ehrlich gesagt wäre intuitiver Ansatz, denke ich einen ersten Blick du wirst nicht in der Lage sein zu erkennen, wenn der Benutzer wurde Ihnen mehr Eingang, als Sie eigentlich wollten. Das ist also eine implizite Form der Fehlerprüfung. Aber beachten Sie, was ich hier zu tun. Sobald ich bin sicher, dass der Benutzer gab mir eine Charakter, befreien ich die Linie, zu tun das Gegenteil von getstring, was wiederum malloc verwendet, und dann bin ich zurück C1, das Zeichen, dass ich hoffte, dass die Benutzer zur Verfügung gestellt und zur Verfügung gestellt. So eine schnelle flüchtig nur, aber Fragen zum getchar? Wir kommen zurück, um einige der anderen. Nun, lassen Sie mich gehen Sie vor und tun dies - Nehmen wir nun an, nur um zu motivieren unsere Diskussion in einer Woche plus Zeit, diese ist eine Datei namens structs.h. Und wieder, das ist nur ein Vorgeschmack von etwas, das vor uns liegt. Beachten Sie aber, dass eine Menge Dies hat Kommentare. Also lassen Sie mich unterstreichen nur die Interessant für jetzt. typedef - es ist das gleiche Keyword erneut. typedef wir verwenden, um String deklarieren als spezieller Datentyp. Sie können typedef, um neue zu schaffen Datentypen, die nicht existieren, wenn C erfunden wurde. Zum Beispiel kommt int mit C. char kommt mit Doppel-C kommt mit C. Aber gibt es keine Vorstellung von einem Schüler. Und doch wäre es ziemlich nützlich zu sein in der Lage, ein Programm, das speichert schreiben in einer Variablen, eines Schülers ID-Nummer, ihren Namen, und ihr Haus. Mit anderen Worten, drei Stücke von Daten, wie ein int und ein String und andere Zeichenfolge. Mit typedef, was ist ziemlich mächtig über dies und das Schlüsselwort für sturct Struktur, Sie als Programmierer im Jahr 2013, tatsächlich eigene definieren die Datentypen, die nicht existierten Jahre her, aber dass Ihre Zwecke. Und hier, in den Zeilen 13 bis 19, wir erklären einen neuen Datentyp, wie ein int, aber nannte es Schüler. Und innerhalb dieser Variablen wird zu gehen sein drei Dinge - ein int, String, und eine Zeichenfolge. So können Sie von dem, was wirklich hier passiert ist, obwohl es sich um eine Bit einer Vereinfachung für heute, ein Student im Wesentlichen gehen wie folgt aussehen. Sein Gehen, ein Stück sein Speicher mit einer ID, ein Name Feld, und ein Haus ein. Und wir werden in der Lage sein, diese Stücke verwenden Speicher und greifen Sie wie folgt. Wenn ich in struct0.c gehen, ist hier ein relativ lang, aber nach einer Muster, der Code, verwendet diesen neuen Trick. Also lassen Sie mich zunächst darauf aufmerksam zu den interessanten Teilen bis oben. Sharp legt Studenten 3, erklärt ein Konstante namens Studenten und Abtretungsempfänger willkürlich die Zahl 3, nur so habe ich drei Studenten, die mit dieses Programm für heute. Kommt Main. Und beachtet, wie kann ich erklären eine Reihe von Studenten? Nun, ich nutze einfach die gleiche Syntax. Das Wort Student ist offensichtlich neu. Aber Schüler, Klasse, Schüler Halterung. So leider gibt es eine Menge der Wiederverwendung von Begriffen hier. Dies ist nur eine Nummer. Also das ist wie gesagt drei. Klasse ist genau das, was ich will die Variable nennen. Ich könnte es Studenten. Aber Klasse, ist dies nicht eine Klasse in ein objektorientierten Java Art und Weise. Es ist nur eine Klasse von Schülern. Und der Datentyp jedes Elements in diesem Array ist Student. Also das ist ein wenig anders und von etwas zu sagen wie diese, es ist nur - Ich sage mir drei Studenten und rufen Sie das Array-Klasse. In Ordnung. Jetzt ist hier eine vier-Schleife. Dieser Kerl ist vertraut - iterate von Null auf bis zu drei. Und hier ist das neue Stück von Syntax. Das Programm wird mich veranlassen, der Mensch, um ihm ein Student ID, die ein int ist. Und hier ist die Syntax, mit denen Sie speichern etwas in der ID-Feld auf Lageklasse Halterung I. So Diese Syntax ist nicht neu. Dies bedeutet nur, gib mir die achte Schüler in der Klasse. Aber das Symbol ist neu. Bis jetzt haben wir nicht genutzt dot, zumindest in Code wie diesen. Das bedeutet, auf die Struktur bekannt als gehen ein Student und legte dort etwas. Auch in diesem nächsten Zeile, 31, gehen voran und setzen, was der Benutzer-Typen für Sie hier einen Namen und was sie für eine Haus, dasselbe, gehen Sie vor und steckte es in. Hauses. Also, was macht dieses Programm letztendlich zu tun? Sie können einen kleinen Vorgeschmack gibt. Lassen Sie mich gehen Sie vor und machen Sie Strukturen 0 dot Schrägstrich struct 0, Schüler-ID 1, sagen David Mather, Studentenausweis 2. Rob Kirkland, Studentenausweis 3. Lauren Leverit - und das einzige, was dieses Programm haben, Das ist einfach völlig willkürlich, wird Ich wollte etwas mit diesen Daten zu tun, jetzt, dass ich uns gelehrt, wie man Strukturen verwenden, ist, dass ich gerade diese zusätzliche Schleife hier. Ich über die Anordnung der Studierenden durchlaufen. Früher habe ich unsere, vielleicht inzwischen vertrauten Freund, String vergleichen, um stircomp Check ist der 8. Schülers Haus gleich Mather? Und wenn ja, nur etwas ausdrucken willkürlich mag, ja, das ist es. Aber noch einmal, nur gibt mir Möglichkeiten zu nutzen und wiederzuverwenden und Wiederverwendung dieser neuen dot-Notation. Also wer sich interessiert, nicht wahr? Coming up mit einem Schüler-Programm ist etwas willkürlich, aber es stellt sich heraus, dass wir nützliche Dinge tun mit Dies ist zum Beispiel wie folgt. Dies ist ein komplizierter struct in C. Es hat ein Dutzend oder mehr Felder, etwas kryptisch benannt. Aber wenn Sie jemals von einem Grafik gehört Dateiformat namens Bitmap, BMP, es stellt sich heraus, dass die Bitmap-Datei-Format ziemlich ähnlich sieht, dass diese. Es ist eine dumme kleine Smiley Gesicht. Es ist ein kleines Bild, dass ich in gezoomt auf ziemlich groß, so dass ich sehen konnte jeder von den einzelnen Punkten oder Pixeln. Nun, es stellt sich heraus, dass wir ein darstellen kann black dot mit, sagen wir, die Zahl 0. Und ein weißer Punkt mit der Nummer 1. Also mit anderen Worten, wenn Sie wollen, ziehen ein Smiley-Gesicht und speichern Sie das Bild in ein Computer, genügt es, Nullen speichern und diejenigen, die so aussehen, wo wieder, sind diejenigen, weiß und Nullen sind schwarz. Und gemeinsam, wenn Sie effektiv haben ein von Einsen und Nullen rüsten, haben Sie ein Gitter aus Pixeln, und wenn Sie legen sie aus, haben Sie eine nette wenig Smiley Gesicht. Nun ist Bitmapdateiformat, BMP, effektiv, dass unter der Haube, aber mit mehr Pixeln sot, dass Sie kann tatsächlich repräsentieren Farben. Aber wenn man über kompliziertere Dateiformate wie BMP und JPEG und GIF mit denen Sie vielleicht kennen, die Dateien auf der Festplatte in der Regel nicht nur haben Nullen und Einsen für die Pixel, aber sie haben einige Metadaten sowie - meta in dem Sinne, das ist nicht wirklich Daten, aber es ist nützlich zu haben. Also diese Felder hier impliziert, und wir werden diese im Detail in P-Satz zu sehen 5, dass vor den Nullen und Einsen, dass stellen die Pixel in einem Bild, gibt es eine Reihe von Metadaten wie die Größe des Bildes und die Breite des Bildes. Und ich merke, ich Rupfen aus einige beliebige Dinge hier - Breite und Höhe. Bit count und einige andere Dinge. So gibt es einige Metadaten in einer Datei. Aber durch das Verständnis, wie die Dateien gelegt werden auf diese Weise kann man tatsächlich dann Bearbeiten von Bildern, erholen Bilder von der Festplatte, die Größe von Bildern. Aber man kann nicht unbedingt verbessern sie. Ich brauchte ein Foto. Also ging ich zurück zu RJ hier, die du gesehen hast, auf dem Bildschirm schon vor einiger Zeit. Und wenn ich Keynote hier öffnen, ist dies was passiert, wenn Sie versuchen, um es zu vergrößern und RJ verbessern. Er ist nicht besser, wirklich. Jetzt Keynote ist eine Art verwischt es ein wenig, nur um über den Glanz Tatsache, dass RJ nicht besonders bekommen erhöht, wenn Sie in. vergrößern Und wenn es auf diese Weise, sehen die Quadrate? Ja, können Sie auf jeden Fall sehen die Quadrate auf einem Projektor. Das ist, was Sie, wenn Sie verbessern zu bekommen. Aber zu verstehen, wie unsere RJ oder die Smiley-Gesicht umgesetzt wird uns tatsächlich Code schreiben, der manipuliert diese Dinge. Und ich dachte, ich würde in diesem Sinne zu beenden, mit 55 Sekunden von einer Verbesserung ist, dass, Ich wage, sagen wir eher irreführend. [VIDEO PLAYBACK] -Er lügt. Über was, ich weiß nicht. -Also, was wissen wir? -Das um 9:15 Ray Santoya war bei der ATM. -Die Frage ist also, was tat er um 9:16? -Schießen die neun Millimeter auf etwas. Vielleicht sah er die Scharfschützen. -Oder war die Arbeit mit ihm. -Warten. Zurück eins. -Was sehen Sie? -Bringen Sie sein Gesicht, Vollbild. -Seine Brille. -Es ist eine Reflexion. -Das ist die Neuvitas Baseball-Team. Das ist ihr Logo. -Und er hat zu reden, wer ist Tragen diese Jacke. [END VIDEO PLAYBACK] DAVID J. MALAN: Dies wird sein Problem Set 5. Wir sehen uns nächste Woche. Männlicher Sprecher: An der nächsten CS50. [Grillen zirpen] [Musik spielt]