1 00:00:00,000 --> 00:00:02,500 [Powered by Google Translate] [Abschnitt 5 - komfortabler] 2 00:00:02,500 --> 00:00:04,690 [Rob Bowden - Harvard University] 3 00:00:04,690 --> 00:00:07,250 [Dies ist CS50. - CS50.TV] 4 00:00:08,990 --> 00:00:14,250 >> Wie ich in meinem E-Mail-gesagt, es gibt eine Menge Dinge, die Sie verwenden können 5 00:00:14,250 --> 00:00:17,060 andere als das Gerät tatsächlich nicht das Problem Sets. 6 00:00:17,060 --> 00:00:19,910 Wir empfehlen, dass Sie sie in das Gerät nur, weil dann können wir leicht helfen Ihnen 7 00:00:19,910 --> 00:00:22,070 und wir wissen, wie alles funktionieren wird. 8 00:00:22,070 --> 00:00:26,950 Aber als ein Beispiel, wo man Dinge tun kann, wenn, sagen wir, müssen Sie nicht den Zugang 9 00:00:26,950 --> 00:00:31,570 zu einem Gerät oder Sie wollen in der Science Center Keller arbeiten - 10 00:00:31,570 --> 00:00:33,090 was eigentlich haben sie das Gerät auch - 11 00:00:33,090 --> 00:00:35,150 Wenn Sie irgendwo arbeiten wollen. 12 00:00:35,150 --> 00:00:42,370 Ein Beispiel ist hast du gesehen / gehört der SSH? 13 00:00:44,380 --> 00:00:47,780 SSH ist im Grunde wie eine Verbindung zu etwas. 14 00:00:47,780 --> 00:00:51,340 Eigentlich im Moment bin ich in das Gerät SSHed. 15 00:00:51,340 --> 00:00:54,290 Ich habe nie direkt in der Appliance. 16 00:00:55,930 --> 00:01:01,060 Hier ist das Gerät, und wenn man hier unten sehen Sie diese IP-Adresse. 17 00:01:01,060 --> 00:01:03,650 Ich habe nie in das Gerät selbst zu arbeiten; 18 00:01:03,650 --> 00:01:08,840 Ich komme immer mehr zu einem iTerm2 Fenster / Terminal-Fenster. 19 00:01:08,840 --> 00:01:15,910 Sie können SSH zu dieser IP-Adresse, ssh jharvard@192.168.129.128. 20 00:01:15,910 --> 00:01:20,390 Ich erinnere mich an diese Nummer sehr leicht, weil es so ein schönes Muster ist. 21 00:01:20,390 --> 00:01:24,920 Aber das wird mich nach meinem Passwort fragen, und jetzt bin ich in das Gerät. 22 00:01:24,920 --> 00:01:33,060 Grundsätzlich an diesem Punkt, wenn Sie eröffnet eine Klemme im Inneren des Gerätes selbst, 23 00:01:33,060 --> 00:01:36,350 diese Schnittstelle, aber Sie würden es zu benutzen, ist genau das gleiche 24 00:01:36,350 --> 00:01:40,010 als Schnittstelle Ich verwende hier aber jetzt bist du SSHed. 25 00:01:42,240 --> 00:01:44,920 Sie brauchen nicht zu SSH auf das Gerät haben. 26 00:01:44,920 --> 00:01:52,360 Ein Beispiel für einen anderen Ort konnte man SSH ist, ich bin mir ziemlich sicher, dass Sie standardmäßig - 27 00:01:52,360 --> 00:01:55,020 Oh. Bigger. 28 00:01:55,020 --> 00:02:01,130 Alle von euch sollte standardmäßig FAS Konten auf den FAS-Server haben. 29 00:02:01,130 --> 00:02:06,840 Für mich würde ich SSH rbowden@nice.fas.harvard.edu. 30 00:02:06,840 --> 00:02:11,610 Es wird, dass die erste Zeit zu fragen, und Sie sagen, ja. 31 00:02:11,610 --> 00:02:15,840 Mein Passwort ist gerade dabei, meinen FAS Passwort sein. 32 00:02:15,840 --> 00:02:22,650 Und jetzt bin ich auf die schöne Servern SSHed, und ich kann was ich will hier tun. 33 00:02:22,650 --> 00:02:28,560 Eine Menge von Klassen, die Sie nehmen, könnte wie 124, gehen zu müssen, die Sie hochladen Zeug hier 34 00:02:28,560 --> 00:02:30,950 tatsächlich senden Sie Ihre Problemstellungen. 35 00:02:30,950 --> 00:02:34,100 Aber sagen Sie nicht haben Zugriff auf Ihr Gerät. 36 00:02:34,100 --> 00:02:37,910 Dann können Sie Dinge tun, wie hier wird es sagen - 37 00:02:37,910 --> 00:02:42,160 Dies ist nur unserer Sektion der Fragen. 38 00:02:42,160 --> 00:02:45,070 Es wird Sie bitten, dies in dem Gerät zu tun. 39 00:02:45,070 --> 00:02:47,790 Stattdessen werde ich es einfach tun auf dem Server. 40 00:02:47,790 --> 00:02:50,560 Ich werde um sie zu entpacken, dass. 41 00:02:50,560 --> 00:02:55,670 Das Problem wird sein, dass Sie mit so etwas wie gedit gewohnt 42 00:02:55,670 --> 00:02:58,160 oder was auch immer im Inneren des Gerätes. 43 00:02:58,160 --> 00:03:01,830 Du wirst nicht mit der auf dem FAS-Server haben. 44 00:03:01,830 --> 00:03:04,110 Es ist alles nur gehen, um diese textuelle Schnittstelle. 45 00:03:04,110 --> 00:03:09,180 So können Sie entweder ein, versuchen Sie einen Text-Editor, dass sie haben zu lernen. 46 00:03:09,180 --> 00:03:12,130 Sie haben Nano. 47 00:03:12,130 --> 00:03:14,990 Nano ist in der Regel recht einfach zu bedienen. 48 00:03:14,990 --> 00:03:19,470 Sie können Ihre Pfeile und geben in der Regel. 49 00:03:19,470 --> 00:03:21,250 Also das ist nicht schwer. 50 00:03:21,250 --> 00:03:24,720 Wenn Sie sich wirklich hübsch machen wollen, können Sie Emacs, 51 00:03:24,720 --> 00:03:29,850 was ich sollte wohl nicht geöffnet werden, weil ich nicht einmal weiß, wie man Emacs zu schließen haben. 52 00:03:29,850 --> 00:03:32,760 Control X, Control C? Yeah. 53 00:03:32,760 --> 00:03:35,310 Oder Sie können Vim, was ich verwenden soll. 54 00:03:35,310 --> 00:03:37,800 Und also sind Ihre Möglichkeiten. 55 00:03:37,800 --> 00:03:43,830 Wenn Sie nicht wollen, das zu tun, können Sie auch, wenn man sich manual.cs50.net-- 56 00:03:43,830 --> 00:03:45,410 Oh. 57 00:03:45,410 --> 00:03:49,920 Auf einem PC, können Sie SSH mit PuTTY, 58 00:03:49,920 --> 00:03:51,940 die Sie gehen zu müssen separat heruntergeladen werden. 59 00:03:51,940 --> 00:03:55,460 Auf einem Mac können Sie einfach standardmäßig Einsatz Terminal oder können Sie iTerm2, 60 00:03:55,460 --> 00:03:58,490 das ist wie eine schöne, ausgefallene Terminal. 61 00:03:58,490 --> 00:04:03,780 Wenn Sie manual.cs50.net gehen Sie sehen einen Link zu Notepad + +, 62 00:04:03,780 --> 00:04:07,120 das ist, was Sie auf einem PC verwenden. 63 00:04:07,120 --> 00:04:13,340 Es ermöglicht Ihnen SFTP von Notepad + + ist was im Grunde SSH. 64 00:04:13,340 --> 00:04:17,750 Was dies können Sie tun, ist zu bearbeiten Sie Ihre Dateien lokal, 65 00:04:17,750 --> 00:04:20,670 und dann, wenn Sie sie speichern möchten, wird es nice.fas speichern, 66 00:04:20,670 --> 00:04:23,670 wo man dann laufen sie. 67 00:04:23,670 --> 00:04:26,880 Und das Äquivalent auf einem Mac wird TextWrangler sein. 68 00:04:26,880 --> 00:04:28,760 So können Sie das gleiche tun. 69 00:04:28,760 --> 00:04:32,800 Damit können Sie Dateien bearbeiten lokal und speichern Sie sie auf nice.fas, 70 00:04:32,800 --> 00:04:35,730 wo man dann laufen sie. 71 00:04:35,730 --> 00:04:40,400 Also, wenn Sie jemals ohne ein Gerät stecken sind, haben Sie diese Optionen 72 00:04:40,400 --> 00:04:44,230 noch nicht Ihr Problem Sets. 73 00:04:44,230 --> 00:04:48,250 Das einzige Problem wird sein, dass Sie nicht gehen, um den CS50 Bibliothek haben 74 00:04:48,250 --> 00:04:51,580 weil nice.fas nicht standardmäßig das haben. 75 00:04:51,580 --> 00:04:55,970 Sie können entweder den CS50-Bibliothek - 76 00:04:55,970 --> 00:04:58,470 Ich glaube nicht, brauche ich an dieser Stelle. 77 00:04:58,470 --> 00:05:03,270 Sie können entweder den CS50-Bibliothek und kopieren Sie ihn auf nice.fas, 78 00:05:03,270 --> 00:05:07,450 oder ich denke wir an dieser Stelle nicht mehr benutzte sowieso. 79 00:05:07,450 --> 00:05:12,720 Oder wenn wir das tun, können Sie für die Zeit, die es ersetzen 80 00:05:12,720 --> 00:05:18,480 die Implementierungen der Funktionen in der CS50-Bibliothek sowieso. 81 00:05:18,480 --> 00:05:21,370 So das sollte nicht so viel von einer Beschränkung. 82 00:05:21,370 --> 00:05:23,710 Und das ist es. 83 00:05:26,460 --> 00:05:29,820 >> Ich gehe zurück zu dem Gerät jetzt werden wir alles in dem Gerät zu tun. 84 00:05:29,820 --> 00:05:37,510 Mit Blick auf unserer Sektion der Fragen am Anfang, wie ich in meinem E-Mail-sagte, 85 00:05:37,510 --> 00:05:43,620 Wir müssen über die ein Kurz gesagt, Sie sollen sehen waren reden. 86 00:05:43,620 --> 00:05:51,980 Wir haben das Umleiten & Pipes und diese drei Fragen. 87 00:05:51,980 --> 00:05:56,070 >> Um die Stream Sie Funktionen wie printf standardmäßig schreiben? 88 00:05:56,070 --> 00:05:59,130 So Stream. Was ist ein Stream? 89 00:06:06,520 --> 00:06:15,100 Ein Strom ist im Grunde wie es nur einige - 90 00:06:15,100 --> 00:06:21,450 Es ist nicht einmal eine Quelle von 1s und 0s. 91 00:06:21,450 --> 00:06:24,920 Der Stream es hier zu fragen ist serienmäßig aus. 92 00:06:24,920 --> 00:06:27,250 Und so Standardausgabe ist ein Strom, wenn Sie es schreiben, 93 00:06:27,250 --> 00:06:30,940 es erscheint auf dem Bildschirm. 94 00:06:30,940 --> 00:06:36,860 Standard aus, indem Strom, es heißt, Sie schreiben einfach 1s und 0s es, 95 00:06:36,860 --> 00:06:40,220 und das andere Ende der Standardausgabe gerade liest aus diesem Stream. 96 00:06:40,220 --> 00:06:43,540 Es ist nur eine Reihe von 1s und 0s. 97 00:06:43,540 --> 00:06:45,570 Sie können Streams schreiben oder Sie können aus Bächen lesen 98 00:06:45,570 --> 00:06:47,950 je nachdem, was der Strom tatsächlich ist. 99 00:06:47,950 --> 00:06:52,800 Die beiden anderen Standard-Streams sind Standard in und Standardfehler. 100 00:06:52,800 --> 00:06:57,540 Standard in ist, wenn Sie GetString tun, ist es für Sie zur Eingabe Sachen warten. 101 00:06:57,540 --> 00:07:01,570 So ist es für Sie warten, ist es eigentlich wartet auf Standard-in, 102 00:07:01,570 --> 00:07:04,880 das ist wirklich das, was Sie, wenn Sie über die Tastatur einzugeben bekommen. 103 00:07:04,880 --> 00:07:07,530 Sie sind in Standard in. eingeben 104 00:07:07,530 --> 00:07:10,050 Standardfehler ist im Grunde gleichwertig in die Standardausgabe, 105 00:07:10,050 --> 00:07:13,280 aber es ist spezialisiert auf, dass, wenn Sie Standard-Fehler drucken, 106 00:07:13,280 --> 00:07:16,770 Sie soll nur drucken, Fehlermeldungen, dass 107 00:07:16,770 --> 00:07:20,200 so können Sie zwischen den regulären Nachrichten auf dem Bildschirm ausgegeben zu unterscheiden 108 00:07:20,200 --> 00:07:24,560 gegenüber Fehlermeldungen je nachdem, ob sie gingen die Standardausgabe oder Standardfehler. 109 00:07:24,560 --> 00:07:28,660 Dateien zu. 110 00:07:28,660 --> 00:07:32,440 Standard aus, Standard und Standardfehler sind nur spezielle Streams 111 00:07:32,440 --> 00:07:36,810 aber wirklich jeder Datei, wenn Sie eine Datei öffnen, wird es einen Stream von Bytes 112 00:07:36,810 --> 00:07:40,740 wo man gerade aus diesem Stream zu lesen. 113 00:07:40,740 --> 00:07:47,770 Sie zum größten Teil kann nur einer Datei als einen Strom von Bytes zu denken. 114 00:07:47,770 --> 00:07:51,190 Also, was Streams sie schreibt standardmäßig? Standard aus. 115 00:07:51,190 --> 00:07:56,980 >> Was ist der Unterschied zwischen> und? >> 116 00:07:58,140 --> 00:08:03,710 Hat jemand das Video vorher? Okay. 117 00:08:03,710 --> 00:08:10,960 > Sein wird, wie Sie in Dateien umzuleiten, 118 00:08:10,960 --> 00:08:15,240 und >> wird sich auch die Ausgabe in eine Datei umleiten, 119 00:08:15,240 --> 00:08:17,820 aber es ist anstatt gehen, um die Datei anzuhängen. 120 00:08:17,820 --> 00:08:23,430 Zum Beispiel, sagen wir, ich zufällig dict hier haben, 121 00:08:23,430 --> 00:08:27,020 und das einzige Zeug in der dict ist Katze, Katze, Hund, Fische, Hund. 122 00:08:27,020 --> 00:08:31,530 Ein Befehl, den Sie in der Befehlszeile haben, ist cat, 123 00:08:31,530 --> 00:08:34,539 das ist nur Drucklegung, was in einer Datei. 124 00:08:34,539 --> 00:08:40,679 Also, wenn ich cat dict sagen, es geht um Katze, Katze, Hund, Fisch, Hund drucken. Das ist alles, Katze tut. 125 00:08:40,679 --> 00:08:46,280 Das bedeutet, dass sie auf die Standardausgabe gedruckt Katze, Katze, Hund, Fische, Hund. 126 00:08:46,280 --> 00:08:53,240 Wenn ich stattdessen möchten, dass in eine Datei umleiten, kann ich> und leiten es an, was die Datei ist. 127 00:08:53,240 --> 00:08:56,460 Ich rufe die Datei Datei. 128 00:08:56,460 --> 00:09:00,320 So wenn ich nun ls, werde ich sehen, ich habe eine neue Datei namens Datei. 129 00:09:00,320 --> 00:09:05,700 Und wenn ich es öffnen, es zu haben, genau das, was Katze an der Kommandozeile eingegeben werden. 130 00:09:05,700 --> 00:09:11,040 So, jetzt, wenn ich das wieder tun, dann wird es die Ausgabe in Datei umleiten, 131 00:09:11,040 --> 00:09:13,930 und ich werde genau die gleiche Sache zu haben. 132 00:09:13,930 --> 00:09:17,910 So technisch, es vollständig hinwegsetzte, was wir hatten. 133 00:09:17,910 --> 00:09:22,970 Und wir werden sehen, ob ich dict ändern, nahm ich Hund. 134 00:09:22,970 --> 00:09:29,980 Nun, wenn wir cat dict in die Datei wieder, werden wir die neue Version mit Hund entfernt haben. 135 00:09:29,980 --> 00:09:32,400 So ist es komplett überschreibt es. 136 00:09:32,400 --> 00:09:36,640 Stattdessen, wenn wir >> verwenden, es geht um die Datei anzuhängen. 137 00:09:36,640 --> 00:09:40,860 Nun Öffnen der Datei, sehen wir uns genau das gleiche zweimal gedruckt 138 00:09:40,860 --> 00:09:44,920 weil es dort einmal war, dann werden wir auf die ursprüngliche angehängt. 139 00:09:44,920 --> 00:09:48,130 Also das ist, was> und >> tun. 140 00:09:48,130 --> 00:09:50,580 Ist die nächste fragen - Es ist nicht danach zu fragen. 141 00:09:50,580 --> 00:09:59,050 >> Die andere, die wir haben <, die, wenn> leitet die Standardausgabe, 142 00:09:59,050 --> 00:10:01,970 00:10:12,050 Mal sehen, ob wir ein Beispiel. 144 00:10:14,750 --> 00:10:16,930 Ich kann ein sehr kurz. 145 00:10:17,870 --> 00:10:25,700 Nehmen wir eine beliebige Datei, hello.c. 146 00:10:56,060 --> 00:10:59,070 Relativ unkompliziert Datei. 147 00:10:59,070 --> 00:11:03,570 Ich bin gerade erst einen String und dann gedruckt "Hallo", was der Saite, die ich gerade eingegeben war. 148 00:11:03,570 --> 00:11:07,990 So hallo und dann. / Hallo. 149 00:11:07,990 --> 00:11:10,720 Jetzt ist es auffordert mir etwas geben, 150 00:11:10,720 --> 00:11:15,070 was bedeutet, dass es auf die Dinge warten, um in Standard in. eingegeben werden 151 00:11:15,070 --> 00:11:20,450 So geben was ich in Standard möchten in. Wir haben gerade gehst zu sagen Hallo, Rob! 152 00:11:20,450 --> 00:11:23,310 Dann ist es Standard-Ausdruck Hallo, Rob! 153 00:11:23,310 --> 00:11:28,860 Wenn ich das tue. / Hallo und dann umleiten, 154 00:11:30,740 --> 00:11:34,310 jetzt kann man nur aus einer Datei umzuleiten. 155 00:11:34,310 --> 00:11:41,720 Also, wenn ich habe in einigen Datei, txt, und ich legte Rob, 156 00:11:41,720 --> 00:11:52,300 wenn ich laufe hallo und dann leiten Sie die Datei txt in. / hallo, es geht zu sagen, Hallo, Rob! sofort. 157 00:11:52,300 --> 00:11:57,160 Wenn es zuerst bekommt GetString und es ist auf Standard-Wartezeit in, 158 00:11:57,160 --> 00:12:01,730 Standard ist nicht mehr warten auf die Tastatur für die Daten eingegeben zu werden. 159 00:12:01,730 --> 00:12:05,980 Stattdessen haben wir weitergeleitet Standard aus der Datei txt lesen. 160 00:12:05,980 --> 00:12:10,290 Und so geht aus der Datei txt, die nur die Linie Rob ist zu lesen, 161 00:12:10,290 --> 00:12:13,380 und dann es wird Hallo, Rob drucken! 162 00:12:13,380 --> 00:12:18,180 Und wenn ich wollte, könnte ich auch tun. / Hallo 00:12:21,500 und dann der Standard, dass es der Druckerei, die Hallo ist, Rob!, 164 00:12:21,500 --> 00:12:24,700 Das kann ich in eine eigene Datei umzuleiten. 165 00:12:24,700 --> 00:12:29,790 Ich werde einfach rufen Sie die Datei hallo - nein, das werde ich nicht, denn das ist die ausführbare Datei - txt2. 166 00:12:29,790 --> 00:12:40,150 Nun wird txt2 werde die Ausgabe von. / Hallo 00:12:43,520 >> Haben Sie Fragen? 168 00:12:45,900 --> 00:12:49,090 >> Okay. Also hier haben wir Pipeline. 169 00:12:49,090 --> 00:12:53,510 Pipes sind die letzte Einheit der Umleitung. 170 00:12:53,510 --> 00:12:58,750 >> Oh. Ich denke, eine weitere Einheit der Umleitung, wenn anstelle von> Sie 2> 171 00:12:58,750 --> 00:13:01,070 Das ist umleiten Standardfehler. 172 00:13:01,070 --> 00:13:06,280 Also, wenn etwas ging Standardfehler, wäre es nicht in txt2 gelegt bekommen. 173 00:13:06,280 --> 00:13:12,480 Aber merken, wenn ich 2> zu tun, dann ist es immer noch gedruckt Hallo, Rob! in der Befehlszeile 174 00:13:12,480 --> 00:13:18,600 weil ich nur umgeleitet werde Standardfehler, ich bin nicht umleiten Standardausgabe. 175 00:13:18,600 --> 00:13:22,210 Standardfehler und Standardausgabe sind unterschiedlich. 176 00:13:24,210 --> 00:13:27,080 Wollte man tatsächlich Standardfehler schreiben, 177 00:13:27,080 --> 00:13:35,080 dann könnte ich dies ändern zu fprintf auf stderr. 178 00:13:35,080 --> 00:13:37,850 So printf, die standardmäßig druckt die Standardausgabe. 179 00:13:37,850 --> 00:13:41,720 Wenn ich auf Standard-Fehler manuell drucken möchten, dann muss ich fprintf verwenden 180 00:13:41,720 --> 00:13:45,010 und geben, was ich drucken möchten. 181 00:13:45,010 --> 00:13:49,720 Wenn ich stattdessen fprintf stdout hat, dann ist das im Grunde gleichwertig zum printf. 182 00:13:49,720 --> 00:13:55,530 Aber fprintf Standard-Fehler. 183 00:13:57,790 --> 00:14:03,650 So, jetzt, wenn ich diese Umleitung in txt2, Hallo, Rob! ist noch immer in der Befehlszeile gedruckt 184 00:14:03,650 --> 00:14:08,270 Da es gewöhnungsbedürftig Standardfehler gedruckt und ich bin nur umleiten Standardausgabe. 185 00:14:08,270 --> 00:14:16,420 Wenn ich umleiten jetzt Standardfehler, jetzt ist es nicht gedruckt wird, erhalten und txt2 sein wird Hallo, Rob! 186 00:14:16,420 --> 00:14:21,910 So, jetzt können Sie Ihre tatsächliche Fehler auf stderr gedruckt 187 00:14:21,910 --> 00:14:24,720 und drucken Sie Ihre regelmäßigen Nachrichten in die Standardausgabe. 188 00:14:24,720 --> 00:14:31,420 Und so, wenn Sie Ihr Programm ausführen, können Sie es als laufen. / Hallo diese Art mit dem 2> 189 00:14:31,420 --> 00:14:33,800 so dass Ihr Programm wird normal ausgeführt, 190 00:14:33,800 --> 00:14:38,400 aber alle Fehlermeldungen, die Sie erhalten, können Sie später überprüfen in Ihrem Fehlerprotokoll 191 00:14:38,400 --> 00:14:44,500 so Fehler, und dann später aussehen und Ihre Fehler Datei wird alle Fehler, die passiert sind. 192 00:14:45,200 --> 00:14:47,540 >> Haben Sie Fragen? 193 00:14:47,540 --> 00:14:58,070 >> Der letzte ist Rohr, die Sie sich als unter den Standard aus einem Befehl denken kann 194 00:14:58,070 --> 00:15:01,210 und macht es der Standard in der nächsten Befehl. 195 00:15:01,210 --> 00:15:05,570 Ein Beispiel ist hier echo ist ein Kommandozeilen-Sache 196 00:15:05,570 --> 00:15:11,840 Das ist gerade dabei, echo, was ich als Argument. Ich werde nicht Anführungszeichen setzen. 197 00:15:11,840 --> 00:15:16,150 Echo blah, blah, blah ist gerade dabei, blah, blah, blah drucken. 198 00:15:16,150 --> 00:15:20,600 Früher, als ich sagte, ich musste Rob in eine txt Datei ablegen 199 00:15:20,600 --> 00:15:28,830 da kann ich nur umzuleiten txt-Dateien, sondern / wenn ich echo Rob 200 00:15:28,830 --> 00:15:35,520 und leiten sie in. / Hallo, das wird auch nicht die gleiche Art von Ding. 201 00:15:35,520 --> 00:15:39,160 Dies wird unter die Ausgabe dieses Befehls echo Rob, 202 00:15:39,160 --> 00:15:43,610 und es als Eingabe für. / hallo. 203 00:15:44,790 --> 00:15:49,560 Sie können denken, es als erster umzuleiten echo Rob in einer Datei 204 00:15:49,560 --> 00:15:54,160 und dann Eingang in. / hallo, dass die Datei, die gerade ausgegeben. 205 00:15:54,160 --> 00:15:57,850 Aber es braucht die temporäre Datei aus dem Bild. 206 00:16:01,890 --> 00:16:04,460 >> Fragen dazu? 207 00:16:04,460 --> 00:16:07,150 >> Die nächste Frage wird diese einzubeziehen. 208 00:16:07,150 --> 00:16:15,310 Welche Pipeline könnte man verwenden, um die Anzahl der eindeutigen Namen in einer Datei namens names.txt finden? 209 00:16:15,310 --> 00:16:24,160 Die Befehle, die wir gehen zu wollen, hier verwenden wollen sind einzigartig, so uniq, und dann WC. 210 00:16:24,160 --> 00:16:28,840 Sie können Menschen uniq eigentlich, was das bedeutet schauen, 211 00:16:28,840 --> 00:16:34,840 und es ist gerade dabei, neben passenden Zeilen aus der Eingabe zu filtern. 212 00:16:34,840 --> 00:16:40,690 Und der Mensch WC wird den Zeilenumbruch, Wort und Byteanzahl für jede Datei zu drucken. 213 00:16:40,690 --> 00:16:43,760 Und das letzte, was wir gehen zu wollen, verwenden wollen ist eine Art, 214 00:16:43,760 --> 00:16:47,410 das geht nur sortieren Zeilen txt-Datei. 215 00:16:47,410 --> 00:16:58,080 Wenn ich etwas txt-Datei, names.txt, und es ist Rob, Tommy, Joseph, Tommy, Joseph, RJ, Rob, 216 00:16:58,080 --> 00:17:03,910 was ich will hier tun ist, finden die Anzahl der eindeutigen Namen in dieser Datei. 217 00:17:03,910 --> 00:17:08,750 Also, was soll die Antwort sein? >> [Schüler] 4. >> Ja. 218 00:17:08,750 --> 00:17:13,780 Es sollte 4 sein, da Rob, Tommy, Joseph, sind RJ nur eindeutige Namen in dieser Datei. 219 00:17:13,780 --> 00:17:20,180 Der erste Schritt, wenn ich nur tun Wortanzahl auf names.txt, 220 00:17:20,180 --> 00:17:24,290 dies tatsächlich erzählte mir alles. 221 00:17:24,290 --> 00:17:32,560 Dies ist eigentlich Druck - mal sehen, man wc - Zeilenumbrüche, Worten und Bytezahl. 222 00:17:32,560 --> 00:17:38,270 Wenn ich über Linien nur kümmern, dann kann ich nur tun wc-l names.txt. 223 00:17:41,730 --> 00:17:44,300 Damit ist Schritt 1. 224 00:17:44,300 --> 00:17:50,510 Aber ich weiß nicht, wc-l names.txt wollen, weil names.txt enthält nur die Namen, 225 00:17:50,510 --> 00:17:54,170 und ich herausfiltern möchten alle nicht Einzigen. 226 00:17:54,170 --> 00:18:01,200 Also, wenn ich uniq names.txt tun, bedeutet das nicht ganz mir, was ich will 227 00:18:01,200 --> 00:18:03,760 weil die duplizierten Namen sind noch da. 228 00:18:03,760 --> 00:18:07,690 Warum ist, dass? Warum ist uniq nicht tun, was ich will? 229 00:18:07,690 --> 00:18:10,500 [Schüler] Die Duplikate sind nicht [unverständlich] >> Ja. 230 00:18:10,500 --> 00:18:16,370 Denken Sie an die Manpage für uniq sagt Filter angrenzenden übereinstimmenden Zeilen. 231 00:18:16,370 --> 00:18:19,680 Sie sind nicht benachbart sind, so wird es nicht filtern sie. 232 00:18:19,680 --> 00:18:31,100 Wenn ich sie zuerst zu sortieren, ist eine Art names.txt gehen, um alle doppelten Zeilen zusammen. 233 00:18:31,100 --> 00:18:34,450 So, jetzt sort names.txt ist, dass. 234 00:18:34,450 --> 00:18:40,550 Ich werde zu wollen, dass als Eingang für uniq, welches verwenden | uniq. 235 00:18:40,550 --> 00:18:43,390 Das gibt mir Joseph, RJ, Rob, Tommy, 236 00:18:43,390 --> 00:18:49,260 und ich möchte, dass als Eingang für wc-l verwenden, 237 00:18:49,260 --> 00:18:52,740 das wird mir 4. 238 00:18:52,740 --> 00:18:56,930 Wie es hier sagt, was könnte Pipeline verwenden Sie? 239 00:18:56,930 --> 00:19:01,390 Sie können eine Menge von Dingen wie mit einer Reihe von Befehlen zu tun 240 00:19:01,390 --> 00:19:05,130 , wo Sie die Ausgabe eines Befehls als Eingabe für den nächsten Befehl. 241 00:19:05,130 --> 00:19:08,780 Sie können eine Menge Dinge, viel kluge Dinge. 242 00:19:08,780 --> 00:19:11,440 >> Haben Sie Fragen? 243 00:19:12,910 --> 00:19:14,600 Okay. 244 00:19:14,600 --> 00:19:17,880 Das war es für Pipes und Umleitungen. 245 00:19:18,370 --> 00:19:24,090 >> Jetzt gehen wir zum eigentlichen Sachen, die Codierung Zeug. 246 00:19:24,090 --> 00:19:29,100 Innerhalb dieses PDF, sehen Sie diesen Befehl, 247 00:19:29,100 --> 00:19:32,950 und Sie wollen diesen Befehl in Ihrem Gerät laufen. 248 00:19:36,240 --> 00:19:42,250 wget ist der Befehl für nur immer etwas aus dem Internet, im Grunde, 249 00:19:42,250 --> 00:19:45,180 so wget und diese URL. 250 00:19:45,180 --> 00:19:49,110 Wenn Sie zu dieser URL ging in Ihrem Browser, wäre es downloaden Sie diese Datei. 251 00:19:49,110 --> 00:19:52,510 Ich klickte auf sie, so dass es die Datei heruntergeladen haben für mich. 252 00:19:52,510 --> 00:19:55,650 Aber schriftlich wget dieses Ding in der Klemme 253 00:19:55,650 --> 00:19:58,620 wird nur gehen, um es in Ihrem Endgerät herunterladen. 254 00:19:58,620 --> 00:20:02,750 Ich habe section5.zip und Sie wollen section5.zip entpacken, 255 00:20:02,750 --> 00:20:06,520 das wird Ihnen ein Ordner namens Abschnitt5, 256 00:20:06,520 --> 00:20:11,550 was wird alle Dateien wir verwenden heute innerhalb der IT sind zu haben. 257 00:20:33,380 --> 00:20:37,710 Da diese Programme 'file Namen vermuten lassen, sind sie ein bisschen buggy, 258 00:20:37,710 --> 00:20:40,990 so dass Ihre Mission ist es, herauszufinden, warum mit gdb. 259 00:20:40,990 --> 00:20:44,560 Hat jeder haben sie heruntergeladen / wissen, wie man sie heruntergeladen 260 00:20:44,560 --> 00:20:47,480 in ihre Appliance? Okay. 261 00:20:47,480 --> 00:20:56,400 >> Laufen ./buggy1, wird sie sagen Segmentation fault (core dumped), 262 00:20:56,400 --> 00:21:00,500 denen zu jeder Zeit erhalten Sie einen segfault, es ist eine schlechte Sache. 263 00:21:00,500 --> 00:21:03,810 Unter welchen Umständen bekommt man einen segfault? 264 00:21:03,810 --> 00:21:08,210 [Schüler] Dereferenzierung eines NULL-Zeiger. >> Ja. Also das ist ein Beispiel. 265 00:21:08,210 --> 00:21:11,580 Dereferenzierung eines Null-Zeiger Sie vorhaben, ein segfault zu bekommen sind. 266 00:21:11,580 --> 00:21:16,720 Was für ein segfault Mittel Sie berühren Speicher sollten Sie sich nicht berühren. 267 00:21:16,720 --> 00:21:21,350 So Dereferenzierung eines Null-Zeiger berührt Adresse 0, 268 00:21:21,350 --> 00:21:28,060 und im Grunde alle Computer heute sagen, dass die Adresse 0 Speicher, den Sie nicht zu berühren ist. 269 00:21:28,060 --> 00:21:31,920 Also das ist, warum Dereferenzierung eines Null-Zeiger führt zu einem segfault. 270 00:21:31,920 --> 00:21:37,210 Wenn Sie nicht einen Zeiger zu initialisieren passieren, dann hat es eine Garbage-Wert, 271 00:21:37,210 --> 00:21:41,520 und so, wenn Sie zu dereferenzieren es versuchen, in aller Wahrscheinlichkeit Sie berühren Speicher 272 00:21:41,520 --> 00:21:43,540 das ist in der Mitte von Nirgendwo. 273 00:21:43,540 --> 00:21:45,650 Wenn Sie geschehen, mit etwas Glück und der Müll-Wert 274 00:21:45,650 --> 00:21:48,440 passiert, um irgend etwas zu zeigen auf dem Stack oder so etwas, 275 00:21:48,440 --> 00:21:50,820 dann, wenn Sie Dereferenzierung des Zeigers, die Sie noch nicht initialisiert ist, 276 00:21:50,820 --> 00:21:52,730 nichts schief gehen. 277 00:21:52,730 --> 00:21:55,480 Wenn es aber darauf ist, sagen wir, irgendwo zwischen dem Stapel und dem Haufen, 278 00:21:55,480 --> 00:21:59,850 oder es ist darauf nur irgendwo, dass ist nicht von Ihrem Programm noch verwendet werden, 279 00:21:59,850 --> 00:22:02,240 dann sind Sie berühren Speicher sollte man nicht berühren und Sie segfault. 280 00:22:02,240 --> 00:22:06,370 Wenn Sie schreiben eine rekursive Funktion und es rekursiv zu oft 281 00:22:06,370 --> 00:22:08,720 und Ihr Stack wächst zu groß und die Stapel kollidiert in Dinge 282 00:22:08,720 --> 00:22:12,270 dass es nicht mit zu kollidieren, Sie berühren Speicher sollte man nicht berühren, 283 00:22:12,270 --> 00:22:14,810 so dass Sie segfault. 284 00:22:14,810 --> 00:22:17,010 Das ist, was ein segfault ist. 285 00:22:17,010 --> 00:22:21,810 >> Es ist auch aus dem gleichen Grund, dass wenn Sie eine Zeichenfolge wie - 286 00:22:21,810 --> 00:22:23,930 gehen wir zurück zum vorherigen Programm. 287 00:22:23,930 --> 00:22:28,530 In hello.c--ich bin gerade dabei, etwas anderes zu machen. 288 00:22:28,530 --> 00:22:33,770 char * s = "Hallo Welt!"; 289 00:22:33,770 --> 00:22:42,310 Wenn ich * s = etwas oder s [0] = 'X'; 290 00:22:42,310 --> 00:22:47,290 so stellen hallo,. / hallo, warum, dass segfault? 291 00:22:48,410 --> 00:22:51,250 Warum ist das segfault? 292 00:22:55,660 --> 00:22:57,890 Was würden Sie erwarten passieren? 293 00:22:57,890 --> 00:23:06,640 Wenn ich printf tat ("% s \ n", s), was würden Sie erwarten, gedruckt werden? 294 00:23:06,640 --> 00:23:09,930 [Schüler] X hallo. >> Ja. 295 00:23:09,930 --> 00:23:15,140 Das Problem ist, dass, wenn Sie eine Zeichenfolge wie diese zu erklären, 296 00:23:15,140 --> 00:23:18,190 s ist ein Zeiger, gehen auf den Stapel geht, 297 00:23:18,190 --> 00:23:25,880 und was s wird zeigen, ist diese Zeichenfolge, die in Nur-Lese-Speicher enthalten ist. 298 00:23:25,880 --> 00:23:30,560 Also nur durch den Namen, Nur-Lese-Speicher, sollten Sie auf die Idee 299 00:23:30,560 --> 00:23:33,010 dass, wenn Sie versuchen zu ändern, was in Nur-Lese-Speicher, 300 00:23:33,010 --> 00:23:36,670 Sie tun etwas, das Sie nicht mit dem Gedächtnis tun sollte und Sie segfault. 301 00:23:36,670 --> 00:23:45,360 Dies ist tatsächlich ein großer Unterschied zwischen char * s und char s []. 302 00:23:45,360 --> 00:23:48,790 So char s [], jetzt diese Saite wird auf den Stapel gelegt werden, 303 00:23:48,790 --> 00:23:53,960 und der Stapel nicht nur gelesen werden, was bedeutet, dass dies funktionieren sollte völlig in Ordnung. 304 00:23:55,500 --> 00:23:57,370 Und das tut sie. 305 00:23:57,370 --> 00:24:06,250 Beachten Sie, dass, wenn ich char * s = "Hallo Welt!", Ist s selbst auf dem Stack 306 00:24:06,250 --> 00:24:10,390 aber s Punkte woanders, und dass irgendwo zufällig nur gelesen werden. 307 00:24:10,390 --> 00:24:15,640 Aber char s [] ist nur etwas auf den Stapel. 308 00:24:17,560 --> 00:24:21,760 Damit ist ein weiteres Beispiel für ein segfault geschieht. 309 00:24:21,760 --> 00:24:27,820 >> Wir sahen, dass ./buggy1 in einem segfault geführt. 310 00:24:27,820 --> 00:24:31,810 In der Theorie sollten Sie nicht zu buggy1.c sofort suchen. 311 00:24:31,810 --> 00:24:35,170 Stattdessen werden wir es durch gdb aussehen. 312 00:24:35,170 --> 00:24:37,750 Beachten Sie, dass, wenn Sie Segmentation fault (core dumped) zu erhalten, 313 00:24:37,750 --> 00:24:40,850 erhalten Sie diese Datei über hier als Kern. 314 00:24:40,850 --> 00:24:45,200 Wenn wir ls-l, werden wir sehen, dass der Kern ist in der Regel eine ziemlich große Datei. 315 00:24:45,200 --> 00:24:51,580 Dies ist die Anzahl der Bytes der Datei, so dass es aussieht wie es 250-etwas Kilobyte ist. 316 00:24:51,580 --> 00:24:56,120 Der Grund dafür ist, dass, was die Kernspeicherauszug tatsächlich 317 00:24:56,120 --> 00:25:01,410 ist, wenn Ihr Programm abstürzt, der Zustand des Speichers Ihres Programms 318 00:25:01,410 --> 00:25:05,230 bekommt nur kopiert und in dieser Datei. 319 00:25:05,230 --> 00:25:07,270 Es wird in dieser Datei geworfen. 320 00:25:07,270 --> 00:25:13,060 Dieses Programm, während es läuft, passiert eine Speicherauslastung von rund 250 Kilobyte haben, 321 00:25:13,060 --> 00:25:17,040 und so, dass ist es, was wurde in diese Datei geworfen. 322 00:25:17,040 --> 00:25:23,630 Jetzt können Sie diese Datei aussehen, wenn wir gdb buggy1 Kern zu tun. 323 00:25:23,630 --> 00:25:30,130 Wir können nur tun gdb buggy1, und das wird einfach starten Sie gdb regelmäßig, 324 00:25:30,130 --> 00:25:33,800 Verwendung buggy1 als Eingabedatei. 325 00:25:33,800 --> 00:25:38,260 Aber wenn Sie gdb buggy1 Kern zu tun, dann ist es speziell gehen zu starten gdb 326 00:25:38,260 --> 00:25:40,330 Dazu suchen Sie in diesem System Datei. 327 00:25:40,330 --> 00:25:45,560 Und Sie sagen buggy1 mittels gdb kennt, dass Core-Datei von der buggy1 Programm kommt. 328 00:25:45,560 --> 00:25:49,580 So gdb buggy1 Kern wird sofort bringen uns 329 00:25:49,580 --> 00:25:52,060 , wo das Programm passiert zu beenden. 330 00:25:57,720 --> 00:26:02,340 Wir sehen hier Programm mit Signal 11, Segmentation fault beendet. 331 00:26:02,340 --> 00:26:10,110 Wir passieren eine Reihe von Montage, das ist wahrscheinlich nicht sehr hilfreich zu sehen. 332 00:26:10,110 --> 00:26:15,360 Aber wenn Sie bt oder backtrace geben, das geht auf die Funktion sein 333 00:26:15,360 --> 00:26:19,430 das gibt uns die Liste unserer aktuellen Stack-Frames. 334 00:26:19,430 --> 00:26:23,150 So backtrace. Es sieht aus wie wir haben nur zwei Stack-Frames. 335 00:26:23,150 --> 00:26:26,310 Die erste ist unsere Stack-Frame, 336 00:26:26,310 --> 00:26:29,810 und der zweite ist der Stapelrahmen für diese Funktion, die wir in sein passieren, 337 00:26:29,810 --> 00:26:34,440 das sieht aus wie wir haben nur die Assembler-Code für. 338 00:26:34,440 --> 00:26:38,050 So gehen wir zurück in unsere Hauptfunktion 339 00:26:38,050 --> 00:26:42,300 und zu tun, dass wir Rahmen 1 zu tun, und ich denke, wir können auch nach unten, 340 00:26:42,300 --> 00:26:45,160 aber ich fast nie nach unten - oder nach oben. Yeah. 341 00:26:45,160 --> 00:26:50,710 Rauf und runter. Up bringt Sie ein Stack-Frame, unten bringt Sie unten einen Stack-Frame. 342 00:26:50,710 --> 00:26:53,240 Ich neige dazu, niemals, dass. 343 00:26:53,240 --> 00:26:59,120 Ich habe gerade ausdrücklich sagen Rahmen 1, die dem Bild mit der Bezeichnung 1 gehen wird. 344 00:26:59,120 --> 00:27:01,750 Frame 1 wird uns bringen in Haupt-Stack-Frame, 345 00:27:01,750 --> 00:27:05,570 und er sagt, hier die Linie der Code, den wir passieren, um zu sein. 346 00:27:05,570 --> 00:27:07,950 Wenn wir noch ein paar Zeilen Code wollte, können wir sagen, Liste, 347 00:27:07,950 --> 00:27:11,280 und dass geht um uns alle Zeilen Code um ihn herum. 348 00:27:11,280 --> 00:27:13,360 Die Linie, die wir am segfaulted betrug 6: 349 00:27:13,360 --> 00:27:17,360 if (strcmp ("CS50 rocks", argv [1]) == 0). 350 00:27:17,360 --> 00:27:24,130 Wenn es nicht offensichtlich ist, haben, können Sie es gerade bekommen von hier nur durch das Denken, warum es segfaulted. 351 00:27:24,130 --> 00:27:28,800 Aber wir können noch einen Schritt weiter gehen und sagen: "Warum sollte argv [1] segfault?" 352 00:27:28,800 --> 00:27:38,830 Lassen Sie drucken argv [1], und es sieht aus wie die 0x0, die NULL-Zeiger ist. 353 00:27:38,830 --> 00:27:44,750 Wir strcmping CS50 Felsen und null, und so, das wird segfault. 354 00:27:44,750 --> 00:27:48,280 Und warum ist argv [1] null? 355 00:27:48,640 --> 00:27:51,280 [Schüler] Weil wir nicht geben keine Kommandozeilen-Argumente. 356 00:27:51,280 --> 00:27:53,390 Yeah. Wir haben es nicht geben keine Kommandozeilen-Argumente. 357 00:27:53,390 --> 00:27:58,460 So ./buggy1 wird nur gehen zu müssen argv [0] ./buggy1 sein. 358 00:27:58,460 --> 00:28:02,100 Es ist nicht zu haben eine argv [1], so, das wird segfault. 359 00:28:02,100 --> 00:28:07,450 Aber wenn, anstatt, ich CS50 zu tun, es geht zu sagen, Sie erhalten eine D 360 00:28:07,450 --> 00:28:09,950 weil das ist, was es tun soll. 361 00:28:09,950 --> 00:28:15,240 Mit Blick auf buggy1.c, es soll print "Sie erhalten eine D" - 362 00:28:15,240 --> 00:28:20,820 Wenn argv [1] ist nicht "CS50 rocks", "Du bist ein D bekommen" else "Sie erhalten eine A!" 363 00:28:20,820 --> 00:28:25,660 Also, wenn wir eine A wollen, müssen wir dies als wahr zu vergleichen, 364 00:28:25,660 --> 00:28:28,710 was bedeutet, dass es auf 0 vergleicht. 365 00:28:28,710 --> 00:28:31,100 So argv [1] muss "CS50 rocks" sein. 366 00:28:31,100 --> 00:28:35,660 Wenn Sie, dass auf der Kommandozeile tun wollen, müssen Sie \ verwenden, um den Raum zu entkommen. 367 00:28:35,660 --> 00:28:41,690 So CS50 \ Felsen und Sie erhalten eine A! 368 00:28:41,690 --> 00:28:44,060 Wenn Sie das nicht tun den Backslash, warum das nicht funktioniert? 369 00:28:44,060 --> 00:28:47,190 [Schüler] Es gibt zwei unterschiedliche Argumente. >> Ja. 370 00:28:47,190 --> 00:28:52,540 Argv [1] wird CS50, und argv [2] wird Felsen. Okay. 371 00:28:52,540 --> 00:28:56,470 >> Jetzt ./buggy2 wird wieder segfault. 372 00:28:56,470 --> 00:29:01,880 Statt der Eröffnung es mit seinem Core-Datei, wir öffnen Sie einfach buggy2 direkt 373 00:29:01,880 --> 00:29:05,000 so gdb buggy2. 374 00:29:05,000 --> 00:29:09,590 Nun, wenn wir laufen nur unser Programm, dann wird es zu sagen Programm empfangene Signal SIGSEGV, 375 00:29:09,590 --> 00:29:15,530 welches das segfault Signal, und hier ist es geschehen passiert. 376 00:29:15,530 --> 00:29:21,250 Mit Blick auf unsere backtrace, sehen wir, dass wir in der Funktion oh_no waren, 377 00:29:21,250 --> 00:29:23,900 die durch die Funktion dinky, die durch die Funktion binky genannt wurde genannt, 378 00:29:23,900 --> 00:29:26,460 Das war nach den wichtigsten genannt. 379 00:29:26,460 --> 00:29:31,680 Wir können auch die Argumente für diese Funktionen. 380 00:29:31,680 --> 00:29:34,680 Das Argument für dinky und binky 1 war. 381 00:29:34,680 --> 00:29:44,390 Wenn wir die Funktion oh_no Liste, sehen wir, dass oh_no ist nur tun, char ** s = NULL; 382 00:29:44,390 --> 00:29:47,410 * S = "BOOM"; 383 00:29:47,410 --> 00:29:50,330 Warum wäre das nicht? 384 00:29:54,330 --> 00:29:58,380 [Schüler] Sie können nicht Dereferenzierung den Null-Zeiger? >> Ja. 385 00:29:58,380 --> 00:30:06,090 Dies ist nur zu sagen s NULL ist, unabhängig davon, ob dies geschieht, um ein char ** sein, 386 00:30:06,090 --> 00:30:12,070 die, je nachdem, wie Sie interpretieren, könnte es ein Zeiger auf einen Zeiger auf eine Zeichenfolge 387 00:30:12,070 --> 00:30:15,550 oder ein Array von Strings. 388 00:30:15,550 --> 00:30:21,430 Es ist s ist NULL, so * s ist Dereferenzierung eines Null-Zeiger, 389 00:30:21,430 --> 00:30:24,800 und so, das wird abstürzen. 390 00:30:24,800 --> 00:30:27,540 Dies ist eine der schnellsten Möglichkeiten, wie Sie möglicherweise segfault können. 391 00:30:27,540 --> 00:30:31,300 Es ist einfach erklärt eine Null-Zeiger und sofort Speicherzugriffsfehler. 392 00:30:31,300 --> 00:30:34,570 Das ist, was oh_no tut. 393 00:30:34,570 --> 00:30:43,400 Wenn wir ein Bild gehen, dann werden wir in der Funktion, die oh_no genannt bekommen. 394 00:30:43,400 --> 00:30:44,830 Ich muss, dass sich zu tun. 395 00:30:44,830 --> 00:30:48,610 Wenn Sie keinen einen Befehl, und Sie drücken Sie einfach erneut die Eingabetaste, 396 00:30:48,610 --> 00:30:52,350 es wird nur wiederholen Sie den vorherigen Befehl, den Sie lief. 397 00:30:52,350 --> 00:30:56,610 Wir sind in Bild 1. 398 00:30:56,610 --> 00:31:04,650 Auflisten diesem Rahmen sehen wir hier unsere Funktion. 399 00:31:04,650 --> 00:31:08,520 Können Sie die Liste wieder zu schlagen, oder können Sie die Liste 20 zu tun und es wird mehr aufzulisten. 400 00:31:08,520 --> 00:31:13,640 Die Funktion dinky sagt, wenn i 1 ist, dann ist der oh_no Funktion gehen, 401 00:31:13,640 --> 00:31:15,960 sonst zum slinky Funktion zu gelangen. 402 00:31:15,960 --> 00:31:18,700 Und wir wissen, i ist 1, weil wir sehen, hier passiert 403 00:31:18,700 --> 00:31:22,560 dass dinky wurde mit dem Argument 1 aufgerufen. 404 00:31:22,560 --> 00:31:27,560 Oder Sie können einfach gedruckt i und es wird sagen i = 1 ist. 405 00:31:27,560 --> 00:31:33,770 Wir sind derzeit in dinky, und wenn wir gehen einen anderen Rahmen, wissen wir, wir landen in binky. 406 00:31:33,770 --> 00:31:36,600 Up. Jetzt sind wir in binky. 407 00:31:36,600 --> 00:31:41,340 Auflisten diese Funktion - die Liste von vor der Pause unterbrach mich - 408 00:31:41,340 --> 00:31:52,670 es begann, als ob i 0 ist, dann werden wir es nennen oh_no, sonst dinky nennen. 409 00:31:52,670 --> 00:31:57,000 Wir wissen, ich war 1, so heißt dinky. 410 00:31:57,000 --> 00:32:05,030 Und jetzt sind wir wieder in Haupt-und wichtigsten ist gerade dabei, int i = rand ()% 3; 411 00:32:05,030 --> 00:32:08,790 Das ist gerade dabei, Ihnen eine Zufallszahl, die entweder 0, 1 oder 2 ist. 412 00:32:08,790 --> 00:32:12,780 Es wird binky mit dieser Nummer anrufen, und es wird 0 zurück. 413 00:32:12,780 --> 00:32:16,700 Mit Blick auf diese, 414 00:32:16,700 --> 00:32:19,880 nur zu Fuß durch das Programm manuell ohne läuft es sofort, 415 00:32:19,880 --> 00:32:25,400 Sie würden einen Haltepunkt an Haupt gesetzt, was bedeutet, dass, wenn wir das Programm ausführen 416 00:32:25,400 --> 00:32:31,020 Ihr Programm läuft, bis es einen Haltepunkt trifft. 417 00:32:31,020 --> 00:32:35,450 So läuft das Programm, wird es laufen und dann wird es die Hauptfunktion getroffen und nicht mehr ausgeführt. 418 00:32:35,450 --> 00:32:44,700 Jetzt sind wir im Inneren von Haupt-, und Schritt oder nächste wird uns in die nächste Zeile des Codes zu bringen. 419 00:32:44,700 --> 00:32:47,050 Sie können Schritt oder nächsten. 420 00:32:47,050 --> 00:32:51,800 Schlagen nächsten, jetzt i hat rand ()% 3, so können wir den Wert von i print eingestellt wurde, 421 00:32:51,800 --> 00:32:55,280 und es wird sagen i = 1 ist. 422 00:32:55,280 --> 00:32:58,110 Nun ist es nicht egal, ob wir nächste oder Schritt. 423 00:32:58,110 --> 00:33:01,000 Ich denke, es zählte im Vorjahr ein, aber wir würden wollen nächstes nutzen. 424 00:33:01,000 --> 00:33:06,000 Wenn wir Schritt verwenden wir in die Funktion treten, was bedeutet, Blick auf die eigentliche Sache 425 00:33:06,000 --> 00:33:07,940 Das ist innerhalb binky passiert. 426 00:33:07,940 --> 00:33:10,510 Wenn wir das nächste zu verwenden, dann bedeutet es, gehen über die Funktion 427 00:33:10,510 --> 00:33:14,070 und nur in die nächste Zeile des Codes in unsere Funktion zu gelangen. 428 00:33:14,070 --> 00:33:17,900 Genau hier auf dieser Linie war ich bei, wo es heißt rand ()% 3; 429 00:33:17,900 --> 00:33:21,320 wenn ich Schritt täte, würde es in die Umsetzung der rand gehen 430 00:33:21,320 --> 00:33:25,110 und was dort vor sich geht, und ich konnte durch die rand-Funktion fort. 431 00:33:25,110 --> 00:33:26,920 Aber ich weiß nicht über die Funktion rand kümmern. 432 00:33:26,920 --> 00:33:30,190 Ich will einfach nur in die nächste Zeile des Codes im Hauptspeicher zu gehen, so dass ich weiter. 433 00:33:30,190 --> 00:33:35,800 Aber jetzt weiß ich kümmern uns um die binky Funktion, so möchte ich in diesen Schritt. 434 00:33:35,800 --> 00:33:37,730 Jetzt bin ich in binky. 435 00:33:37,730 --> 00:33:42,040 Die erste Zeile des Codes wird sagen, wenn (i == 0), ich einen Schritt, 436 00:33:42,040 --> 00:33:44,930 sehen wir uns am Ende auf dinky. 437 00:33:44,930 --> 00:33:51,620 Wenn wir Liste Dinge, sehen wir, dass geprüft wird, i = 0. 438 00:33:51,620 --> 00:33:55,470 i ist nicht gleich 0, so ging es in die else-Bedingung, 439 00:33:55,470 --> 00:33:59,540 was wird dinky (i) nennen. 440 00:33:59,540 --> 00:34:04,030 Sie könnten verwirrt werden. 441 00:34:04,030 --> 00:34:07,380 Wenn Sie diese Zeilen direkt zu sehen, könnte man denken, wenn (i == 0), 442 00:34:07,380 --> 00:34:10,800 okay, dann nahm ich einen Schritt zurück und jetzt bin ich an dinky (i), 443 00:34:10,800 --> 00:34:14,120 Man könnte meinen, muss bedeuten, i = 0 oder so etwas. 444 00:34:14,120 --> 00:34:18,980 Nein, es bedeutet nur, dass sie weiß, es kann direkt kleben an der Linie dinky (i). 445 00:34:18,980 --> 00:34:23,300 Weil ich nicht 0 ist, ist der nächste Schritt nicht auf der anderen enden. 446 00:34:23,300 --> 00:34:26,239 Else ist nicht eine Zeile es geht um zu stoppen ist. 447 00:34:26,239 --> 00:34:31,570 Ist es nur geht, um in die nächste Zeile tatsächlich ausführen können, was dinky (i) gehen. 448 00:34:31,570 --> 00:34:36,090 Der Schritt in dinky (i), sehen wir, wenn (i == 1). 449 00:34:36,090 --> 00:34:42,670 Wir wissen, i = 1, so dass, wenn wir Schritt, wir wissen, wir werden bis zum Ende in oh_no 450 00:34:42,670 --> 00:34:46,489 weil i = 1 ruft die Funktion oh_no, die Sie in Schritt kann 451 00:34:46,489 --> 00:34:52,969 was wird eingestellt char ** s = NULL und sofort "BOOM". 452 00:34:54,270 --> 00:34:59,690 Und dann tatsächlich Blick auf die Umsetzung der buggy2, 453 00:34:59,690 --> 00:35:04,590 Dabei wird i gerade erst eine Zufallszahl - 0, 1 oder 2 - Berufung binky, 454 00:35:04,590 --> 00:35:10,610 die, wenn i 0 ist es oh_no nennt, sonst dinky nennt, kommt die hier oben. 455 00:35:10,610 --> 00:35:18,100 Wenn i 1 ist, rufen oh_no, sonst rufen slinky, die kommen hier 456 00:35:18,100 --> 00:35:20,460 wenn i 2 ist, rufen oh_no. 457 00:35:20,460 --> 00:35:24,720 Ich glaube nicht einmal, es ist ein Weg - 458 00:35:24,720 --> 00:35:30,030 Hat jemand finden einen Weg, dies ein Programm, das nicht segfault wird? 459 00:35:30,030 --> 00:35:37,530 Denn wenn ich etwas fehlt bin, wenn i 0 ist, werden Sie sofort segfault, 460 00:35:37,530 --> 00:35:41,250 was Sie auf eine Funktion, wenn i 1 Sie segfault gehen, 461 00:35:41,250 --> 00:35:44,540 was Sie zu einer Funktion, wenn i 2 segfault Sie gehen. 462 00:35:44,540 --> 00:35:46,810 Also egal, was du tust, segfault Sie. 463 00:35:46,810 --> 00:35:52,380 >> Ich denke, ein Weg zur Festsetzung wäre es anstatt das zu tun char ** s = NULL sein, 464 00:35:52,380 --> 00:35:55,610 Sie könnten Platz für diesen String malloc. 465 00:35:55,610 --> 00:36:04,230 Wir könnten malloc (sizeof) - sizeof was? 466 00:36:09,910 --> 00:36:15,190 [Schüler] (char) * 5? >> Scheint dies richtig? 467 00:36:15,190 --> 00:36:21,060 Ich nehme an, das wird funktionieren, wenn ich lief es tatsächlich, aber es ist nicht das, was ich suche. 468 00:36:24,400 --> 00:36:32,940 Schauen Sie sich die Art der s. Wir fügen int *, so int * x. 469 00:36:32,940 --> 00:36:35,600 Ich tun würde, malloc (sizeof (int)). 470 00:36:35,600 --> 00:36:40,490 Oder wenn ich ein Array von 5 wollte, würde ich es tun (sizeof (int) * 5); 471 00:36:40,490 --> 00:36:44,210 Was passiert, wenn ich ein int ** haben? 472 00:36:46,260 --> 00:36:49,140 Was würde ich malloc? 473 00:36:49,140 --> 00:36:53,510 [Schüler] Größe des Zeigers. >> Ja. (Sizeof (int *)); 474 00:36:53,510 --> 00:36:56,960 Das Gleiche gilt hier unten. 475 00:36:56,960 --> 00:37:01,280 Ich möchte (sizeof (char *)); 476 00:37:06,170 --> 00:37:12,840 Dies wird Platz für die Zeiger, die auf "BOOM", betont zuzuweisen. 477 00:37:12,840 --> 00:37:15,330 Ich brauche nicht, um Platz für "BOOM" selbst zuweisen 478 00:37:15,330 --> 00:37:17,210 denn dies ist im Grunde gleichwertig zu dem, was ich vorhin gesagt habe 479 00:37:17,210 --> 00:37:20,870 der char * x = "BOOM". 480 00:37:20,870 --> 00:37:27,950 "BOOM" existiert bereits. Es passiert existieren in der Nur-Lese-Bereich des Speichers. 481 00:37:27,950 --> 00:37:35,200 Aber es existiert bereits, was bedeutet diese Codezeile, wenn s ein char ** ist, 482 00:37:35,200 --> 00:37:43,900 dann * s ist ein char * und du bist Einstellung dieses char * auf "BOOM" zeigen. 483 00:37:43,900 --> 00:37:50,040 Wenn ich auf "BOOM" in s kopieren wollte, dann würde ich brauchen, um Platz für s zuzuweisen. 484 00:37:55,170 --> 00:38:03,900 Ich werde tun, * s = malloc (sizeof (char) * 5); 485 00:38:03,900 --> 00:38:06,210 Warum 5? 486 00:38:06,210 --> 00:38:10,860 Warum nicht 4? Es sieht aus wie "BOOM" ist 4 Zeichen. >> [Schüler] Die Null-Zeichen. 487 00:38:10,860 --> 00:38:14,580 Yeah. Alle Ihre Saiten werden das Null-Zeichen benötigen. 488 00:38:14,580 --> 00:38:23,590 Jetzt kann ich so etwas wie strcat tun - Was ist die Funktion zum Kopieren eines Strings? 489 00:38:23,590 --> 00:38:28,520 [Schüler] cpy? >> Strcpy. 490 00:38:28,520 --> 00:38:32,700 Mann strcpy. 491 00:38:36,120 --> 00:38:39,590 So strcpy oder strncpy. 492 00:38:39,590 --> 00:38:43,410 strncpy ist ein bisschen sicherer, da Sie angeben können, wie viele Zeichen, 493 00:38:43,410 --> 00:38:46,190 aber hier ist es egal, weil wir wissen. 494 00:38:46,190 --> 00:38:50,340 So strcpy und schauen Sie in den Argumenten. 495 00:38:50,340 --> 00:38:53,100 Das erste Argument ist unser Ziel. 496 00:38:53,100 --> 00:38:56,770 Das zweite Argument ist unsere Quelle. 497 00:38:56,770 --> 00:39:10,310 Wir gehen in unserem Ziel * Kopie S der Zeiger "BOOM". 498 00:39:10,310 --> 00:39:19,820 Warum sollten Sie dies mit einem strcpy statt nur, was wir hatten, bevor 499 00:39:19,820 --> 00:39:22,800 von * s = "BOOM"? 500 00:39:22,800 --> 00:39:28,630 Es ist ein Grund, warum Sie dies tun wollen könnte, aber was ist das Grund? 501 00:39:28,630 --> 00:39:31,940 [Schüler] Wenn Sie etwas in "BOOM" ändern möchten. >> Ja. 502 00:39:31,940 --> 00:39:37,950 Jetzt kann ich etwas tun, s [0] = 'X'; 503 00:39:37,950 --> 00:39:48,190 weil s verweist auf dem Heap und diesem Raum auf dem Heap, dass s wird darauf 504 00:39:48,190 --> 00:39:52,320 ist ein Zeiger, um mehr Platz auf dem Heap, die Speicherung von "BOOM" genannt wird. 505 00:39:52,320 --> 00:39:55,150 So diese Kopie von "BOOM" wird in dem Heap gespeichert. 506 00:39:55,150 --> 00:39:58,780 Es sind technisch zwei Exemplare von "BOOM" in unserem Programm. 507 00:39:58,780 --> 00:40:03,500 Es ist das erste, das gerade durch diese "BOOM" string constant ist gegeben, 508 00:40:03,500 --> 00:40:09,250 und die zweite Kopie von "BOOM", erstellt strcpy die Kopie von "BOOM". 509 00:40:09,250 --> 00:40:13,100 Aber die Kopie von "BOOM" wird auf dem Heap gespeichert, und der Haufen, du bist frei zu ändern. 510 00:40:13,100 --> 00:40:17,250 Der Haufen ist nicht nur gelesen, bedeutet so, dass s [0] 511 00:40:17,250 --> 00:40:20,500 wird gehen zu lassen, ändern Sie den Wert von "BOOM". 512 00:40:20,500 --> 00:40:23,130 Es gehen zu lassen, ändern Sie diese Zeichen. 513 00:40:23,130 --> 00:40:26,640 >> Haben Sie Fragen? 514 00:40:27,740 --> 00:40:29,290 Okay. 515 00:40:29,290 --> 00:40:35,500 >> Bewegen Sie sich auf buggy3, lasst gdb buggy3. 516 00:40:35,500 --> 00:40:39,840 Wir führen Sie es einfach und wir sehen bekommen wir einen segfault. 517 00:40:39,840 --> 00:40:46,550 Wenn wir backtrace, gibt es nur zwei Funktionen. 518 00:40:46,550 --> 00:40:52,970 Wenn wir gehen in unsere Funktion, sehen wir, dass wir auf dieser Linie segfaulted. 519 00:40:52,970 --> 00:41:00,180 So gerade auf der Suche in dieser Zeile, int line = 0 for (; fgets dieses Zeug nicht gleich NULL; 520 00:41:00,180 --> 00:41:03,770 Linie + +). 521 00:41:03,770 --> 00:41:08,010 Unsere vorherigen Frame genannt wurde _IO_fgets. 522 00:41:08,010 --> 00:41:10,720 Du wirst sehen, dass eine Menge mit integriertem C-Funktionen, 523 00:41:10,720 --> 00:41:15,350 , dass, wenn Sie die segfault bekommen, wird es wirklich kryptisch Funktionsnamen werden 524 00:41:15,350 --> 00:41:18,090 RS _IO_fgets. 525 00:41:18,090 --> 00:41:21,770 Aber das geht auf diese fgets Anruf beziehen. 526 00:41:21,770 --> 00:41:25,850 Irgendwo hier drinnen sind wir Speicherzugriffsfehler. 527 00:41:25,850 --> 00:41:30,340 Wenn wir uns die Argumente an fgets betrachten, können wir drucken Puffer. 528 00:41:30,340 --> 00:41:41,180 Lassen Sie drucken, wie a - Oh, nein. 529 00:41:48,980 --> 00:41:51,900 Print wird nicht genau so, wie ich es will arbeiten. 530 00:41:55,460 --> 00:41:58,000 Lassen Sie uns das eigentliche Programm zu suchen. 531 00:42:02,200 --> 00:42:09,640 Buffer ist ein Zeichen-Array. Es ist ein Zeichen-Array von 128 Zeichen. 532 00:42:09,640 --> 00:42:14,980 Wenn ich also sage Druckpuffer, es geht um jene 128 Zeichen zu drucken, 533 00:42:14,980 --> 00:42:18,300 die ich schätze, ist, was erwartet wird. 534 00:42:18,300 --> 00:42:21,390 Was ich suche, ist Drucken Sie die Adresse des Puffers, 535 00:42:21,390 --> 00:42:23,680 aber das bedeutet nicht wirklich sagen mir viel. 536 00:42:23,680 --> 00:42:30,770 Also, wenn ich sagen hier x-Puffer geschieht, zeigt er mir 0xbffff090, 537 00:42:30,770 --> 00:42:38,690 die, wenn man aus früheren oder irgendwann erinnern, Oxbffff ein Stapel-ish Region neigt. 538 00:42:38,690 --> 00:42:46,020 Der Stapel neigt dazu, irgendwo anfangen knapp 0xc000. 539 00:42:46,020 --> 00:42:51,890 Nur indem wir diese Adresse, ich weiß, dass Puffer auf dem Stack passiert. 540 00:42:51,890 --> 00:43:04,500 Neustart mein Programm, laufen, bis, puffern wir sahen, war diese Folge von Zeichen 541 00:43:04,500 --> 00:43:06,530 das sind so ziemlich bedeutungslos. 542 00:43:06,530 --> 00:43:12,270 Dann Druckdatei, was bedeutet Datei aussehen? 543 00:43:15,120 --> 00:43:17,310 [Schüler] Null. >> Ja. 544 00:43:17,310 --> 00:43:22,610 Datei ist eine vom Typ FILE *, so ist es ein Zeiger, 545 00:43:22,610 --> 00:43:26,610 und der Wert von diesem Zeiger ist null. 546 00:43:26,610 --> 00:43:33,240 So fgets wird versuchen, aus diesem Zeiger auf indirekte Weise zu lesen, 547 00:43:33,240 --> 00:43:37,320 aber um diesen Zeiger zuzugreifen, muss es dereferenzieren. 548 00:43:37,320 --> 00:43:40,550 Oder, um zu übersetzen, was es sollte, es dereferences es zeigen. 549 00:43:40,550 --> 00:43:43,810 Also ist es Dereferenzierung eines Null-Zeiger und es segfaults. 550 00:43:46,600 --> 00:43:48,730 Ich konnte es gestartet hat es. 551 00:43:48,730 --> 00:43:52,170 Wenn wir unsere wichtigste Punkt zu brechen und zu laufen, 552 00:43:52,170 --> 00:43:57,320 die erste Zeile Code ist char * filename = "NonExistent.txt"; 553 00:43:57,320 --> 00:44:00,870 Das sollte ein ziemlich großes Hinweis darauf, warum dieses Programm nicht. 554 00:44:00,870 --> 00:44:06,080 Typing nächsten bringt mich in die nächste Zeile, wo ich diese Datei öffnen, 555 00:44:06,080 --> 00:44:11,140 und dann habe ich sofort in unserer Linie, wo ich einst getroffen nächsten zu kommen, es geht um segfault. 556 00:44:11,140 --> 00:44:16,880 Möchte jemand zu werfen, ein Grund, warum wir werden Speicherzugriffsfehler könnte? 557 00:44:16,880 --> 00:44:19,130 [Schüler] Die Datei existiert nicht. >> Ja. 558 00:44:19,130 --> 00:44:22,250 Dies soll ein Hinweis sein 559 00:44:22,250 --> 00:44:29,570 , dass, wenn Sie eine Datei öffnen, müssen Sie überprüfen, ob die Datei tatsächlich existiert. 560 00:44:29,570 --> 00:44:31,510 Also hier, "NonExistent.txt"; 561 00:44:31,510 --> 00:44:34,700 Wenn wir fopen Dateiname zum Lesen, müssen wir dann sagen, 562 00:44:34,700 --> 00:44:45,870 if (file == NULL) und sagen printf ("Die Datei existiert nicht!" 563 00:44:45,870 --> 00:44:56,340 oder - noch besser - filename); return 1; 564 00:44:56,340 --> 00:45:00,300 So, jetzt überprüfen wir, wenn es NULL ist 565 00:45:00,300 --> 00:45:03,930 bevor sie tatsächlich weiter und versuchen, aus dieser Datei gelesen. 566 00:45:03,930 --> 00:45:08,800 Wir können Remake es nur zu, dass diese Arbeiten zu sehen. 567 00:45:11,020 --> 00:45:14,970 Ich wollte eine neue Zeile einzufügen. 568 00:45:21,090 --> 00:45:25,290 So, jetzt NonExistent.txt existiert nicht. 569 00:45:26,890 --> 00:45:30,040 Sie sollten immer für diese Art der Sache zu prüfen. 570 00:45:30,040 --> 00:45:33,870 Sie sollten immer prüfen, ob fopen NULL zurück. 571 00:45:33,870 --> 00:45:38,170 Sie sollten immer überprüfen, um sicherzustellen, dass malloc nicht NULL zurückgeben, 572 00:45:38,170 --> 00:45:41,410 oder du segfault. 573 00:45:42,200 --> 00:45:45,930 >> Jetzt buggy4.c. 574 00:45:49,190 --> 00:45:58,440 Running. Ich vermute, dies ist für die Eingabe oder möglicherweise Endlosschleife wartet. 575 00:45:58,440 --> 00:46:01,870 Ja, es ist Endlosschleife. 576 00:46:01,870 --> 00:46:05,560 So buggy4. Es sieht aus wie wir Endlosschleife sind. 577 00:46:05,560 --> 00:46:12,590 Wir können an Haupt zu brechen, führen unser Programm. 578 00:46:12,590 --> 00:46:20,180 In gdb, solange die Abkürzung Sie ist eindeutig 579 00:46:20,180 --> 00:46:23,420 oder spezielle Abkürzungen, die sie bieten für Sie, 580 00:46:23,420 --> 00:46:29,020 dann können Sie n zum nächsten anstatt zu tippen nächsten ganzen Weg zu verwenden. 581 00:46:29,020 --> 00:46:33,730 Und jetzt, wo ich getroffen habe n einmal, kann ich einfach Enter drücken, um weiterzumachen nächsten 582 00:46:33,730 --> 00:46:36,640 anstatt zu schlagen n Geben, n Geben, n die Eingabetaste. 583 00:46:36,640 --> 00:46:44,630 Es sieht aus wie ich in einer Art for-Schleife, die Einstellung Arrays [i] auf 0 bin. 584 00:46:44,630 --> 00:46:50,510 Es sieht aus wie ich bin nie brechen aus dieser for-Schleife. 585 00:46:50,510 --> 00:46:54,780 Wenn ich i, drucken, so i = 2 ist, dann werde ich weiter gehen. 586 00:46:54,780 --> 00:46:59,250 Ich werde print i, i = 3, dann werde ich weiter gehen. 587 00:46:59,250 --> 00:47:05,360 Ich werde print i und i 3. Weiter, drucken i, i 4. 588 00:47:05,360 --> 00:47:14,520 Eigentlich ist Druck sizeof (array), so Feldgröße von 20. 589 00:47:16,310 --> 00:47:32,870 Aber wie es aussieht, es gibt einige spezielle gdb-Befehl für den Gang, bis etwas passiert. 590 00:47:32,870 --> 00:47:37,620 Es ist wie Einstellen eines Zustands von dem Wert der Variablen. Aber ich erinnere mich nicht, was es ist. 591 00:47:37,620 --> 00:47:44,100 Also, wenn wir weitermachen - 592 00:47:44,100 --> 00:47:47,120 Was hast du gesagt? Was hast du zu bringen? 593 00:47:47,120 --> 00:47:50,500 [Schüler] Hat anzuzeigen füge ich - >> Ja. So zeigen kann ich helfen. 594 00:47:50,500 --> 00:47:54,530 Wenn wir zeigen Sie nur i, wird es hier aufgestellt, was den Wert von i ist 595 00:47:54,530 --> 00:47:56,470 so dass ich nicht haben, um es auszudrucken jeder Zeit. 596 00:47:56,470 --> 00:48:02,930 Hält man gerade dabei neben sehen wir 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5. 597 00:48:02,930 --> 00:48:08,530 Etwas wird furchtbar schief, und ich wird auf 0 zurückgesetzt. 598 00:48:13,330 --> 00:48:22,220 Mit Blick auf buggy4.c, sehen wir alles, was geschieht, ist int array [5]; 599 00:48:22,220 --> 00:48:26,200 for (i = 0, i <= sizeof (Array); i + +) 600 00:48:26,200 --> 00:48:28,550 array [i] = 0; 601 00:48:28,550 --> 00:48:31,390 Was wir sehen, dass ist hier falsch? 602 00:48:31,390 --> 00:48:39,480 Als Hinweis, wenn ich tat das gdb buggy4 - lasst break main, run - 603 00:48:39,480 --> 00:48:45,980 Ich habe Druck sizeof (array) nur um zu sehen, was der Zustand, in dem ich endlich ausbrechen sollte ist. 604 00:48:47,690 --> 00:48:51,100 Wo bin ich? Habe ich laufen? 605 00:48:51,100 --> 00:48:54,280 Ich habe noch nicht erklären. 606 00:48:54,280 --> 00:48:58,680 So drucken Sie sizeof (array) und das ist 20, 607 00:48:58,680 --> 00:49:06,690 die voraussichtlich seit meinem Array der Größe 5 und es ist von 5 Zahlen, 608 00:49:06,690 --> 00:49:12,410 so dass die ganze Sache sollte 5 * sizeof (int) Bytes, wobei sizeof (int) tendiert bis 4 betragen. 609 00:49:12,410 --> 00:49:14,780 So sizeof (array) ist 20. 610 00:49:14,780 --> 00:49:17,420 Was soll das sein? 611 00:49:17,420 --> 00:49:21,720 [Student] von sizeof (int) unterteilt. >> Ja, / sizeof (int). 612 00:49:21,720 --> 00:49:30,630 Es sieht so aus, als gäbe es noch ein Problem hier. Ich denke, dies sollte nur sein < 613 00:49:30,630 --> 00:49:36,960 da es so ziemlich immer ist 00:49:44,860 Lassen Sie uns nun darüber, warum dies tatsächlich gebrochen zu denken. 615 00:49:44,860 --> 00:49:53,370 Hat jemand errät Warum war ich wieder auf 0 zurückgesetzt durch jede Iteration der Schleife? 616 00:50:01,300 --> 00:50:09,350 Das einzige, was im Inneren von hier, die passiert ist, dass array [i] wird auf 0 gesetzt ist. 617 00:50:09,350 --> 00:50:15,350 Also irgendwie ist diese Codezeile verursacht unseren int i auf 0 gesetzt werden. 618 00:50:16,730 --> 00:50:23,130 [Schüler] Könnte es sein, weil es das Überschreiben ist die Erinnerung an diesen Teil der i 619 00:50:23,130 --> 00:50:27,970 wenn es denkt, dass es das nächste Element des Arrays? >> [Bowden] Ja. 620 00:50:27,970 --> 00:50:33,880 Wenn wir über das Ende der unser Angebot gehen, 621 00:50:33,880 --> 00:50:39,870 irgendwie, dass der Raum, dass wir das Überschreiben wird das Überschreiben der Wert von i. 622 00:50:39,870 --> 00:50:48,030 Und so, wenn wir in buggy4 schauen, break main, run, 623 00:50:48,030 --> 00:50:53,120 wir drucken die Adresse des i. 624 00:50:53,120 --> 00:50:57,280 Es sieht aus wie es bffff124 ist. 625 00:50:57,280 --> 00:51:03,930 Nun wollen wir drucken die Adresse array [0]. 110. 626 00:51:03,930 --> 00:51:06,290 Was ist [1]? 114. 627 00:51:06,290 --> 00:51:07,920 [2] 118. 628 00:51:07,920 --> 00:51:14,530 11c, 120. array [5] ist bfff124. 629 00:51:14,530 --> 00:51:26,990 So array [5] hat die gleiche Adresse wie i, was bedeutet, dass array [5] ist i bedeutet. 630 00:51:26,990 --> 00:51:30,720 Wenn sie die gleiche Adresse haben, sind sie ein und dasselbe. 631 00:51:30,720 --> 00:51:38,410 Also, wenn wir array [5] auf 0 setzen, setzen wir i auf 0 gesetzt. 632 00:51:38,410 --> 00:51:46,070 Und wenn Sie darüber nachdenken, dies im Hinblick auf den Stapel, 633 00:51:46,070 --> 00:51:55,590 int i wird zunächst erklärt, was bedeutet, ich bekomme etwas Platz auf dem Stack. 634 00:51:55,590 --> 00:52:04,730 Dann array [5] zugeordnet ist, so dass dann 20 Byte auf dem Stack zugeordnet sind. 635 00:52:04,730 --> 00:52:08,400 So i wird zuerst zugeteilt werden diese 20 Bytes bekommen zugeordnet. 636 00:52:08,400 --> 00:52:11,400 So i geschieht direkt vor dem Array 637 00:52:11,400 --> 00:52:19,230 und wegen der Art, wie ich schon sagte letzte Woche, soweit technisch der Stapel nach unten wächst, 638 00:52:19,230 --> 00:52:28,520 wenn man in einem Array-Index, sind wir sichergestellt, dass die 0. Position in der Anordnung 639 00:52:28,520 --> 00:52:31,970 geschieht immer vor dem ersten Position im Feld. 640 00:52:31,970 --> 00:52:35,900 Dies ist eine Art, wie ich zog es letzte Woche. 641 00:52:35,900 --> 00:52:42,210 Beachten Sie, dass an der Unterseite haben wir die Adresse 0 haben und an der Spitze haben wir Adresse Max. 642 00:52:42,210 --> 00:52:44,880 Der Stack wächst ständig nach unten. 643 00:52:48,100 --> 00:52:53,500 Sagen wir, wir reservieren i. 644 00:52:53,500 --> 00:52:59,680 Wir verteilen integer i, das heißt, sagen wir einfach, hier integer i zugeordnet wird. 645 00:52:59,680 --> 00:53:06,420 Dann ordnen wir unser Angebot von 5 Zahlen, was bedeutet, dass unter, dass 646 00:53:06,420 --> 00:53:11,230 Da der Stack wächst nach unten, bekommen die 5 Zahlen zugeordnet. 647 00:53:11,230 --> 00:53:15,900 Aber weil, wie Arrays arbeiten, wir sichergestellt, dass die erste Position im Array 648 00:53:15,900 --> 00:53:22,260 hat immer eine Adresse kleiner als der zweite, was in dem Array. 649 00:53:22,260 --> 00:53:28,270 So Arrayposition 0 muss immer zuerst geschehen im Speicher 650 00:53:28,270 --> 00:53:30,700 während Arrayposition 1 muss danach passieren 651 00:53:30,700 --> 00:53:33,310 und Array-Position 2 muss danach passieren, 652 00:53:33,310 --> 00:53:37,900 was bedeutet, dass Arrayposition 0 würde irgendwo hier unten passieren, 653 00:53:37,900 --> 00:53:40,690 Arrayposition 1 würde über das passieren 654 00:53:40,690 --> 00:53:45,530 da bewegt sich bedeutet höhere Adressen, da die maximale Adresse ist hier oben. 655 00:53:45,530 --> 00:53:50,490 So array [0] hier unten, array [1] hier oben, array [2] hier oben, array [3] hier oben. 656 00:53:50,490 --> 00:53:55,620 Beachten Sie, wie, bevor wir integer zugeordnet i den ganzen Weg bis hier 657 00:53:55,620 --> 00:54:01,040 wie wir weiter in unser Angebot zu bewegen, sind wir näher und näher an unsere integer i. 658 00:54:01,040 --> 00:54:07,640 Es passiert einfach so, dass array [5], das ist eine Position jenseits unserer Array 659 00:54:07,640 --> 00:54:13,010 Genau hier integer i zugeordnet werden passiert. 660 00:54:13,010 --> 00:54:16,920 Also das ist der Punkt, wo wir gerade sind Schlagen der Platz auf dem Stack 661 00:54:16,920 --> 00:54:21,680 Das war für integer i zugeordnet, und wir, daß auf 0 setzen. 662 00:54:21,680 --> 00:54:26,160 >> Das ist, wie das funktioniert. Haben Sie Fragen? Yeah. 663 00:54:26,160 --> 00:54:30,710 [Schüler] Never mind. Okay. 664 00:54:30,710 --> 00:54:33,090 [Schüler] Wie vermeiden Sie diese Art von Fehlern? 665 00:54:33,090 --> 00:54:41,190 Diese Art von Fehler? Verwenden Sie keine C als Programmiersprache. 666 00:54:41,190 --> 00:54:45,840 Verwenden Sie eine Sprache, die Feldgrenzen überprüft hat. 667 00:54:45,840 --> 00:54:55,900 Solange du vorsichtig bist, brauchen Sie nur zu vermeiden, gehen vorbei an den Grenzen des Arrays. 668 00:54:55,900 --> 00:54:58,300 [Schüler] Also hier, wenn wir an die Grenzen des Arrays ging - 669 00:54:58,300 --> 00:55:01,840 [Bowden] Das ist, wo die Dinge schief gehen beginnen. >> [Schüler] Oh, okay. 670 00:55:01,840 --> 00:55:05,730 Solange Sie im Speicher für das Array zugeordnet bleiben, bist du in Ordnung. 671 00:55:05,730 --> 00:55:12,400 Aber C führt keine Fehlerprüfung. Wenn ich array zu tun [1000], wird es gerne nur ändern, was passiert - 672 00:55:12,400 --> 00:55:16,500 Es geht zum Anfang des Arrays, dann geht 1000 Positionen nach und setzt es auf 0 gesetzt. 673 00:55:16,500 --> 00:55:20,000 Es macht keinen Überprüfung, dass oh, das eigentlich nicht haben 1000 Dinge in ihm. 674 00:55:20,000 --> 00:55:22,750 1000 ist weit über das, was ich sollte sich ändern, 675 00:55:22,750 --> 00:55:26,940 während Java oder etwas, das Sie bekommen array out of bounds index 676 00:55:26,940 --> 00:55:29,820 oder Index out of bounds Ausnahme. 677 00:55:29,820 --> 00:55:33,950 Das ist, warum viele Hochsprachen diese Dinge haben 678 00:55:33,950 --> 00:55:37,340 wo, wenn Sie über die Grenzen des Arrays zu gehen, scheitern Sie 679 00:55:37,340 --> 00:55:40,070 so dass Sie nicht ändern können, Dinge aus unter Ihnen 680 00:55:40,070 --> 00:55:42,590 Und dann wird es viel schlimmer, als nur immer eine Ausnahme 681 00:55:42,590 --> 00:55:44,940 sagen, dass Sie über das Ende des Arrays ging. 682 00:55:44,940 --> 00:55:50,970 [Schüler] Und so sollten wir gerade änderte sich die <= nur > [Bowden] Yeah. 683 00:55:50,970 --> 00:55:54,800 Es sollte 00:55:59,560 Seit sizeof (array) ist 20, aber wir wollen nur 5. >> [Schüler] Right. 685 00:55:59,560 --> 00:56:04,060 Noch Fragen? Okay. 686 00:56:04,060 --> 00:56:07,380 >> [Schüler] Ich habe eine Frage. >> Ja. 687 00:56:07,380 --> 00:56:16,440 [Schüler] Was ist der eigentliche Array-Variable? 688 00:56:16,440 --> 00:56:20,000 [Bowden] wie, was ist Array? 689 00:56:20,000 --> 00:56:24,930 Array selbst ist ein Symbol. 690 00:56:24,930 --> 00:56:31,490 Es ist nur die Adresse des Anfangs der 20 Bytes, die wir verweisen. 691 00:56:31,490 --> 00:56:38,070 Sie können es als Zeiger denken, aber es ist ein konstanter Zeiger. 692 00:56:38,070 --> 00:56:44,140 Sobald alles kompiliert, wird der Variablen-Array nicht mehr existieren. 693 00:56:44,140 --> 00:56:48,210 [Schüler] Also, wie findet er die Größe des Array? 694 00:56:48,210 --> 00:56:54,130 Größe des Feldes bezieht sich auf die Größe dieses Blocks, dass Symbol bezeichnet. 695 00:56:54,130 --> 00:57:01,240 Wenn ich etwas tun, wie printf ("% p \ n", array); 696 00:57:01,240 --> 00:57:05,140 lasst uns laufen lassen. 697 00:57:12,960 --> 00:57:15,530 Was habe ich gerade falsch gemacht? 698 00:57:15,530 --> 00:57:19,220 Array 'array' hier deklariert. 699 00:57:20,820 --> 00:57:23,200 Oh, hier oben. 700 00:57:23,200 --> 00:57:31,250 Clang ist klug, und es geschieht zu bemerken, dass ich das Array als 5 Elemente deklariert 701 00:57:31,250 --> 00:57:34,540 aber ich bin in die Position 1000 der Indizierung. 702 00:57:34,540 --> 00:57:38,450 Es kann das tun, weil diese nur Konstanten sind. 703 00:57:38,450 --> 00:57:43,370 Es kann nur so weit gehen, zu bemerken, dass ich über die Grenzen des Arrays gehen. 704 00:57:43,370 --> 00:57:46,880 Aber bevor, wenn wir i nicht korrekt bemerken, 705 00:57:46,880 --> 00:57:51,040 es kann unmöglich festzustellen, wie viele Werte konnte ich übernehmen, 706 00:57:51,040 --> 00:57:55,540 so kann es nicht bestimmen, dass ich über das Ende des Arrays gehen. 707 00:57:55,540 --> 00:57:59,430 Das ist nur Clang ist clever. 708 00:57:59,430 --> 00:58:03,340 >> Aber jetzt machen buggy4. So was mache ich falsch? 709 00:58:03,340 --> 00:58:05,970 Implizit erklärt Library-Funktion 'printf'. 710 00:58:05,970 --> 00:58:14,960 Ich werde zu wollen # include. 711 00:58:14,960 --> 00:58:18,710 Okay. Jetzt läuft buggy4. 712 00:58:18,710 --> 00:58:24,840 Drucken Sie den Wert des Feldes wie ich hier, ihn zu drucken als Zeiger 713 00:58:24,840 --> 00:58:30,060 Drucke etwas, das wie folgt aussieht - bfb8805c - die einige Adresse ist 714 00:58:30,060 --> 00:58:33,450 das ist im Stapel-ish Region. 715 00:58:33,450 --> 00:58:41,820 Array selbst ist wie ein Zeiger, aber es ist nicht ein tatsächliches Zeiger, 716 00:58:41,820 --> 00:58:45,410 Seit einem regulären Zeiger können wir ändern. 717 00:58:45,410 --> 00:58:54,700 Array ist nur eine Konstante ist. Die 20 Blöcke des Speichers an der Adresse 0xbfb8805c starten. 718 00:58:54,700 --> 00:59:09,020 So bfb8805c über diese Adresse +20- oder ich denke, -20 - 719 00:59:09,020 --> 00:59:17,400 ist der gesamte Speicher für dieses Array zugeordnet. 720 00:59:17,400 --> 00:59:20,350 Array, wird die Variable selbst nicht irgendwo gespeichert. 721 00:59:20,350 --> 00:59:27,660 Wenn Sie die Erstellung der Compiler - Hand winken sie - 722 00:59:27,660 --> 00:59:33,060 aber der Compiler wird nur einzusetzen, wo sie array zu sein weiß. 723 00:59:33,060 --> 00:59:36,090 Es weiß, wo das Array beginnt, 724 00:59:36,090 --> 00:59:40,910 und so kann es immer nur Dinge tun, in Bezug auf die Offsets von diesem Anfang. 725 00:59:40,910 --> 00:59:43,960 Es braucht nicht eine variable sich Array repräsentieren. 726 00:59:43,960 --> 00:59:53,730 Aber wenn ich so etwas wie int * p = array zu tun, jetzt p ist ein Zeiger, der auf diesem Array verweist, 727 00:59:53,730 --> 00:59:57,830 und nun p eigentlich gar auf dem Stack vorhanden. 728 00:59:57,830 --> 01:00:01,950 Ich bin frei, p ändern. Ich kann p = malloc. 729 01:00:01,950 --> 01:00:06,500 So es ursprünglich wies auf Array, jetzt ist es verweist auf etwas Platz auf dem Heap. 730 01:00:06,500 --> 01:00:09,620 Ich kann das nicht array = malloc. 731 01:00:09,620 --> 01:00:13,710 Wenn Clang ist clever, wird es bei mir auf Anhieb schreien. 732 01:00:17,000 --> 01:00:21,430 Eigentlich bin ich ziemlich sicher, gcc würde dies auch tun. 733 01:00:21,430 --> 01:00:25,010 So Array-Typ 'int [5] "ist nicht übertragbar. 734 01:00:25,010 --> 01:00:28,040 Sie können nicht zuordnen etwas zu einem Array-Typ 735 01:00:28,040 --> 01:00:30,500 weil Array ist nur eine Konstante. 736 01:00:30,500 --> 01:00:34,760 Es ist ein Symbol, das Verweise diese 20 Byte. Ich kann es nicht ändern. 737 01:00:34,760 --> 01:00:37,690 >> [Schüler] Und wo ist die Größe des Arrays gespeichert? 738 01:00:37,690 --> 01:00:40,670 [Bowden] Es ist nicht irgendwo gespeichert. Es ist, wenn es kompiliert ist. 739 01:00:40,670 --> 01:00:46,310 Also, wo ist die Größe des Array gespeichert? 740 01:00:46,310 --> 01:00:51,870 Sie können nur sizeof (Array) innerhalb der Funktion, dass das Array selbst erklärt. 741 01:00:51,870 --> 01:01:03,150 Also, wenn ich eine Funktion, foo, und kann ich tun (int array []) 742 01:01:03,150 --> 01:01:10,450 printf ("% d \ n", sizeof (array)); 743 01:01:10,450 --> 01:01:21,330 und dann hier unten Ich nenne foo (array); 744 01:01:21,330 --> 01:01:24,840 Innere dieser Funktion - wir führen Sie es. 745 01:01:34,200 --> 01:01:36,840 Dies ist Clang ist kluge wieder. 746 01:01:36,840 --> 01:01:43,890 Es sagt mir, dass sizeof auf Array Funktionsparameter 747 01:01:43,890 --> 01:01:46,690 wird Größe 'int *' zurückzukehren. 748 01:01:46,690 --> 01:01:55,150 Dies wäre ein Fehler, wenn es nicht ist, was ich zu geschehen wollte. 749 01:01:55,150 --> 01:01:58,960 Lasst uns tatsächlich auszuschalten Werror. 750 01:02:14,950 --> 01:02:17,590 Warnung. Warnungen sind in Ordnung. 751 01:02:17,590 --> 01:02:19,960 Es wird noch kompilieren, solange es eine Warnung aufweist. 752 01:02:19,960 --> 01:02:22,910 . / A.out wird 4 zu drucken. 753 01:02:22,910 --> 01:02:28,650 Die Warnung generiert wurde ist ein klarer Indikator, was falsch gelaufen ist. 754 01:02:28,650 --> 01:02:34,120 Das int-Array wird nur gehen, um sizeof (int *) zu drucken. 755 01:02:34,120 --> 01:02:39,790 Selbst wenn ich array [5] legte hier, es ist immer noch gerade dabei, sizeof (int *) zu drucken. 756 01:02:39,790 --> 01:02:47,440 So, sobald Sie geben es in eine Funktion, die Unterscheidung zwischen Arrays und Zeiger 757 01:02:47,440 --> 01:02:49,670 ist nicht existent. 758 01:02:49,670 --> 01:02:52,640 Dies geschieht, um ein Array, das auf den Stapel erklärt wurde sein, 759 01:02:52,640 --> 01:02:58,300 aber sobald wir an den Wert, dass 0xbf blah, blah, blah in dieser Funktion 760 01:02:58,300 --> 01:03:03,350 dann Zeiger auf dieses Array auf dem Stack. 761 01:03:03,350 --> 01:03:08,310 Das heißt also, dass sizeof gilt nur in der Funktion, die das Array deklariert wurde, 762 01:03:08,310 --> 01:03:11,230 was bedeutet, dass, wenn Sie kompilieren diese Funktion, 763 01:03:11,230 --> 01:03:17,330 wenn Clang durch diese Funktion geht, sieht es Array ist ein int-Array der Größe 5. 764 01:03:17,330 --> 01:03:20,640 Also es sieht sizeof (array). Nun, das ist 20. 765 01:03:20,640 --> 01:03:26,440 Das ist tatsächlich, wie sizeof arbeitet grundsätzlich für fast alle Fälle. 766 01:03:26,440 --> 01:03:31,150 Sizeof ist keine Funktion, es ist ein Operator. 767 01:03:31,150 --> 01:03:33,570 Sie rufen Sie nicht die sizeof Funktion. 768 01:03:33,570 --> 01:03:38,280 Sizeof (int), wird der Compiler nur, dass bis 4 zu übersetzen. 769 01:03:41,480 --> 01:03:43,700 Verstanden? Okay. 770 01:03:43,700 --> 01:03:47,520 >> [Schüler] Also, was ist der Unterschied zwischen sizeof (array) in Haupt-und in foo? 771 01:03:47,520 --> 01:03:52,840 Dies ist, weil wir sagen, sizeof (array), die vom Typ int * ist bist, 772 01:03:52,840 --> 01:03:57,120 während das Array hier unten ist nicht vom Typ int *, es ist ein int-Array. 773 01:03:57,120 --> 01:04:04,540 >> [Schüler] Also, wenn Sie den Parameter hatte array [] anstelle von int * array, 774 01:04:04,540 --> 01:04:09,230 würde das bedeuten, dass man sich noch ändern array, weil es jetzt ein Zeiger ist? 775 01:04:09,230 --> 01:04:14,250 [Bowden] Wie das? >> [Schüler] Yeah. Können Sie Array innerhalb der Funktion jetzt? 776 01:04:14,250 --> 01:04:18,420 [Bowden] Man könnte Array in beiden Fällen ändern. 777 01:04:18,420 --> 01:04:23,130 In beiden Fällen sind Sie frei zu sagen, array [4] = 0 ist. 778 01:04:23,130 --> 01:04:26,590 [Schüler] Aber können Sie Arrays, auf etwas anderes? 779 01:04:26,590 --> 01:04:30,230 [Bowden] Oh. Yeah. In jedem Fall - >> [Schüler] Yeah. 780 01:04:30,230 --> 01:04:38,410 [Bowden] Die Unterscheidung zwischen array [] und ein int * array, gibt es keine. 781 01:04:38,410 --> 01:04:42,570 Sie können auch einige mehrdimensionales Array hier 782 01:04:42,570 --> 01:04:47,050 für einige praktische Syntax, aber es ist immer noch nur ein Zeiger. 783 01:04:47,050 --> 01:04:56,400 Das bedeutet, dass ich frei array tun habe = malloc (sizeof (int)), und nun woanders zeigen. 784 01:04:56,400 --> 01:04:59,610 Aber wie, wie dies immer und immer funktioniert, 785 01:04:59,610 --> 01:05:03,210 Änderung dieses Array, indem sie verweisen auf etwas anderes 786 01:05:03,210 --> 01:05:07,570 ändert nichts an dieser array hier unten, weil es eine Kopie des Arguments ist, 787 01:05:07,570 --> 01:05:10,780 es ist nicht ein Zeiger auf dieses Argument. 788 01:05:10,780 --> 01:05:16,070 Und tatsächlich, so wie weitere Anzeichen dafür, dass es genau das gleiche - 789 01:05:16,070 --> 01:05:21,100 wir bereits gesehen, was Druck array Drucke - 790 01:05:21,100 --> 01:05:31,410 was ist, wenn wir drucken die Adresse des Arrays oder die Adresse der Adresse des Arrays 791 01:05:31,410 --> 01:05:36,290 , von denen entweder? 792 01:05:41,770 --> 01:05:45,220 Lassen Sie ignorieren diese ein. 793 01:05:48,140 --> 01:05:51,660 Okay. Das ist in Ordnung. Es läuft jetzt. / A.out. 794 01:05:51,660 --> 01:06:00,220 Printing-Array, dann drucken Sie die Adresse des Arrays sind die gleiche Sache. 795 01:06:00,220 --> 01:06:02,870 Array gerade nicht vorhanden ist. 796 01:06:02,870 --> 01:06:08,190 Er weiß, wann Sie drucken Array, Sie drucken das Symbol, das den 20 Byte bezieht. 797 01:06:08,190 --> 01:06:11,940 Drucken Sie die Adresse des Arrays, na ja, nicht Array nicht existieren. 798 01:06:11,940 --> 01:06:17,200 Es muss nicht eine Adresse, so dass es nur druckt die Adresse jener 20 Byte. 799 01:06:20,820 --> 01:06:28,150 Sobald Sie sich kompilieren, in der kompilierten buggy4 mögen. / A.out, 800 01:06:28,150 --> 01:06:30,340 Array ist nicht existent. 801 01:06:30,340 --> 01:06:33,640 Pointers existieren. Arrays nicht. 802 01:06:34,300 --> 01:06:38,060 Die Blöcke des Speichers repräsentiert das Array noch existieren, 803 01:06:38,060 --> 01:06:43,270 aber die variable Arrays und Variablen dieses Typs gibt es nicht. 804 01:06:46,260 --> 01:06:50,270 Das sind, wie die wichtigsten Unterschiede zwischen Arrays und Zeiger 805 01:06:50,270 --> 01:06:55,590 werden, sobald Sie Funktionsaufrufe zu machen, gibt es keinen Unterschied. 806 01:06:55,590 --> 01:07:00,460 Aber innerhalb der Funktion, die das Array selbst erklärt wird, arbeitet sizeof anders 807 01:07:00,460 --> 01:07:05,190 da Sie das Drucken der Größe der Blöcke statt der Größe des Typs, 808 01:07:05,190 --> 01:07:08,950 und man kann es nicht ändern, weil es ein Symbol ist. 809 01:07:08,950 --> 01:07:14,370 Drucken der Sache und die Adresse der Sache druckt die gleiche Sache. 810 01:07:14,370 --> 01:07:18,480 Und das ist ziemlich viel es. 811 01:07:18,480 --> 01:07:20,820 [Schüler] Könnte man sagen, dass man mehr Zeit? 812 01:07:21,170 --> 01:07:24,170 Ich könnte etwas verpasst haben. 813 01:07:24,170 --> 01:07:29,260 Printing-Array und Adresse des Arrays druckt die gleiche Sache, 814 01:07:29,260 --> 01:07:33,180 während, wenn Sie drucken einen Zeiger gegen die Adresse des Zeigers, 815 01:07:33,180 --> 01:07:36,010 die eine Sache, druckt die Adresse von dem, was Sie auf den Hinweis, 816 01:07:36,010 --> 01:07:40,360 der andere gibt die Adresse des Zeigers auf dem Stack. 817 01:07:40,360 --> 01:07:47,040 Sie können einen Zeiger, man kann es nicht ändern ein Array-Symbol. 818 01:07:47,740 --> 01:07:53,270 Und sizeof Zeiger wird die Größe dieses Zeigers drucken. 819 01:07:53,270 --> 01:07:57,470 So int * p sizeof (p) wird 4 zu drucken, 820 01:07:57,470 --> 01:08:04,110 aber int array [5] print sizeof (array) wird auf 20 drucken. 821 01:08:04,110 --> 01:08:07,480 [Schüler] So int array [5] druckt 20? >> Ja. 822 01:08:07,480 --> 01:08:13,300 Das ist, warum innerhalb buggy4, wenn es um sizeof (array) werden verwendet 823 01:08:13,300 --> 01:08:16,660 Diese tat i <20, ist das nicht das, was wir wollten. 824 01:08:16,660 --> 01:08:20,880 Wir wollen i <5. >> [Schüler] Okay. 825 01:08:20,880 --> 01:08:25,569 [Bowden] Und dann, sobald Sie vorbei in den Funktionen zu starten, 826 01:08:25,569 --> 01:08:34,340 wenn wir das täten int * p = array; 827 01:08:34,340 --> 01:08:39,779 Innere dieser Funktion können wir im Grunde mit p-und Array in genau der gleichen Weise, 828 01:08:39,779 --> 01:08:43,710 mit Ausnahme der sizeof Problem und die sich verändernde Problem. 829 01:08:43,710 --> 01:08:49,810 Aber p [0] = 1; ist die gleiche wie zu sagen array [0] = 1; 830 01:08:49,810 --> 01:08:55,600 Und sobald wir foo (array) sagen, oder foo (p); 831 01:08:55,600 --> 01:08:59,760 Innenseite des foo-Funktion, das ist das gleiche Gespräch zweimal. 832 01:08:59,760 --> 01:09:03,350 Es gibt keinen Unterschied zwischen diesen zwei Anrufe. 833 01:09:07,029 --> 01:09:11,080 >> Jeder gut auf, dass? Okay. 834 01:09:14,620 --> 01:09:17,950 Wir haben 10 Minuten. 835 01:09:17,950 --> 01:09:28,319 >> Wir werden versuchen, durch diesen Hacker Typer Programm zu erhalten, 836 01:09:28,319 --> 01:09:32,350 Diese Website, die kam im letzten Jahr oder so etwas. 837 01:09:34,149 --> 01:09:41,100 Es ist einfach sein soll wie du zufällig eingeben und er druckt - 838 01:09:41,100 --> 01:09:46,729 Was auch immer Datei geschieht es geladen haben, ist, wie es du schreibst aussieht. 839 01:09:46,729 --> 01:09:52,069 Es sieht aus wie eine Art von Betriebssystem-Code. 840 01:09:53,760 --> 01:09:56,890 Das ist, was wir umsetzen wollen. 841 01:10:08,560 --> 01:10:11,690 Sie sollten eine binäre ausführbare Datei namens hacker_typer 842 01:10:11,690 --> 01:10:14,350 das braucht in einem einzigen Argument, die Datei "Hacker-Typ." 843 01:10:14,350 --> 01:10:16,480 Starten der ausführbaren Datei sollte den Bildschirm 844 01:10:16,480 --> 01:10:20,850 und dann ausdrucken ein Charakter aus der übergebenen Datei jedes Mal der Benutzer eine Taste drückt. 845 01:10:20,850 --> 01:10:24,990 So beliebigen Tonart drücken, sollte es entfernt und stattdessen Drucken ein Zeichen aus der Datei 846 01:10:24,990 --> 01:10:27,810 das ist das Argument. 847 01:10:29,880 --> 01:10:34,350 Ich werde ziemlich viel sagen, was die Dinge, die wir gehen zu müssen, zu wissen, sind sind. 848 01:10:34,350 --> 01:10:36,440 Aber wir wollen Sie bitte zuerst die termios Bibliothek. 849 01:10:36,440 --> 01:10:44,840 Ich habe noch nie diese Bibliothek in meinem ganzen Leben verwendet, so hat es sehr minimal Zwecke. 850 01:10:44,840 --> 01:10:48,610 Aber das wird die Bibliothek nutzen wir wegwerfen, das Zeichen, das Sie treffen können 851 01:10:48,610 --> 01:10:52,390 wenn Sie in Standard in. eingeben 852 01:10:56,970 --> 01:11:05,840 So hacker_typer.c, und wir gehen zu wollen, # include. 853 01:11:05,840 --> 01:11:12,870 Mit Blick auf die Manpage für termios - ich vermute, dass es das Terminal OS oder so etwas - 854 01:11:12,870 --> 01:11:16,240 Ich weiß nicht, wie es zu lesen. 855 01:11:16,240 --> 01:11:21,040 Mit Blick auf diese, sagt er, um diese 2 Dateien enthalten, so werden wir das tun. 856 01:11:37,620 --> 01:11:46,820 >> Das allererste, wollen wir in einem einzigen Argument, das die Datei sollten wir öffnen wird. 857 01:11:46,820 --> 01:11:52,420 So was will ich tun? Wie kann ich überprüfen, ich habe ein einziges Argument? 858 01:11:52,420 --> 01:11:56,480 [Schüler] Wenn argc es gleich. >> [Bowden] Yeah. 859 01:11:56,480 --> 01:12:21,250 So if (argc = 2!) Printf ("usage:% s [Datei öffnen]"). 860 01:12:21,250 --> 01:12:32,750 So jetzt, wenn ich das ohne eine zweite Argument ausgeführt - oh, ich brauche die neue Linie - 861 01:12:32,750 --> 01:12:36,240 Sie werden sehen, es sagt Nutzung:. / hacker_typer, 862 01:12:36,240 --> 01:12:39,770 und dann das zweite Argument sollte die Datei Ich möchte zu öffnen sein. 863 01:12:58,430 --> 01:13:01,260 Nun, was soll ich tun? 864 01:13:01,260 --> 01:13:08,490 Ich möchte aus dieser Datei gelesen. Wie kann ich aus einer Datei lesen? 865 01:13:08,490 --> 01:13:11,920 [Schüler] öffnen Sie es zuerst. >> Ja. 866 01:13:11,920 --> 01:13:15,010 So fopen. Was bedeutet fopen aussehen? 867 01:13:15,010 --> 01:13:22,980 [Schüler] Dateiname. >> [Bowden] Dateiname wird argv [1] sein. 868 01:13:22,980 --> 01:13:26,110 [Schüler] Und dann, was Sie wollen damit zu tun, so dass die - >> [Bowden] Yeah. 869 01:13:26,110 --> 01:13:28,740 Also, wenn Sie sich nicht erinnern, könnten Sie einfach tun, man fopen, 870 01:13:28,740 --> 01:13:32,960 wohin es geht, ein const char * path, wobei Pfad Dateiname sein, 871 01:13:32,960 --> 01:13:34,970 const char * mode. 872 01:13:34,970 --> 01:13:38,660 Wenn Sie sich nicht erinnern, was Modus passieren, dann können Sie für den Modus zu suchen. 873 01:13:38,660 --> 01:13:44,660 Innerhalb von Manpages, ist der Schrägstrich, was Sie verwenden können, um für Dinge zu suchen. 874 01:13:44,660 --> 01:13:49,790 So tippe ich / Modus für den Suchmodus. 875 01:13:49,790 --> 01:13:57,130 n und N sind, was Sie können, um durch die Suche nach Übereinstimmungen zu verwenden. 876 01:13:57,130 --> 01:13:59,800 Hier heißt es das Argument mode zeigt auf einen String 877 01:13:59,800 --> 01:14:01,930 beginnend mit einer der folgenden Sequenzen. 878 01:14:01,930 --> 01:14:06,480 So r, Open Text-Datei zum Lesen. Das ist, was wir tun wollen. 879 01:14:08,930 --> 01:14:13,210 Zum Lesen, und ich möchte zu speichern, dass. 880 01:14:13,210 --> 01:14:18,720 Die Sache wird ein FILE * sein. Nun, was kann ich tun? 881 01:14:18,720 --> 01:14:21,200 Gib mir eine Sekunde. 882 01:14:28,140 --> 01:14:30,430 Okay. Nun, was kann ich tun? 883 01:14:30,430 --> 01:14:32,940 [Schüler] Prüfen Sie, ob es NULL ist. >> [Bowden] Yeah. 884 01:14:32,940 --> 01:14:38,690 Jedes Mal, wenn Sie eine Datei öffnen, stellen Sie sicher, dass Sie erfolgreich sind in der Lage, es zu öffnen. 885 01:14:58,930 --> 01:15:10,460 >> Jetzt möchte ich, dass termios Dinge zu tun, wo ich zum ersten Mal las meine aktuellen Einstellungen möchten 886 01:15:10,460 --> 01:15:14,050 und speichern Sie diese in etwas, dann möchte ich meine Einstellungen ändern 887 01:15:14,050 --> 01:15:19,420 wegzuwerfen jedes Zeichen, dass ich geben, 888 01:15:19,420 --> 01:15:22,520 und dann möchte ich, um diese Einstellungen zu aktualisieren. 889 01:15:22,520 --> 01:15:27,250 Und dann am Ende des Programms, möchte ich ändern zurück zu meiner ursprünglichen Einstellungen. 890 01:15:27,250 --> 01:15:32,080 So ist die Struktur wird vom Typ termios sein, und ich werde zwei von denen wollen. 891 01:15:32,080 --> 01:15:35,600 Die erste wird mein current_settings sein, 892 01:15:35,600 --> 01:15:42,010 und dann wirst meine hacker_settings sein. 893 01:15:42,010 --> 01:15:48,070 Zuerst werde ich möchte meine aktuellen Einstellungen zu speichern, 894 01:15:48,070 --> 01:15:53,790 dann werde ich zu wollen hacker_settings aktualisieren, 895 01:15:53,790 --> 01:16:01,570 und dann so am Ende meines Programms, ich möchte um die aktuellen Einstellungen zurück. 896 01:16:01,570 --> 01:16:08,660 So sparen aktuellen Einstellungen, die Art und Weise, die funktioniert haben wir Menschen termios. 897 01:16:08,660 --> 01:16:15,810 Wir sehen, dass wir diese int tcsetattr, int tcgetattr haben. 898 01:16:15,810 --> 01:16:22,960 Ich gehe in einem termios struct durch ihre Zeiger. 899 01:16:22,960 --> 01:16:30,640 Die Art und Weise dies aussehen wird - ich habe schon vergessen, was die Funktion aufgerufen wurde. 900 01:16:30,640 --> 01:16:34,930 Kopieren und einfügen. 901 01:16:39,150 --> 01:16:45,500 So tcgetattr, dann will ich in der Struktur passieren, dass ich die Angaben speichern in, 902 01:16:45,500 --> 01:16:49,650 was wird current_settings sein, 903 01:16:49,650 --> 01:16:59,120 und das erste Argument ist der Deskriptor für das, was ich will, um die Attribute zu speichern. 904 01:16:59,120 --> 01:17:04,360 Was die Dateideskriptor ist wie jedes Mal, wenn Sie eine Datei öffnen, wird es einen Dateideskriptor. 905 01:17:04,360 --> 01:17:14,560 Wenn ich fopen argv [1], wird es einen Dateideskriptor, die Sie verweisen 906 01:17:14,560 --> 01:17:16,730 wenn Sie zu lesen oder zu schreiben. 907 01:17:16,730 --> 01:17:19,220 Das ist nicht der Dateideskriptor Ich möchte hier verwenden. 908 01:17:19,220 --> 01:17:21,940 Es gibt drei Dateideskriptoren haben standardmäßig 909 01:17:21,940 --> 01:17:24,310 das sind Standard in, Standardausgabe und Standardfehler. 910 01:17:24,310 --> 01:17:29,960 Standardmäßig ich denke es ist Standard in 0 ist, Standardausgabe 1 ist und Standardfehler 2 ist. 911 01:17:29,960 --> 01:17:33,980 So was will ich, um die Einstellungen zu ändern? 912 01:17:33,980 --> 01:17:37,370 Ich möchte die Einstellungen, wenn ich traf ein Zeichen zu ändern, 913 01:17:37,370 --> 01:17:41,590 Ich möchte, dass dieses Zeichen entfernt, anstatt ihn zu drucken auf dem Bildschirm. 914 01:17:41,590 --> 01:17:45,960 Was stream - Standard, Standard out, oder Standard-Fehler - 915 01:17:45,960 --> 01:17:52,050 reagiert auf Dinge, wenn ich auf der Tastatur eingeben? >> [Student] Standard in. >> Ja. 916 01:17:52,050 --> 01:17:56,450 So kann ich entweder 0 oder ich kann stdin tun. 917 01:17:56,450 --> 01:17:59,380 Ich erhalte die current_settings von Standard in. 918 01:17:59,380 --> 01:18:01,720 >> Jetzt möchte ich diese Einstellungen zu aktualisieren, 919 01:18:01,720 --> 01:18:07,200 so erste Ich werde in hacker_settings was meine current_settings sind kopieren. 920 01:18:07,200 --> 01:18:10,430 Und wie structs Arbeit ist, wird es nur zu kopieren. 921 01:18:10,430 --> 01:18:14,510 Diese kopiert alle Felder, wie man es erwarten würde. 922 01:18:14,510 --> 01:18:17,410 >> Jetzt möchte ich einige der Felder zu aktualisieren. 923 01:18:17,410 --> 01:18:21,670 Mit Blick auf termios, müssten Sie durch eine Menge von diesen gelesen 924 01:18:21,670 --> 01:18:24,110 nur um zu sehen, was Sie suchen möchten, 925 01:18:24,110 --> 01:18:28,210 aber die Flags, die Sie gehen zu wollen, zu suchen sind sind Echo, 926 01:18:28,210 --> 01:18:33,110 so ECHO Echo Zeichen einzugeben. 927 01:18:33,110 --> 01:18:37,710 Zuerst möchte ich eingestellt - ich habe schon vergessen, was die Felder. 928 01:18:45,040 --> 01:18:47,900 Dies ist, was die Struktur aussieht. 929 01:18:47,900 --> 01:18:51,060 So Eingabemodi Ich denke, wir ändern wollen. 930 01:18:51,060 --> 01:18:54,210 Wir werden am Lösung suchen, um sicherzustellen, dass das, was wir ändern wollen. 931 01:19:04,060 --> 01:19:12,610 Wir wollen lflag ändern, um zu verhindern, die im Wege alle diese aussehen. 932 01:19:12,610 --> 01:19:14,670 Wir wollen die lokalen Modus zu ändern. 933 01:19:14,670 --> 01:19:17,710 Sie müssten durch diese ganze Sache zu lesen, um zu verstehen, wo alles gehört 934 01:19:17,710 --> 01:19:19,320 dass wir ändern möchten. 935 01:19:19,320 --> 01:19:24,120 Aber es ist im Inneren des lokalen Modi, wo wir gehen zu wollen, um das zu ändern sind. 936 01:19:27,080 --> 01:19:33,110 So hacker_settings.cc_lmode ist, was es heißt. 937 01:19:39,630 --> 01:19:43,020 c_lflag. 938 01:19:49,060 --> 01:19:52,280 Dies ist, wo wir in Bitoperatoren bekommen. 939 01:19:52,280 --> 01:19:54,860 Wir sind irgendwie aus der Zeit, aber wir werden es ganz schnell gehen. 940 01:19:54,860 --> 01:19:56,600 Dies ist, wo wir in bitweisen Operatoren zu erhalten, 941 01:19:56,600 --> 01:19:59,950 wo ich glaube, ich sagte einmal vor langer Zeit, dass, wenn Sie sich mit Fahnen zu starten, 942 01:19:59,950 --> 01:20:03,370 du gehst zu sein mit bitweisen Operator eine Menge. 943 01:20:03,370 --> 01:20:08,240 Jedes Bit in der Flagge entspricht einer Art von Verhalten. 944 01:20:08,240 --> 01:20:14,090 Also hier hat dieses Flag eine Reihe von verschiedenen Dingen, wo sie sich alle etwas anderes bedeuten. 945 01:20:14,090 --> 01:20:18,690 Aber was ich tun will ist einfach abschalten Bit, das ECHO entspricht. 946 01:20:18,690 --> 01:20:25,440 So drehen, dass der I do & = ¬ ECHO. 947 01:20:25,440 --> 01:20:30,110 Eigentlich, denke ich, es ist wie Techo oder so etwas. Ich werde einfach noch einmal zu überprüfen. 948 01:20:30,110 --> 01:20:34,050 Ich kann termios es. Es ist einfach ECHO. 949 01:20:34,050 --> 01:20:38,440 ECHO wird ein einzelnes Bit sein. 950 01:20:38,440 --> 01:20:44,230 ¬ ECHO wird bedeuten, alle Bits auf 1 gesetzt sind, was bedeutet, alle Flags auf true gesetzt 951 01:20:44,230 --> 01:20:47,140 mit Ausnahme der ECHO-Bit. 952 01:20:47,140 --> 01:20:53,830 Mit Beendigung meiner lokalen Merker mit dieser, bedeutet dies, alle Flaggen, die derzeit auf true gesetzt 953 01:20:53,830 --> 01:20:56,520 noch auf true gesetzt werden. 954 01:20:56,520 --> 01:21:03,240 Wenn meine ECHO-Flag auf true gesetzt wird, dann wird dies zwangsläufig auf der ECHO-Flag auf false. 955 01:21:03,240 --> 01:21:07,170 So diese Codezeile einfach schaltet die ECHO-Flagge. 956 01:21:07,170 --> 01:21:16,270 Die anderen Zeilen Code, werde ich sie einfach kopieren Sie sie im Interesse der Zeit, und dann erklären sie. 957 01:21:27,810 --> 01:21:30,180 In der Lösung, sagte er 0. 958 01:21:30,180 --> 01:21:33,880 Es ist wahrscheinlich besser, explizit sagen stdin. 959 01:21:33,880 --> 01:21:42,100 >> Beachten Sie, dass ich auch tun ECHO | ICANON hier. 960 01:21:42,100 --> 01:21:46,650 ICANON bezieht sich auf etwas getrennt, die kanonische Modus bedeutet. 961 01:21:46,650 --> 01:21:50,280 Was kanonischen Modus bedeutet in der Regel, wenn Sie mit der Eingabe out sind die Befehlszeile 962 01:21:50,280 --> 01:21:54,670 Standard in nicht verarbeitet nichts, bis Sie newline getroffen. 963 01:21:54,670 --> 01:21:58,230 Also, wenn Sie GetString, geben Sie ein paar Dinge, dann drückst du Zeilenumbruch. 964 01:21:58,230 --> 01:22:00,590 Das ist, wenn es auf Standard eingeschickt 965 01:22:00,590 --> 01:22:02,680 Das ist die Standardeinstellung. 966 01:22:02,680 --> 01:22:05,830 Wenn ich abschalten kanonischen-Modus, jetzt jedes einzelne Zeichen drücken Sie 967 01:22:05,830 --> 01:22:10,910 ist, was wird verarbeitet, was normalerweise etwas schlecht, weil es langsam, diese Dinge zu verarbeiten ist, 968 01:22:10,910 --> 01:22:14,330 weshalb es gut ist, um es in ganze Zeilen zu puffern. 969 01:22:14,330 --> 01:22:16,810 Aber ich will jedes Zeichen verarbeitet werden 970 01:22:16,810 --> 01:22:18,810 da ich nicht wollen, dass es auf mich warten newline zu schlagen 971 01:22:18,810 --> 01:22:21,280 bevor es alle Zeichen verarbeitet Ich habe tippen. 972 01:22:21,280 --> 01:22:24,760 Dies schaltet kanonischen Modus. 973 01:22:24,760 --> 01:22:31,320 Dieses Zeug bedeutet nur, wenn es verarbeitet tatsächlich Zeichen. 974 01:22:31,320 --> 01:22:35,830 Dies bedeutet, verarbeiten sie sofort; sobald ich tippe sie zu verarbeiten. 975 01:22:35,830 --> 01:22:42,510 Und dies ist die Funktion, die Aktualisierung meines Einstellungen für Standard-in, 976 01:22:42,510 --> 01:22:45,480 und TCSA Mitteln tun es jetzt. 977 01:22:45,480 --> 01:22:50,310 Die anderen Optionen werden warten, bis alles, was derzeit auf dem Strom verarbeitet wird. 978 01:22:50,310 --> 01:22:52,030 Das spielt eigentlich keine Rolle. 979 01:22:52,030 --> 01:22:56,920 Gerade jetzt meine Einstellungen ändern zu sein, was derzeit in hacker_typer_settings. 980 01:22:56,920 --> 01:23:02,210 Ich glaube, ich nannte es hacker_settings, also lasst uns das ändern. 981 01:23:09,610 --> 01:23:13,500 Ändern Sie alles hacker_settings. 982 01:23:13,500 --> 01:23:16,870 >> Jetzt, am Ende unseres Programms werden wir zurückkehren möchten 983 01:23:16,870 --> 01:23:20,210 zu dem, was derzeit innerhalb normal_settings, 984 01:23:20,210 --> 01:23:26,560 was wird wie und normal_settings aussehen. 985 01:23:26,560 --> 01:23:30,650 Beachten Sie, ich habe nicht alle meine normal_settings da ursprünglich bekommen es geändert. 986 01:23:30,650 --> 01:23:34,520 Dann ändern Sie einfach sie zurück, gehe ich sie wieder am Ende. 987 01:23:34,520 --> 01:23:38,390 Dies war das Update. Okay. 988 01:23:38,390 --> 01:23:43,900 >> Nun innerhalb von hier werde ich nur erklären, den Code im Interesse der Zeit. 989 01:23:43,900 --> 01:23:46,350 Es ist nicht so viel Code. 990 01:23:50,770 --> 01:24:03,750 Wir sehen lesen wir ein Zeichen aus der Datei. Wir nannten es f. 991 01:24:03,750 --> 01:24:07,850 Jetzt können Menschen fgetc, aber wie fgetc funktionieren wird 992 01:24:07,850 --> 01:24:11,910 ist nur, es wird das Zeichen, das Sie gerade lesen oder EOF zurück, 993 01:24:11,910 --> 01:24:15,680 das entspricht dem Ende der Datei oder des Fehlers geschieht. 994 01:24:15,680 --> 01:24:19,900 Wir sind Looping, weiterhin ein einzelnes Zeichen aus der Datei gelesen, 995 01:24:19,900 --> 01:24:22,420 bis wir aus Zeichen ausführen, um zu lesen. 996 01:24:22,420 --> 01:24:26,650 Und während wir tun wollen, warten wir auf einen einzelnen Charakter von Standard in. 997 01:24:26,650 --> 01:24:29,090 Jedes einzelne Mal, wenn Sie etwas eingeben in der Befehlszeile, 998 01:24:29,090 --> 01:24:32,820 das ist in einem Charakter Lesen von Standard in. 999 01:24:32,820 --> 01:24:38,330 Dann putchar ist eben das char lesen wir hier von der Datei in Standard-Out setzen. 1000 01:24:38,330 --> 01:24:42,890 Sie können Menschen putchar, aber es ist gerade dabei, in die Standardausgabe, es ist Ausdruck dieser Charakter. 1001 01:24:42,890 --> 01:24:51,600 Man könnte auch einfach printf tun ("% c", c); gleiche Idee. 1002 01:24:53,330 --> 01:24:56,670 Das wird den größten Teil unserer Arbeit zu tun. 1003 01:24:56,670 --> 01:25:00,300 >> Das letzte, was wir wollen, zu tun, ist nur fclose unserer Datei. 1004 01:25:00,300 --> 01:25:03,310 Wenn Sie nicht fclose, das ist ein Speicherverlust. 1005 01:25:03,310 --> 01:25:06,680 Wir wollen die Datei, die wir ursprünglich eröffnet fclose, und ich denke, das ist es. 1006 01:25:06,680 --> 01:25:13,810 Wenn wir das machen, hatte ich schon Probleme. 1007 01:25:13,810 --> 01:25:17,260 Mal sehen. 1008 01:25:17,260 --> 01:25:19,960 Was hat es beschweren? 1009 01:25:19,960 --> 01:25:30,220 Erwartete 'int', sondern Argument ist vom Typ 'struct _IO_FILE *'. 1010 01:25:36,850 --> 01:25:39,370 Wir werden sehen, ob das funktioniert. 1011 01:25:45,210 --> 01:25:53,540 Nur in C99 erlaubt. Augh. Okay, machen hacker_typer. 1012 01:25:53,540 --> 01:25:57,760 Jetzt bekommen wir weitere nützliche Beschreibungen. 1013 01:25:57,760 --> 01:25:59,900 So Schwarzarbeit Kennung 'normal_settings "zu verwenden. 1014 01:25:59,900 --> 01:26:04,170 Ich habe es nicht nennen normal_settings. Ich nannte es current_settings. 1015 01:26:04,170 --> 01:26:12,090 So ändern wir das alles. 1016 01:26:17,920 --> 01:26:21,710 Jetzt Übergabe des Arguments. 1017 01:26:26,290 --> 01:26:29,500 Ich werde diese 0 für jetzt machen. 1018 01:26:29,500 --> 01:26:36,720 Okay. . / Hacker_typer cp.c. 1019 01:26:36,720 --> 01:26:39,590 Ich habe auch nicht den Bildschirm am Anfang. 1020 01:26:39,590 --> 01:26:42,960 Aber man blickt auf die letzte Problem Satz zu sehen, wie Sie den Bildschirm zu löschen. 1021 01:26:42,960 --> 01:26:45,160 Es ist nur Ausdruck einige Zeichen 1022 01:26:45,160 --> 01:26:47,210 während dies zu tun, was ich tun will. 1023 01:26:47,210 --> 01:26:48,900 Okay. 1024 01:26:48,900 --> 01:26:55,280 Und darüber nachzudenken, warum dies notwendig, um 0 statt stdin sein, 1025 01:26:55,280 --> 01:27:00,560 die sollten # definieren 0, 1026 01:27:00,560 --> 01:27:03,890 dies wird beklagt, dass - 1027 01:27:13,150 --> 01:27:19,360 Vor wenn ich sagte, dass es Dateideskriptoren, aber dann haben Sie auch Ihren FILE *, 1028 01:27:19,360 --> 01:27:23,210 ein Datei-Deskriptor nur eine einzige Zahl, 1029 01:27:23,210 --> 01:27:26,970 während ein FILE * hat eine ganze Reihe von Sachen mit ihm verbunden. 1030 01:27:26,970 --> 01:27:30,380 Der Grund müssen wir auf 0 statt stdin sagen, 1031 01:27:30,380 --> 01:27:37,480 ist, dass die Standardeingabe ist ein FILE *, die zur Sache, die Referenzierung Dateideskriptor 0 wird betont. 1032 01:27:37,480 --> 01:27:45,070 Also auch hier, wenn ich fopen tun (argv [1], ich bin immer ein FILE * zurück. 1033 01:27:45,070 --> 01:27:51,180 Aber irgendwo in diesem FILE * ist eine Sache, die der Datei-Deskriptor für diese Datei. 1034 01:27:51,180 --> 01:27:57,430 Wenn Sie auf der man-Seite für offene aussehen, so dass ich glaube, du wirst zu tun haben, man 3 offen - nein - 1035 01:27:57,430 --> 01:27:59,380 Mann 2 offen - yeah. 1036 01:27:59,380 --> 01:28:06,250 Wenn Sie auf der Seite für offene betrachten, ist offen wie ein niedrigerer Ebene fopen, 1037 01:28:06,250 --> 01:28:09,350 und es ist wieder die eigentliche Datei-Deskriptor. 1038 01:28:09,350 --> 01:28:12,050 fopen macht ein paar Sachen auf der Oberseite offen, 1039 01:28:12,050 --> 01:28:17,640 die anstelle der Rücksendung nur, dass Dateideskriptor eine ganze Datei zurück * Zeiger 1040 01:28:17,640 --> 01:28:20,590 innerhalb dessen ist unser kleiner Dateideskriptor. 1041 01:28:20,590 --> 01:28:25,020 So Norm bezieht sich auf die FILE * Sache, 1042 01:28:25,020 --> 01:28:29,120 wobei 0 bezieht sich nur auf die Dateideskriptor Standard in sich. 1043 01:28:29,120 --> 01:28:32,160 >> Haben Sie Fragen? 1044 01:28:32,160 --> 01:28:35,930 [Lacht] blies durch, dass. 1045 01:28:35,930 --> 01:28:39,140 Gut. Wir sind fertig. [Lacht] 1046 01:28:39,140 --> 01:28:42,000 >> [CS50.TV]