1 00:00:00,000 --> 00:00:03,000 [Powered by Google Translate] [Tydzień 4] 2 00:00:03,000 --> 00:00:05,000 [David J. Malan] [Harvard University] 3 00:00:05,000 --> 00:00:08,000 [To jest CS50.] [CS50.TV] 4 00:00:08,000 --> 00:00:12,000 >> Dobrze, to CS50, i jest to początek 4 tygodniu 5 00:00:12,000 --> 00:00:16,000 i jest to jeden z najwolniejszych możliwych algorytmów sortowania. 6 00:00:16,000 --> 00:00:19,000 Które z nich było to, że po prostu obserwował tam? 7 00:00:19,000 --> 00:00:24,000 To było coś w rodzaju bańki, tak duże O (n ^ 2) + sum, 8 00:00:24,000 --> 00:00:28,000 i rzeczywiście nie jesteśmy jedynymi, którzy w tym świecie wydaje się wiedzieć 9 00:00:28,000 --> 00:00:30,000 co to jest lub bubble jego czas uruchomiona. 10 00:00:30,000 --> 00:00:33,000 Rzeczywiście, był to wywiad z Eric Schmidt z Google 11 00:00:33,000 --> 00:00:45,000 i były senator Barack Obama, zaledwie kilka lat temu. 12 00:00:45,000 --> 00:00:48,000 >> Teraz, Senator, jesteś tu w Google, 13 00:00:48,000 --> 00:00:54,000 a ja lubię myśleć o prezydencji rozmowy kwalifikacyjnej. 14 00:00:54,000 --> 00:00:58,000 Teraz trudno jest dostać pracę jako prezydenta, a ty przechodzisz rygorów teraz. 15 00:00:58,000 --> 00:01:00,000 Trudno też dostać pracę w Google. 16 00:01:00,000 --> 00:01:05,000 Mamy pytania i prosimy naszych kandydatów pytania, 17 00:01:05,000 --> 00:01:10,000 a ten jest z Larry Schwimmer. 18 00:01:10,000 --> 00:01:14,000 Myślicie, że żartuję? To właśnie tu. 19 00:01:14,000 --> 00:01:18,000 Co to jest najbardziej skuteczny sposób, aby posortować milion 32-bitowe liczby całkowite? 20 00:01:18,000 --> 00:01:21,000 [Śmiech] 21 00:01:21,000 --> 00:01:24,000 Dobrze 22 00:01:24,000 --> 00:01:26,000 Przykro mi. >> No, no, no, no. 23 00:01:26,000 --> 00:01:34,000 Myślę, że sortowanie bąbelkowe byłoby źle droga. 24 00:01:34,000 --> 00:01:39,000 >> Chodź, który powiedział mu to? 25 00:01:39,000 --> 00:01:43,000 Ostatni tydzień przypomnieć zrobiliśmy sobie przerwę od kodu, co najmniej na jeden dzień, 26 00:01:43,000 --> 00:01:46,000 i rozpoczął koncentrując się na niektórych wyższych idei i rozwiązywania problemów na poziomie bardziej ogólnym 27 00:01:46,000 --> 00:01:49,000 w kontekście wyszukiwania i sortowania, 28 00:01:49,000 --> 00:01:53,000 i wprowadził coś, co nie Slap tę nazwę w zeszłym tygodniu, 29 00:01:53,000 --> 00:01:56,000 ale asymptotycznej notacji, Big O, Big Omega, 30 00:01:56,000 --> 00:02:00,000 a czasem Big notacja Theta, a te były po prostu sposoby 31 00:02:00,000 --> 00:02:02,000 opisywania czas pracy algorytmów, 32 00:02:02,000 --> 00:02:05,000 ile czasu zajmuje dla algorytmu do uruchomienia. 33 00:02:05,000 --> 00:02:08,000 >> A może pamiętacie, że mówił o czasie trwania w zakresie wielkości 34 00:02:08,000 --> 00:02:11,000 wejścia, które ogólnie nazywamy n, co problem może być, 35 00:02:11,000 --> 00:02:13,000 gdzie n jest liczba osób w pokoju, 36 00:02:13,000 --> 00:02:17,000 liczba stron w książce telefonicznej i zaczęliśmy pisać rzeczy 37 00:02:17,000 --> 00:02:21,000 jak O (n ^ 2) lub O (n) lub O (n log n), 38 00:02:21,000 --> 00:02:24,000 i nawet jeśli matematyka nie bardzo wyszło tak idealnie 39 00:02:24,000 --> 00:02:28,000 i to było n ² - n / 2 czy coś takiego 40 00:02:28,000 --> 00:02:31,000 my zamiast po prostu wyrzucić niektóre z niższych warunkach zamówienia, 41 00:02:31,000 --> 00:02:34,000 i motywacja nie jest to, że naprawdę chcemy 42 00:02:34,000 --> 00:02:37,000 jakby obiektywny sposób oceny 43 00:02:37,000 --> 00:02:39,000 wydajność programów lub wykonanie algorytmów 44 00:02:39,000 --> 00:02:42,000 , które na koniec dnia nie ma nic, na przykład 45 00:02:42,000 --> 00:02:45,000 z szybkością komputera dziś. 46 00:02:45,000 --> 00:02:47,000 >> Na przykład, jeśli wdrożenie sortowania bąbelkowego, 47 00:02:47,000 --> 00:02:50,000 lub wdrożenie seryjnej sortowania sortowania lub zaznaczenie na dzisiejszym komputerze 48 00:02:50,000 --> 00:02:53,000 2 GHz komputer, i uruchomić go, 49 00:02:53,000 --> 00:02:56,000 i zajmuje pewną liczbę sekund, w przyszłym roku nie ma 3 GHz 50 00:02:56,000 --> 00:02:59,000 lub 4 GHz komputer, a może potem twierdzić, że "Wow, mój algorytm 51 00:02:59,000 --> 00:03:03,000 jest teraz dwa razy szybciej ", podczas gdy w rzeczywistości to nie jest oczywiście prawdą. 52 00:03:03,000 --> 00:03:06,000 To tylko sprzęt jest coraz szybszy, ale komputer 53 00:03:06,000 --> 00:03:10,000 nie, i tak naprawdę chcemy wyrzucić rzeczy jak 54 00:03:10,000 --> 00:03:13,000 wielokrotność 2 lub wielokrotność 3, jeśli chodzi o opis 55 00:03:13,000 --> 00:03:17,000 jak szybko lub jak wolno algorytm jest i naprawdę skupić 56 00:03:17,000 --> 00:03:20,000 na n lub jakiś czynnik zawiadomienia, 57 00:03:20,000 --> 00:03:24,000 niektóre jego mocy, jak w przypadku z sortuje tygodnia. 58 00:03:24,000 --> 00:03:27,000 I przypominają, że z pomocą sortowanie korespondencji seryjnej 59 00:03:27,000 --> 00:03:31,000 byliśmy w stanie zrobić o wiele lepiej niż sortowanie bąbelkowe i rodzaju selekcji 60 00:03:31,000 --> 00:03:33,000 a nawet rodzaj wstawiania. 61 00:03:33,000 --> 00:03:36,000 >> Dostaliśmy się do n log n, i znowu, 62 00:03:36,000 --> 00:03:39,000 Przypomnijmy, że log n ogólnie odnosi się do czegoś, co rośnie 63 00:03:39,000 --> 00:03:43,000 wolniej, a następnie n, więc n log n dotąd było dobre 64 00:03:43,000 --> 00:03:45,000 ponieważ mniej niż ² n. 65 00:03:45,000 --> 00:03:47,000 Ale do osiągnięcia N log N z sortowania korespondencji seryjnej 66 00:03:47,000 --> 00:03:51,000 , co było podstawowym zalążkiem idei, które mieliśmy wykorzystać 67 00:03:51,000 --> 00:03:54,000 że my również wykorzystała już w tydzień 0? 68 00:03:54,000 --> 00:03:58,000 Jak udało się rozwiązać problem sortowania sprytnie z sortowania korespondencji seryjnej? 69 00:03:58,000 --> 00:04:04,000 Co było kluczem insight, być może? 70 00:04:04,000 --> 00:04:07,000 Każdy, kto w ogóle. 71 00:04:07,000 --> 00:04:09,000 Dobra, zróbmy krok w tył. 72 00:04:09,000 --> 00:04:11,000 Opisać seryjnej sortowanie swoimi słowami. 73 00:04:11,000 --> 00:04:15,000 Jak to działa? 74 00:04:15,000 --> 00:04:17,000 Dobrze, wiosłować z powrotem do 0 tygodni. 75 00:04:17,000 --> 00:04:19,000 Dobrze, tak. 76 00:04:19,000 --> 00:04:22,000 [Niesłyszalne-uczeń] 77 00:04:22,000 --> 00:04:26,000 Dobra, dobra, więc podzieliliśmy tablicy liczb na 2 części. 78 00:04:26,000 --> 00:04:29,000 Posortowaliśmy każdego z tych elementów, a następnie połączone ich 79 00:04:29,000 --> 00:04:33,000 i widzieliśmy ten pomysł przed podjęcia problemu, że to jest wielki 80 00:04:33,000 --> 00:04:36,000 i siekanie go na problem, że to jest duży czy to duży. 81 00:04:36,000 --> 00:04:38,000 >> Przypomnijmy przykład książki telefonicznej. 82 00:04:38,000 --> 00:04:42,000 Przypomnijmy sobie własny algorytm liczenia od tygodni temu 83 00:04:42,000 --> 00:04:45,000 więc scalić sort podsumował to Pseudokod tutaj. 84 00:04:45,000 --> 00:04:48,000 Kiedy podano n elementów, najpierw było sanity sprawdzić. 85 00:04:48,000 --> 00:04:51,000 Jeśli n <2, to nic nie robię w ogóle 86 00:04:51,000 --> 00:04:55,000 ponieważ jeśli n <2 to n jest 0 lub 1, oczywiście, 87 00:04:55,000 --> 00:04:57,000 a jeśli tak to albo 0 lub 1 nie ma nic do sortowania. 88 00:04:57,000 --> 00:04:59,000 Skończysz. 89 00:04:59,000 --> 00:05:01,000 Twoja lista jest już trywialnie posortowane. 90 00:05:01,000 --> 00:05:04,000 Ale w przeciwnym razie, jeśli masz 2 lub więcej elementów, należy iść dalej i podzielić je 91 00:05:04,000 --> 00:05:06,000 na 2 części, z lewej i prawej strony. 92 00:05:06,000 --> 00:05:09,000 Sortować każdej z tych połówek, a następnie scalić posortowane połówki. 93 00:05:09,000 --> 00:05:13,000 Ale problemem jest to, że na pierwszy rzut oka to jest jak mamy punting. 94 00:05:13,000 --> 00:05:17,000 Jest to okrągły, że jeśli definicja w Poprosiłem cię posortowanie tych n elementów 95 00:05:17,000 --> 00:05:22,000 i mówisz, "W porządku, w porządku, będziemy sortować te n / 2 i tych, n / 2 elementów" 96 00:05:22,000 --> 00:05:27,000 następnie moje następne pytanie będzie "Dobrze, jak można posortować n / 2 elementów?" 97 00:05:27,000 --> 00:05:30,000 >> Jednak ze względu na strukturę tego programu, 98 00:05:30,000 --> 00:05:33,000 bo nie ma w tym przypadku zasada, że ​​tak powiem, 99 00:05:33,000 --> 00:05:39,000 to szczególny przypadek, który mówi, że jeśli n jest 00:05:42,000 Nie reagują z tym samym odpowiedź kołowym. 101 00:05:42,000 --> 00:05:46,000 Proces ten, w końcu tego cykliczność końca. 102 00:05:46,000 --> 00:05:50,000 Jeśli pytam "Sortuj n te elementy" i mówisz: "Dobrze, sortować te n / 2" 103 00:05:50,000 --> 00:05:53,000 wtedy powiedzieć: "W porządku, sort te n / 4, n / 8, n/16" 104 00:05:53,000 --> 00:05:56,000 końcu będziesz dzielić przez dużej ilości wystarczającej 105 00:05:56,000 --> 00:05:59,000 że będziesz miał tylko 1 elementu w lewo, w którym momencie można powiedzieć, 106 00:05:59,000 --> 00:06:02,000 "Tutaj, tutaj jest posortowane pojedynczy element." 107 00:06:02,000 --> 00:06:06,000 Potem blask tego algorytmu tutaj jest wynikają z faktu 108 00:06:06,000 --> 00:06:09,000 że po tych wszystkich indywidualnie posortowanych list, 109 00:06:09,000 --> 00:06:12,000 z których wszystkie są wielkości 1, co wydaje się być bezużyteczne, 110 00:06:12,000 --> 00:06:15,000 po uruchomieniu ich połączenia oraz połączenia ich 111 00:06:15,000 --> 00:06:19,000 można zbudować wreszcie jako Rob zrobił w filmie listy końcu posortowane. 112 00:06:19,000 --> 00:06:22,000 >> Ale idea ta wykracza daleko poza sortowania. 113 00:06:22,000 --> 00:06:26,000 Jest to pomysł osadzony w programie zwanym rekursji 114 00:06:26,000 --> 00:06:29,000 idea, zgodnie z którą jesteś w programie, 115 00:06:29,000 --> 00:06:32,000 i rozwiązać jakiś problem zadzwonić siebie, 116 00:06:32,000 --> 00:06:36,000 lub umieścić w kontekście języków programowania jesteś funkcja, 117 00:06:36,000 --> 00:06:39,000 oraz w celu rozwiązania problemu, wywołanie funkcji pod 118 00:06:39,000 --> 00:06:42,000 znowu i znowu i znowu, ale funkcja 119 00:06:42,000 --> 00:06:44,000 nie może nazywać się nieskończenie wiele razy. 120 00:06:44,000 --> 00:06:47,000 Ostatecznie trzeba bottom out, by tak rzec, 121 00:06:47,000 --> 00:06:49,000 i jakieś zakodowane warunek podstawowy, który mówi: 122 00:06:49,000 --> 00:06:53,000 w tym momencie przestać nazywać się tak, że cały proces 123 00:06:53,000 --> 00:06:56,000 wreszcie faktycznie zatrzymać. 124 00:06:56,000 --> 00:06:58,000 Co to tak naprawdę znaczy, aby rekursja? 125 00:06:58,000 --> 00:07:01,000 >> Zobaczmy, czy możemy zrobić prosty, banalny przykład, powiedzmy, 126 00:07:01,000 --> 00:07:03,000 3 osoby mnie tutaj na scenie, jeśli ktoś jest wygodne. 127 00:07:03,000 --> 00:07:06,000 1, dalej w górę, 2 i 3. 128 00:07:06,000 --> 00:07:09,000 Jeśli 3 chcą przyjść tutaj. 129 00:07:09,000 --> 00:07:12,000 Jeśli chcesz stać obok mnie tutaj w linii, przypuszczam, że problem w kasie 130 00:07:12,000 --> 00:07:15,000 jest bardzo trywialnie policzyć ludzi, którzy są tutaj. 131 00:07:15,000 --> 00:07:18,000 Ale szczerze mówiąc, jestem zmęczony wszystkich tych przykładach liczenia. 132 00:07:18,000 --> 00:07:21,000 To zajmie trochę czasu, 1, 2, i kropka, kropka, kropka. 133 00:07:21,000 --> 00:07:23,000 To będzie trwać wiecznie. 134 00:07:23,000 --> 00:07:25,000 Wolałbym tylko punt ten problem w ogóle z pomocą-jak masz na imię? 135 00:07:25,000 --> 00:07:27,000 Sara. >> Sara, wszystko w porządku. 136 00:07:27,000 --> 00:07:29,000 Kelly. >> Kelly? 137 00:07:29,000 --> 00:07:31,000 >> Willy. >> Willy, Sara, Kelly i Willy. 138 00:07:31,000 --> 00:07:34,000 Teraz I zostały zadawane pytanie przez kogoś 139 00:07:34,000 --> 00:07:37,000 jak wiele osób się na tym etapie, a ja nie mam pojęcia. 140 00:07:37,000 --> 00:07:40,000 Jest to bardzo długa lista, a więc zamiast zamierzam zrobić trick. 141 00:07:40,000 --> 00:07:43,000 Zamierzam zwrócić się do osoby obok mnie zrobić większość prac, 142 00:07:43,000 --> 00:07:46,000 oraz że odbywa się po robi większość pracy 143 00:07:46,000 --> 00:07:49,000 Mam zamiar zrobić najmniejszą możliwą ilość pracy i po prostu dodać 1 144 00:07:49,000 --> 00:07:51,000 do tego, co jest jej odpowiedź, więc jedziemy. 145 00:07:51,000 --> 00:07:54,000 Poproszono mnie, ile osób jest na scenie. 146 00:07:54,000 --> 00:07:57,000 Ilu ludzi na scenie na lewo od ciebie? 147 00:07:57,000 --> 00:08:00,000 Lewo ode mnie? >> Dobra, ale nie oszukuj. 148 00:08:00,000 --> 00:08:04,000 To dobrze, to prawda, ale jeśli chcemy kontynuować tę logikę 149 00:08:04,000 --> 00:08:08,000 Załóżmy, że podobnie chcą punt ten problem z lewej Ciebie 150 00:08:08,000 --> 00:08:11,000 więc zamiast odpowiedzi bezpośrednio iść do przodu i po prostu przekazać złotówki. 151 00:08:11,000 --> 00:08:14,000 Och, jak wiele osób jest na lewo od mnie? 152 00:08:14,000 --> 00:08:16,000 Ile osób jest na lewo? 153 00:08:16,000 --> 00:08:18,000 1. 154 00:08:18,000 --> 00:08:27,000 [Śmiech] 155 00:08:27,000 --> 00:08:30,000 Ok, więc 0, więc co teraz Willy zrobił 156 00:08:30,000 --> 00:08:33,000 jest pan wrócił swoją odpowiedź w tym kierunku, mówiąc 0. 157 00:08:33,000 --> 00:08:36,000 Teraz, co należy zrobić? >> 1. 158 00:08:36,000 --> 00:08:39,000 Ok, więc jesteś 1, więc mówisz: "Dobra, mam zamiar dodać 1 159 00:08:39,000 --> 00:08:41,000 do tego, co było Ilość Willy ", więc 1 + 0. 160 00:08:41,000 --> 00:08:43,000 Jesteś już 1, więc odpowiedź na prawo jest teraz- 161 00:08:43,000 --> 00:08:45,000 1. >> A mój będzie 2. 162 00:08:45,000 --> 00:08:48,000 Dobra, więc bierzesz poprzednią odpowiedź 1, 163 00:08:48,000 --> 00:08:51,000 dodając minimalną ilość pracy, którą chcesz zrobić, co jest +1. 164 00:08:51,000 --> 00:08:55,000 Teraz masz 2, a następnie podaj mi jaka wartość? 165 00:08:55,000 --> 00:08:57,000 3, to znaczy, przepraszam, 2. 166 00:08:57,000 --> 00:08:59,000 Good. 167 00:08:59,000 --> 00:09:02,000 >> Cóż, mieliśmy 0 w lewo. 168 00:09:02,000 --> 00:09:05,000 Potem mieliśmy 1, a następnie dodajemy 2, 169 00:09:05,000 --> 00:09:07,000 a teraz jesteś wręczając mi numer 2, 170 00:09:07,000 --> 00:09:10,000 i tak mówię, dobra, +1, 3. 171 00:09:10,000 --> 00:09:13,000 Jest rzeczywiście 3 ludzi stojących obok mnie na tym etapie, 172 00:09:13,000 --> 00:09:16,000 więc mogliśmy oczywiście zrobił to bardzo liniowo, 173 00:09:16,000 --> 00:09:19,000 bardzo w oczywisty sposób, ale co tak naprawdę zrobić? 174 00:09:19,000 --> 00:09:21,000 Wzięliśmy problem wielkości 3 na początku. 175 00:09:21,000 --> 00:09:24,000 Następnie złamał go na problem o rozmiarze 2, 176 00:09:24,000 --> 00:09:27,000 to problem wielkości 1, a na końcu bazowym 177 00:09:27,000 --> 00:09:29,000 było naprawdę, oh, nie ma nikogo, 178 00:09:29,000 --> 00:09:33,000 w którym momencie Willy wrócił efektywnie zakodowane odpowiedź kilka razy, 179 00:09:33,000 --> 00:09:36,000 i drugi następnie przepuszcza się, przepuszcza się, przepuszcza się, 180 00:09:36,000 --> 00:09:39,000 , a następnie przez dodanie tej dodatkowej 1 jeden 181 00:09:39,000 --> 00:09:41,000 zaimplementowaliśmy tę podstawową ideę rekursji. 182 00:09:41,000 --> 00:09:44,000 >> Teraz, w tym przypadku nie miało to rozwiązania problemu 183 00:09:44,000 --> 00:09:46,000 dłużej skutecznie następnie widzieliśmy do tej pory. 184 00:09:46,000 --> 00:09:48,000 Ale pomyśl o algorytmach zrobiliśmy na scenie do tej pory. 185 00:09:48,000 --> 00:09:51,000 Mieliśmy 8 kartek na tablicy, 186 00:09:51,000 --> 00:09:55,000 na wideo, kiedy Sean szukał numerem 7, a co on naprawdę robi? 187 00:09:55,000 --> 00:09:58,000 Cóż, nie zrobił żadnego rodzaju dziel i rządź. 188 00:09:58,000 --> 00:10:01,000 Nie zrobił żadnego rodzaju rekursji. 189 00:10:01,000 --> 00:10:03,000 Raczej po prostu nie ten liniowy algorytm. 190 00:10:03,000 --> 00:10:07,000 Ale kiedy wprowadził ideę posortowanych numerów na etapie żyć w zeszłym tygodniu 191 00:10:07,000 --> 00:10:09,000 Następnie mieliśmy ten instynkt będzie na środku, 192 00:10:09,000 --> 00:10:13,000 W tym momencie mieliśmy mniejszą listę wielkości 4 lub inny wykaz wielkości 4, 193 00:10:13,000 --> 00:10:17,000 a następnie mieliśmy dokładnie ten sam problem, więc powtarzać, powtarzać, powtarzać. 194 00:10:17,000 --> 00:10:19,000 Innymi słowy, mamy recursed. 195 00:10:19,000 --> 00:10:24,000 Dziękuję bardzo do naszych 3 wolontariuszy tutaj wykazanie rekursji z nami. 196 00:10:24,000 --> 00:10:28,000 >> Zobaczymy, czy nie możemy tego teraz trochę więcej betonu, 197 00:10:28,000 --> 00:10:30,000 rozwiązania problemu, że ponownie możemy zrobić dość łatwo, 198 00:10:30,000 --> 00:10:34,000 ale będziemy używać go jako odskocznię do realizacji tego podstawowego pojęcia. 199 00:10:34,000 --> 00:10:37,000 Jeśli chcę, aby obliczyć sumowanie kilka numerów, 200 00:10:37,000 --> 00:10:39,000 na przykład, jeśli podajesz w liczbie 3, 201 00:10:39,000 --> 00:10:42,000 Chcę dać wam wartość sigma 3, 202 00:10:42,000 --> 00:10:46,000 to, że suma 3 + 2 + 0 1 +. 203 00:10:46,000 --> 00:10:48,000 Chcę wrócić odpowiedzi 6, 204 00:10:48,000 --> 00:10:51,000 więc będziemy realizować tę funkcję sigma, funkcja sumowania 205 00:10:51,000 --> 00:10:54,000 że znowu bierze na wejściu, a następnie zwraca sumowanie 206 00:10:54,000 --> 00:10:57,000 z tej liczby w dół do 0. 207 00:10:57,000 --> 00:10:59,000 Możemy to zrobić dość łatwo, prawda? 208 00:10:59,000 --> 00:11:01,000 Możemy to zrobić z pewnego rodzaju pętli struktury, 209 00:11:01,000 --> 00:11:04,000 więc pozwól mi iść do przodu i uzyskać to się zaczęło. 210 00:11:04,000 --> 00:11:07,000 >> Dołącz stdio.h. 211 00:11:07,000 --> 00:11:09,000 Pozwól sobie na główny do pracy tutaj. 212 00:11:09,000 --> 00:11:12,000 Ratujmy to jako sigma.c. 213 00:11:12,000 --> 00:11:14,000 Potem mam zamiar iść tutaj, i mam zamiar zadeklarować int n, 214 00:11:14,000 --> 00:11:18,000 i mam zamiar wykonać następujące czynności, podczas gdy użytkownik nie współpracuje. 215 00:11:18,000 --> 00:11:22,000 Gdy użytkownik nie dał mi liczbę dodatnią 216 00:11:22,000 --> 00:11:26,000 pozwól mi iść dalej i skłonić ich do n = getInt, 217 00:11:26,000 --> 00:11:28,000 i dam im kilka wskazówek co do tego, co robić, 218 00:11:28,000 --> 00:11:33,000 więc printf ("liczba całkowita dodatnia proszę"). 219 00:11:33,000 --> 00:11:39,000 Tylko coś stosunkowo proste jak to tak, że w momencie trafiliśmy linii 14 220 00:11:39,000 --> 00:11:42,000 teraz mamy dodatnią przypuszczalnie w n. 221 00:11:42,000 --> 00:11:44,000 >> Teraz coś z tym zrobić. 222 00:11:44,000 --> 00:11:50,000 Pozwólcie mi iść do przodu i obliczyć sumowanie, więc int suma = sigma (n). 223 00:11:50,000 --> 00:11:54,000 Sigma jest tylko podsumowanie, więc ja tylko piszę w hodowcy sposób. 224 00:11:54,000 --> 00:11:56,000 My po prostu nazwać to sigma tam. 225 00:11:56,000 --> 00:11:58,000 To suma, a teraz mam zamiar wydrukować wynik, 226 00:11:58,000 --> 00:12:08,000 printf ("suma jest% d \ n", suma). 227 00:12:08,000 --> 00:12:11,000 A potem wrócę 0 na dokładkę. 228 00:12:11,000 --> 00:12:15,000 Zrobiliśmy wszystko, że ten program wymaga oprócz interesującej części, 229 00:12:15,000 --> 00:12:18,000 które jest rzeczywiście sigma realizacji funkcji. 230 00:12:18,000 --> 00:12:22,000 >> Puść mnie tu na dole, i pozwól mi zadeklarować funkcji sigma. 231 00:12:22,000 --> 00:12:26,000 To musi się zmienną, która jest typu integer, 232 00:12:26,000 --> 00:12:30,000 i jaki typ danych chcę wrócić prawdopodobnie z sigma? 233 00:12:30,000 --> 00:12:34,000 Int, ponieważ chcę, aby dopasować moje oczekiwania na linii 15. 234 00:12:34,000 --> 00:12:37,000 Tu pozwól mi iść dalej i wdrożyć to 235 00:12:37,000 --> 00:12:41,000 w sposób bardzo prosty. 236 00:12:41,000 --> 00:12:45,000 >> Idziemy dalej i powiedzieć, int suma = 0, 237 00:12:45,000 --> 00:12:47,000 i teraz mam zamiar go mieć tutaj trochę dla pętli 238 00:12:47,000 --> 00:12:50,000 że zamierza powiedzieć coś takiego, 239 00:12:50,000 --> 00:13:01,000 for (int i = 0; i <= liczba; i + +) suma + = i. 240 00:13:01,000 --> 00:13:05,000 A potem mam zamiar wrócić sumę. 241 00:13:05,000 --> 00:13:07,000 Mogę to być realizowane na wiele sposobów. 242 00:13:07,000 --> 00:13:09,000 Mogłem użyć pętli while. 243 00:13:09,000 --> 00:13:11,000 Mogłem pominąć użyciu zmiennej sumy jeśli naprawdę chciał, 244 00:13:11,000 --> 00:13:15,000 ale w skrócie, po prostu mieć funkcję, że jeśli ja nie głupi deklaruje suma wynosi 0. 245 00:13:15,000 --> 00:13:18,000 Następnie przechodzi z 0 na górę przez liczbę, 246 00:13:18,000 --> 00:13:23,000 i na każdej iteracji dodaje, że obecne wartości do sumy, a następnie zwraca sumę. 247 00:13:23,000 --> 00:13:25,000 >> Teraz jest niewielka optymalizacja tutaj. 248 00:13:25,000 --> 00:13:29,000 Prawdopodobnie jest to zmarnowany krok, ale tak będzie. To jest w porządku teraz. 249 00:13:29,000 --> 00:13:32,000 Jesteśmy przynajmniej jest dokładny i będzie 0 całą drogę na górę. 250 00:13:32,000 --> 00:13:34,000 Nie bardzo ciężko i bardzo proste, 251 00:13:34,000 --> 00:13:37,000 , ale okazuje się, że przy pomocy funkcji sigma mamy same możliwości 252 00:13:37,000 --> 00:13:39,000 jak my tutaj, na scenie. 253 00:13:39,000 --> 00:13:42,000 Na scenie po prostu liczy ile osób było obok mnie, 254 00:13:42,000 --> 00:13:47,000 lecz jeśli chcemy policzyć 3 + 2 + 1 255 00:13:47,000 --> 00:13:51,000 na dół do 0 mogliśmy podobnie punt do funkcji 256 00:13:51,000 --> 00:13:55,000 że ja zamiast opisać jako rekurencyjne. 257 00:13:55,000 --> 00:13:57,000 Tu zróbmy szybkie sanity sprawdzić i upewnić się, że nie głupi. 258 00:13:57,000 --> 00:14:00,000 >> Wiem, że istnieje co najmniej jedna rzecz w tym programie, że zrobił źle. 259 00:14:00,000 --> 00:14:04,000 Gdy wciskamy enter mam zamiar uzyskać jakiekolwiek na mnie krzyczeć? 260 00:14:04,000 --> 00:14:06,000 Co ja mam być krzyknęła na o? 261 00:14:06,000 --> 00:14:11,000 Tak, zapomniałem o prototyp, więc używam funkcji o nazwie sigma na linii 15, 262 00:14:11,000 --> 00:14:16,000 ale to nie jest zadeklarowane do linii 22, więc najlepiej udać się tutaj aktywnie 263 00:14:16,000 --> 00:14:22,000 i oświadczam prototypu, i powiem int Sigma (int liczba), i to jest to. 264 00:14:22,000 --> 00:14:24,000 Jest realizowany na dole. 265 00:14:24,000 --> 00:14:27,000 >> Albo inny sposób mogę rozwiązać ten problem, 266 00:14:27,000 --> 00:14:30,000 Mogę przenieść funkcję tam, co nie jest złe, 267 00:14:30,000 --> 00:14:32,000 ale przynajmniej gdy twoje programy zaczynają się długo, szczerze mówiąc, 268 00:14:32,000 --> 00:14:35,000 Myślę, że jest jakaś wartość w mając zawsze na górze głównej 269 00:14:35,000 --> 00:14:38,000 tak, że w czytniku może otworzyć plik, a następnie od razu zobaczyć 270 00:14:38,000 --> 00:14:40,000 co program robi, bez konieczności wyszukiwania przez niego 271 00:14:40,000 --> 00:14:42,000 szukam tej głównej funkcji. 272 00:14:42,000 --> 00:14:49,000 Chodźmy do mojego okna terminala tutaj, spróbuj zrobić sigma sigma, 273 00:14:49,000 --> 00:14:51,000 i wkręca się tutaj. 274 00:14:51,000 --> 00:14:55,000 Niejawna deklaracja getInt funkcji oznacza Zapomniałem zrobić to, co jeszcze? 275 00:14:55,000 --> 00:14:57,000 [Niesłyszalne-uczeń] 276 00:14:57,000 --> 00:15:00,000 Dobra, więc najwyraźniej to częsty błąd, więc zróbmy to tu, 277 00:15:00,000 --> 00:15:04,000 cs50.h, a teraz wróćmy do mojego okna terminala. 278 00:15:04,000 --> 00:15:08,000 >> Ja wyczyścić ekran, a ja ponownie uruchomić aby sigma. 279 00:15:08,000 --> 00:15:11,000 Wydaje się, że skompilowany. Chciałbym teraz uruchomić sigma. 280 00:15:11,000 --> 00:15:15,000 Będę pisać w liczbie 3, a ja dostałem 6, więc nie rygorystyczna kontrola, 281 00:15:15,000 --> 00:15:18,000 ale przynajmniej wydaje się działać na pierwszy rzut oka, ale teraz niech zgrać go na kawałki, 282 00:15:18,000 --> 00:15:21,000 i niech faktycznie wykorzystują ideę rekursji, znowu, 283 00:15:21,000 --> 00:15:24,000 w kontekście bardzo prosty, tak aby w ciągu kilku tygodni " 284 00:15:24,000 --> 00:15:27,000 kiedy zaczynamy odkrywać hodowcy struktur danych niż macierze 285 00:15:27,000 --> 00:15:30,000 mamy kolejne narzędzie w zestaw narzędzi, z którym do 286 00:15:30,000 --> 00:15:33,000 manipulować tych struktur danych, jak zobaczymy. 287 00:15:33,000 --> 00:15:36,000 To jest podejście iteracyjne, pętla podejście. 288 00:15:36,000 --> 00:15:39,000 >> Pozwól mi zamiast teraz zrobić. 289 00:15:39,000 --> 00:15:44,000 Pozwól mi powiedzieć, że zamiast sumowanie liczby 290 00:15:44,000 --> 00:15:48,000 w dół do 0 to naprawdę to samo, co 291 00:15:48,000 --> 00:15:53,000 liczba + sigma (liczba - 1). 292 00:15:53,000 --> 00:15:57,000 Innymi słowy, tak jak na etapie I punted do każdego z ludzi obok mnie, 293 00:15:57,000 --> 00:16:00,000 a one z kolei przechowywane punting aż wreszcie najniższy na Willy'ego, 294 00:16:00,000 --> 00:16:03,000 który musiał zwrócić zakodowane odpowiedź jak 0. 295 00:16:03,000 --> 00:16:07,000 Tu teraz jesteśmy podobnie punting do sigma 296 00:16:07,000 --> 00:16:10,000 Funkcjonalność pierwotnie wywołana, ale klucz wiedza o 297 00:16:10,000 --> 00:16:12,000 jest to, że nie dzwonisz sigma identycznie. 298 00:16:12,000 --> 00:16:14,000 Nie jesteśmy przekazując n. 299 00:16:14,000 --> 00:16:17,000 Mamy jasno przekazując numer - 1, 300 00:16:17,000 --> 00:16:20,000 więc nieco mniejszy problem, nieco mniejszy problem. 301 00:16:20,000 --> 00:16:23,000 >> Niestety, nie dość rozwiązanie jest jeszcze, i przed naprawić 302 00:16:23,000 --> 00:16:26,000 co można by wyskoczyć tak oczywiste w niektórych z was 303 00:16:26,000 --> 00:16:28,000 pozwól mi iść do przodu i ponownie wykonać. 304 00:16:28,000 --> 00:16:30,000 Wydaje skompilować okay. 305 00:16:30,000 --> 00:16:32,000 Pozwól, że powtórka z 6 sigma. 306 00:16:32,000 --> 00:16:37,000 Oj, daj mi powtórka z 6 sigma. 307 00:16:37,000 --> 00:16:42,000 Widzieliśmy to już wcześniej, choć czasem przypadkowo ostatniego, jak również. 308 00:16:42,000 --> 00:16:48,000 Dlaczego pojawia się ten tajemniczy segmentation fault? Tak. 309 00:16:48,000 --> 00:16:50,000 [Niesłyszalne-uczeń] 310 00:16:50,000 --> 00:16:53,000 Nie ma wariant podstawowy, a bardziej szczegółowo, co prawdopodobnie się stało? 311 00:16:53,000 --> 00:16:58,000 To zachowanie objawem co? 312 00:16:58,000 --> 00:17:00,000 Powiedz to głośniej. 313 00:17:00,000 --> 00:17:02,000 [Niesłyszalne-uczeń] 314 00:17:02,000 --> 00:17:05,000 Jest to nieskończona pętla skutecznie, i problem z nieskończonej pętli 315 00:17:05,000 --> 00:17:08,000 gdy wiąże rekursję w tym przypadku, funkcja wywołująca się, 316 00:17:08,000 --> 00:17:10,000 , co dzieje się za każdym razem wywołać funkcję? 317 00:17:10,000 --> 00:17:13,000 No cóż, wracam do tego jak rozplanowany pamięci w komputerze. 318 00:17:13,000 --> 00:17:16,000 Powiedzieliśmy, że jest to fragment pamięci nazywa stack to na dole, 319 00:17:16,000 --> 00:17:19,000 i za każdym razem wywołać funkcja trochę więcej pamięci zostanie wprowadzone 320 00:17:19,000 --> 00:17:24,000 w tym tzw stosu zawierający określoną funkcję w lokalnych zmiennych lub parametrów, 321 00:17:24,000 --> 00:17:27,000 jeśli tak nazywa rozmowy sigma Sigma nazywa sigma 322 00:17:27,000 --> 00:17:29,000  wzywa sigma gdzie to mówi historia? 323 00:17:29,000 --> 00:17:31,000 >> Cóż, to w końcu przekroczenia całkowitej kwoty 324 00:17:31,000 --> 00:17:33,000 pamięci, że masz dostęp do komputera. 325 00:17:33,000 --> 00:17:37,000 Jesteś przekroczył segment Miałeś pozostać w, 326 00:17:37,000 --> 00:17:40,000 i masz ten błąd segmentacji, core po cenach dumpingowych, 327 00:17:40,000 --> 00:17:43,000 i co core dumped oznacza to, że mam teraz plik o nazwie rdzeń 328 00:17:43,000 --> 00:17:46,000 który jest plikiem zawierającym zer i jedynek 329 00:17:46,000 --> 00:17:49,000 faktycznie w przyszłości będzie diagnostycznie użyteczne. 330 00:17:49,000 --> 00:17:52,000 Jeśli nie jest to oczywiste dla Ciebie, gdzie jest błąd 331 00:17:52,000 --> 00:17:54,000 rzeczywiście można zrobić trochę analizy sądowej, by tak rzec, 332 00:17:54,000 --> 00:17:58,000 na ten plik zrzutu pamięci, które ponownie, jest po prostu cała masa zer i jedynek 333 00:17:58,000 --> 00:18:02,000 że w istocie reprezentuje stan programu w pamięci 334 00:18:02,000 --> 00:18:05,000 W chwili, gdy w ten sposób awarii. 335 00:18:05,000 --> 00:18:11,000 >> Fix jest to, że nie możemy po prostu ślepo wrócić sigma, 336 00:18:11,000 --> 00:18:14,000 liczba + sigma z nieco mniejszym problemem. 337 00:18:14,000 --> 00:18:16,000 Musimy mieć jakąś przypadku bazowego tutaj 338 00:18:16,000 --> 00:18:19,000 i co należy bazowym prawdopodobnie? 339 00:18:19,000 --> 00:18:22,000 [Niesłyszalne-uczeń] 340 00:18:22,000 --> 00:18:25,000 Ok, tak długo, jak liczba jest dodatnia powinna rzeczywiście powrót tego 341 00:18:25,000 --> 00:18:29,000 lub innymi słowy, jeśli liczba jest, powiedzmy, <= 0 do 342 00:18:29,000 --> 00:18:32,000 wiesz co, ja pójdę dalej i powrotu 0, 343 00:18:32,000 --> 00:18:36,000 podobnie jak Willy zrobił, a inny, mam zamiar iść do przodu 344 00:18:36,000 --> 00:18:41,000 i powrót tego, więc nie jest to znacznie krótszy 345 00:18:41,000 --> 00:18:44,000 niż iteracyjnej wersji, że podciął najpierw przy użyciu pętli for 346 00:18:44,000 --> 00:18:48,000 ale zauważ, że jest to rodzaj elegancji do niego. 347 00:18:48,000 --> 00:18:51,000 Zamiast zwracać pewną liczbę i wykonując wszystkie te matematyki 348 00:18:51,000 --> 00:18:54,000 i dodanie rzeczy z lokalnych zmiennych 349 00:18:54,000 --> 00:18:57,000 ty zamiast powiedzieć "Dobrze, jeśli jest to super łatwy problem, 350 00:18:57,000 --> 00:19:01,000 jak liczba jest <0, niech natychmiast powrócić 0 ". 351 00:19:01,000 --> 00:19:03,000 >> Nie będziemy się przejmować wspierających liczb ujemnych, 352 00:19:03,000 --> 00:19:05,000 więc mam zamiar ciężko kodem wartość 0. 353 00:19:05,000 --> 00:19:08,000 Ale poza tym, do realizacji tej idei zsumowanie 354 00:19:08,000 --> 00:19:11,000 Wszystkie te liczby razem można skutecznie wziąć mały kęs 355 00:19:11,000 --> 00:19:14,000 z tego problemu, podobnie jak my tutaj na scenie, 356 00:19:14,000 --> 00:19:18,000 Następnie reszta Punt problemu do następnej osoby, 357 00:19:18,000 --> 00:19:20,000 ale w tym przypadku osoba to samemu. 358 00:19:20,000 --> 00:19:22,000 To identycznie nazwany funkcji. 359 00:19:22,000 --> 00:19:25,000 Po prostu przekaż to mniejsze i mniejsze i mniejsze problemu za każdym razem, 360 00:19:25,000 --> 00:19:28,000 i mimo, że nie mamy dość sformalizowane rzeczy w kodzie tutaj 361 00:19:28,000 --> 00:19:33,000 to jest dokładnie to, co dzieje się w tydzień 0 z książki telefonicznej. 362 00:19:33,000 --> 00:19:36,000 To jest dokładnie to, co się dzieje w ostatnich tygodniach z Seanem 363 00:19:36,000 --> 00:19:39,000 i naszymi pokazami poszukiwania liczb. 364 00:19:39,000 --> 00:19:42,000 To biorąc problem i dzieląc go ponownie i ponownie. 365 00:19:42,000 --> 00:19:44,000 >> Innymi słowy, jest to sposób teraz przełożenia 366 00:19:44,000 --> 00:19:47,000 Konstrukt ten prawdziwy świat, to wyższy poziom konstrukt 367 00:19:47,000 --> 00:19:51,000 z dziel i rządź i robić coś znowu i znowu 368 00:19:51,000 --> 00:19:56,000 w kodzie, więc jest to coś ujrzymy znów w czasie. 369 00:19:56,000 --> 00:20:00,000 Teraz, jak na bok, jeśli jesteś nowy w rekursji należy przynajmniej rozumiem teraz 370 00:20:00,000 --> 00:20:02,000 dlaczego to jest śmieszne. 371 00:20:02,000 --> 00:20:05,000 Mam zamiar iść do google.com, 372 00:20:05,000 --> 00:20:17,000 i będę szukać pewnych sztuczek rekursji, enter. 373 00:20:17,000 --> 00:20:21,000 Poinformować osobę obok Ciebie, jeśli nie śmiali tylko teraz. 374 00:20:21,000 --> 00:20:23,000 Czy chodziło Ci o rekursji? 375 00:20:23,000 --> 00:20:25,000 Czy masz na myśli-ah, nie idziemy. 376 00:20:25,000 --> 00:20:28,000 Dobrze, że teraz jest reszta każdego. 377 00:20:28,000 --> 00:20:30,000 Trochę Pisanka osadzone gdzieś w Google. 378 00:20:30,000 --> 00:20:33,000 Tak na marginesie, jednym z ogniw możemy umieścić na stronie internetowej oczywiście 379 00:20:33,000 --> 00:20:36,000 na dziś jest tylko siatka ta z różnych algorytmów sortowania, 380 00:20:36,000 --> 00:20:39,000 niektóre z nich spojrzał na ostatni tydzień, ale to, co jest miłe o tej wizualizacji 381 00:20:39,000 --> 00:20:43,000 jak spróbować owinąć wokół różnych umysł rzeczy związanych z algorytmami 382 00:20:43,000 --> 00:20:46,000 wiedzą, że bardzo łatwo można teraz uruchomić z różnymi rodzajami wejść. 383 00:20:46,000 --> 00:20:50,000 Wejścia wszystkie odwrócone wejścia większości posortowane, wejścia losowo i tak dalej. 384 00:20:50,000 --> 00:20:53,000 Jak spróbować ponownie, odróżnić te rzeczy w twoim umyśle 385 00:20:53,000 --> 00:20:57,000 sobie sprawę, że na kursie URL strony internetowej na stronie Wykład 386 00:20:57,000 --> 00:21:00,000 może pomóc powód przez niektóre z nich. 387 00:21:00,000 --> 00:21:05,000 >> Dziś w końcu dostać się do rozwiązania tego problemu na chwilę z powrotem, 388 00:21:05,000 --> 00:21:08,000 co było, że ta funkcja wymiany po prostu nie działa, 389 00:21:08,000 --> 00:21:12,000 a co było podstawowym problemem z tym zamiana funkcji, 390 00:21:12,000 --> 00:21:15,000 Celem, który był znowu do wymiany wartości tu i tu 391 00:21:15,000 --> 00:21:17,000 takie, że tak się stanie? 392 00:21:17,000 --> 00:21:20,000 To faktycznie nie działa. Dlaczego? 393 00:21:20,000 --> 00:21:22,000 Tak. 394 00:21:22,000 --> 00:21:28,000 [Niesłyszalne-uczeń] 395 00:21:28,000 --> 00:21:31,000 Dokładnie wyjaśnienie tego bugginess 396 00:21:31,000 --> 00:21:34,000 po prostu dlatego, że podczas wywoływania funkcji w C 397 00:21:34,000 --> 00:21:38,000 i te funkcje przyjmują argumenty, jak i b tutaj 398 00:21:38,000 --> 00:21:42,000 jesteś przejazdem w kopii niezależnie od wartości czy prowadzimy dla tej funkcji. 399 00:21:42,000 --> 00:21:46,000 Nie dostarczamy oryginalne wartości siebie, 400 00:21:46,000 --> 00:21:49,000 więc widzieliśmy to w kontekście buggyc, 401 00:21:49,000 --> 00:21:52,000 buggy3.c, który wyglądał trochę coś takiego. 402 00:21:52,000 --> 00:21:57,000 >> Przypomnijmy, że X i Y było inicjowane 1 i 2, odpowiednio. 403 00:21:57,000 --> 00:21:59,000 Następnie wydrukować co oni. 404 00:21:59,000 --> 00:22:03,000 Potem twierdził, że byłem zamianę je poprzez wywołanie swap x, y. 405 00:22:03,000 --> 00:22:06,000 Ale problemem było to, że zamiana pracował, 406 00:22:06,000 --> 00:22:10,000 , ale tylko w zakresie wymiany samej funkcji. 407 00:22:10,000 --> 00:22:13,000 Jak tylko hit linii 40 Wartości te zamienione 408 00:22:13,000 --> 00:22:16,000 zostały wyrzucone i tak nic nie 409 00:22:16,000 --> 00:22:21,000 w pierwotnej funkcji głównego faktycznie zmienił się wcale, 410 00:22:21,000 --> 00:22:26,000 więc jeśli uważasz, że wtedy, co to wygląda z punktu widzenia naszej pamięci 411 00:22:26,000 --> 00:22:29,000 Jeśli to lewa strona płyty reprezentuje- 412 00:22:29,000 --> 00:22:33,000 i zrobię mój najlepszy dla wszystkich, aby zobaczyć, czy to lewa strona zarządu 413 00:22:33,000 --> 00:22:37,000 stanowi, powiedzmy, RAM, a stos będzie rosnąć w ten sposób, 414 00:22:37,000 --> 00:22:43,000 i wywołania funkcji, jak główny i główny ma 2 zmienne lokalne, X i Y, 415 00:22:43,000 --> 00:22:48,000 Opiszmy te jako x tutaj i niech opisują je jako y tu 416 00:22:48,000 --> 00:22:55,000 i postawmy w wartościach 1 i 2, więc tu jest głównym, 417 00:22:55,000 --> 00:22:58,000 i gdy główny wywołuje funkcja wymiany systemu operacyjnego 418 00:22:58,000 --> 00:23:02,000 daje Funkcja zamiany własnego pokos pamięci na stosie, 419 00:23:02,000 --> 00:23:04,000 własnej ramki na stosie, że tak powiem. 420 00:23:04,000 --> 00:23:08,000 Również przeznacza 32 bitów dla tych wskazówki. 421 00:23:08,000 --> 00:23:11,000 Zdarza się, zadzwonić do nich i b, ale to jest całkowicie arbitralne. 422 00:23:11,000 --> 00:23:13,000 To mogła być ich powołał, co chce, ale to, co dzieje się, gdy główny 423 00:23:13,000 --> 00:23:19,000 Swap połączenia jest potrzebny ten 1, umieszcza kopię tam, stawia kopię tam. 424 00:23:19,000 --> 00:23:23,000 >> Jest 1 inna zmienna lokalna w swap, choć nazywa co? Tmp. >> 425 00:23:23,000 --> 00:23:27,000 Tmp, więc pozwól mi dać sobie kolejne 32 bity Tutaj 426 00:23:27,000 --> 00:23:29,000 i co zrobić w tej funkcji? 427 00:23:29,000 --> 00:23:34,000 Powiedziałem int tmp ma, więc ma 1, więc zrobiłem to, kiedy ostatnio grał z tego przykładu. 428 00:23:34,000 --> 00:23:39,000 Potem dostaje b, więc b jest 2, tak teraz staje się to 2, 429 00:23:39,000 --> 00:23:42,000 i b otrzymuje się temperatury, to temperatura jest 1, 430 00:23:42,000 --> 00:23:44,000 tak teraz b staje to. 431 00:23:44,000 --> 00:23:46,000 To świetnie. Udało się. 432 00:23:46,000 --> 00:23:49,000 Ale następnie, gdy tylko funkcja zwróci 433 00:23:49,000 --> 00:23:52,000 swap pamięć skutecznie znika, tak, że może być użyte ponownie 434 00:23:52,000 --> 00:23:58,000 przez inną funkcję w przyszłości i głównym jest oczywiście całkowicie niezmieniona. 435 00:23:58,000 --> 00:24:00,000 Potrzebujemy sposób zasadniczy rozwiązania tego problemu, 436 00:24:00,000 --> 00:24:03,000 i dziś będziemy w końcu mieć to sposobem którym 437 00:24:03,000 --> 00:24:06,000 możemy wprowadzić coś, co nazywa wskaźnik. 438 00:24:06,000 --> 00:24:09,000 Okazuje się, że możemy rozwiązać ten problem 439 00:24:09,000 --> 00:24:12,000 nie przekazując kopie xiy 440 00:24:12,000 --> 00:24:18,000 ale zamiast tego, przekazując co, myślisz, z funkcją wymiany? 441 00:24:18,000 --> 00:24:20,000 Tak, a co z adresem? 442 00:24:20,000 --> 00:24:22,000 Tak naprawdę nie mówił o adresy w bardzo szczegółowo, 443 00:24:22,000 --> 00:24:25,000 ale jeśli ta tablica reprezentuje mojego komputera pamięć 444 00:24:25,000 --> 00:24:28,000 moglibyśmy z pewnością rozpocząć numerację bajtów w mojej pamięci 445 00:24:28,000 --> 00:24:31,000 i że to jest 1 bajtu, to bajt # 2, # 3 bajty, 446 00:24:31,000 --> 00:24:35,000 byte # 4, # byte ... 2 miliardy, jeśli mam 2 GB pamięci RAM, 447 00:24:35,000 --> 00:24:38,000 więc możemy z pewnością wymyślić jakiegoś niepożądanego numeracją 448 00:24:38,000 --> 00:24:41,000 dla wszystkich bajtów indywidualnych w mojej pamięci komputera. 449 00:24:41,000 --> 00:24:43,000 >> Co zrobić, jeśli zamiast kiedy dzwonię Swap 450 00:24:43,000 --> 00:24:47,000 zamiast przejść w kopii xiy 451 00:24:47,000 --> 00:24:51,000 dlaczego nie mogę zamiast przekazać w adresie X W tym 452 00:24:51,000 --> 00:24:55,000 adres y tutaj zasadniczo adres pocztowy 453 00:24:55,000 --> 00:24:59,000 xiy bo wtedy swap, jeśli on informowany 454 00:24:59,000 --> 00:25:01,000 z adresu w pamięci x i y, 455 00:25:01,000 --> 00:25:04,000 następnie swap, jeśli ćwiczyliśmy go trochę, 456 00:25:04,000 --> 00:25:07,000 mógłby potencjalnie prowadzić do tego adresu, by tak rzec, 457 00:25:07,000 --> 00:25:11,000 x, i zmień numer tam, a następnie jechać na adres y, 458 00:25:11,000 --> 00:25:16,000 zmienić numer tam, nawet jeśli nie jest właściwie coraz kopie tych wartości siebie, 459 00:25:16,000 --> 00:25:19,000 więc nawet rozmawialiśmy o tym, jako pamięć Main 460 00:25:19,000 --> 00:25:23,000 i to jako swap pamięć potężny i niebezpieczna część C 461 00:25:23,000 --> 00:25:28,000 jest to, że funkcja może dotykać dowolnego w pamięci komputera, 462 00:25:28,000 --> 00:25:32,000 i to jest potężny w których można zrobić bardzo fajne rzeczy z programów komputerowych w C. 463 00:25:32,000 --> 00:25:36,000 Jest to niebezpieczne, ponieważ można też zepsuć bardzo łatwo. 464 00:25:36,000 --> 00:25:39,000 W istocie, jednym z najbardziej popularnych sposobów programów te dni wykorzystać 465 00:25:39,000 --> 00:25:42,000 nadal jest na nie programista zrealizować 466 00:25:42,000 --> 00:25:45,000 że on lub ona jest zezwolenie na danych 467 00:25:45,000 --> 00:25:49,000 być zapisane w pamięci w miejscu, które nie jest przeznaczone. 468 00:25:49,000 --> 00:25:51,000 >> Na przykład stwierdza on szereg wielkości 10 469 00:25:51,000 --> 00:25:56,000 ale potem przypadkowo próbuje umieścić 11 bajtów do tej tablicy pamięci, 470 00:25:56,000 --> 00:25:59,000 i zaczynasz dotykać części pamięci, które nie są już ważne. 471 00:25:59,000 --> 00:26:02,000 Wystarczy kontekstowe, niektórzy z was wiedzą, że 472 00:26:02,000 --> 00:26:06,000 oprogramowanie często monituje o numerach seryjnych lub kluczy rejestracyjnych, 473 00:26:06,000 --> 00:26:08,000 Photoshop i Word oraz programy takie jak ten. 474 00:26:08,000 --> 00:26:12,000 Istnieją pęknięć, jak niektórzy z was wiedzą, w Internecie, gdzie możesz uruchomić mały program, 475 00:26:12,000 --> 00:26:14,000 i voila, nie więcej wniosek o numer seryjny. 476 00:26:14,000 --> 00:26:16,000 Jak to działa? 477 00:26:16,000 --> 00:26:21,000 W wielu przypadkach te rzeczy są po prostu znalezienie w komputerach 478 00:26:21,000 --> 00:26:24,000 segmenty tekstu w komputerze rzeczywistych zer i jedynek 479 00:26:24,000 --> 00:26:28,000 gdzie jest ta funkcja, gdy numer seryjny jest wymagany, 480 00:26:28,000 --> 00:26:31,000 i zastąpić tę przestrzeń, lub gdy program jest uruchomiony 481 00:26:31,000 --> 00:26:33,000 można dowiedzieć się, gdzie klucz jest przechowywany 482 00:26:33,000 --> 00:26:37,000 używając coś nazywa debugger, można złamać oprogramowania w ten sposób. 483 00:26:37,000 --> 00:26:40,000 To nie znaczy, że to jest nasz cel na najbliższe kilka dni, 484 00:26:40,000 --> 00:26:42,000 ale ma bardzo rzeczywiste konsekwencje. 485 00:26:42,000 --> 00:26:45,000 Zdarza się, że jeden do włączenia kradzież oprogramowania, 486 00:26:45,000 --> 00:26:47,000 ale jest również kompromis z całych maszyn. 487 00:26:47,000 --> 00:26:50,000 >> W rzeczywistości, gdy strony te dni wykorzystać 488 00:26:50,000 --> 00:26:53,000 i zagrożona i dane wyciekły i hasła zostały skradzione 489 00:26:53,000 --> 00:26:58,000 to bardzo często odnosi się do złego zarządzania czyjejś pamięci, 490 00:26:58,000 --> 00:27:01,000 lub, w przypadku baz danych, brak przewidywania 491 00:27:01,000 --> 00:27:03,000 kontradyktoryjności input, więc więcej o tym w najbliższych tygodniach, 492 00:27:03,000 --> 00:27:07,000 ale teraz po prostu zapowiedzią tego rodzaju uszkodzenia, które możesz zrobić 493 00:27:07,000 --> 00:27:11,000 przez nie do końca zrozumieć, jak to wszystko działa pod maską. 494 00:27:11,000 --> 00:27:14,000 Chodźmy o zrozumienie, dlaczego to jest zepsuty 495 00:27:14,000 --> 00:27:17,000 z narzędzia, które stają się coraz bardziej przydatne 496 00:27:17,000 --> 00:27:19,000 jak nasze programy zdobyć bardziej złożone. 497 00:27:19,000 --> 00:27:21,000 Do tej pory, kiedy miałem błąd w programie 498 00:27:21,000 --> 00:27:23,000 jak odeszłaś o debugowania? 499 00:27:23,000 --> 00:27:25,000 Co twoi techniki było do tej pory, czy nauczane przez TF 500 00:27:25,000 --> 00:27:27,000 lub po prostu samoukiem? 501 00:27:27,000 --> 00:27:29,000 [Student] printf. 502 00:27:29,000 --> 00:27:31,000 Printf, więc printf był prawdopodobnie Twój przyjaciel, że jeśli chcesz, aby zobaczyć 503 00:27:31,000 --> 00:27:33,000 co się dzieje wewnątrz programu 504 00:27:33,000 --> 00:27:36,000 wystarczy umieścić printf tutaj, printf tutaj, printf tutaj. 505 00:27:36,000 --> 00:27:38,000 Następnie uruchom go, i masz całą masę rzeczy na ekranie 506 00:27:38,000 --> 00:27:43,000 że można użyć, aby następnie wywnioskować, co właściwie dzieje źle w swoim programie. 507 00:27:43,000 --> 00:27:45,000 >> Printf bywa bardzo potężne rzeczy, 508 00:27:45,000 --> 00:27:47,000 ale to bardzo proces ręczny. 509 00:27:47,000 --> 00:27:49,000 Musisz umieścić printf tu printf tutaj 510 00:27:49,000 --> 00:27:51,000 a jeśli go umieścić wewnątrz pętli może dostać 100 linii 511 00:27:51,000 --> 00:27:53,000 produkcji, które następnie trzeba przesiać przez. 512 00:27:53,000 --> 00:27:58,000 To nie jest bardzo łatwy w obsłudze i interaktywny mechanizm debugowania programów jest, 513 00:27:58,000 --> 00:28:00,000 ale na szczęście istnieje alternatywne. 514 00:28:00,000 --> 00:28:03,000 Jest to program, na przykład, o nazwie GDB, GNU Debugger, 515 00:28:03,000 --> 00:28:06,000 który jest trochę arcane w jaki sposób z niego korzystać. 516 00:28:06,000 --> 00:28:08,000 Jest to trochę skomplikowane, ale szczerze mówiąc, 517 00:28:08,000 --> 00:28:11,000 jest to jedna z tych rzeczy, gdzie jeśli umieścisz w tym tygodniu i następnym 518 00:28:11,000 --> 00:28:14,000 dodatkowe godziny, aby zrozumieć coś jak GDB 519 00:28:14,000 --> 00:28:18,000 to zaoszczędzić prawdopodobnie kilkadziesiąt godzin, w dłuższej perspektywie, 520 00:28:18,000 --> 00:28:21,000 tak z tym, dam ci liścik, w jaki sposób ta rzecz działa. 521 00:28:21,000 --> 00:28:23,000 >> Jestem w moim oknie terminala. 522 00:28:23,000 --> 00:28:26,000 Pozwólcie mi iść do przodu i skompilować ten program, buggy3. 523 00:28:26,000 --> 00:28:28,000 Jest już aktualne. 524 00:28:28,000 --> 00:28:31,000 Pozwól mi go uruchomić tak jak zrobiliśmy z powrotem podczas, i rzeczywiście, gdy jest uszkodzony. 525 00:28:31,000 --> 00:28:34,000 Ale dlaczego tak jest? Może spieprzyłem funkcję wymiany. 526 00:28:34,000 --> 00:28:37,000 Może to i b. Nie jestem dość porusza nimi w pełnym zakresie. 527 00:28:37,000 --> 00:28:39,000 Pozwólcie mi iść do przodu i robić. 528 00:28:39,000 --> 00:28:43,000 Zamiast po prostu uruchomić buggy3 pozwól zamiast uruchomić ten GDB programu, 529 00:28:43,000 --> 00:28:48,000 i mam zamiar powiedzieć to uruchomić buggy3, 530 00:28:48,000 --> 00:28:52,000 i mam zamiar dołączyć argument wiersza polecenia,-tui, 531 00:28:52,000 --> 00:28:55,000 a my umieścić to w przyszłości do problemów w ciemno przypominają. 532 00:28:55,000 --> 00:28:57,000 A teraz to czarno-biały interfejs pojawił się, że znów 533 00:28:57,000 --> 00:28:59,000 jest trochę przytłaczające w pierwszym, bo to wszystko jest 534 00:28:59,000 --> 00:29:02,000 Informacja o gwarancji na dół, ale przynajmniej coś jest znajome. 535 00:29:02,000 --> 00:29:04,000 W górnej części okna jest mojego aktualnego kodu, 536 00:29:04,000 --> 00:29:08,000 i jeśli mogę przewinąć tutaj pozwolę sobie przejść do samej górze moim pliku 537 00:29:08,000 --> 00:29:11,000 i rzeczywiście, nie buggy3.c i zauważ, w dolnej części okna 538 00:29:11,000 --> 00:29:13,000 Mam ten GDB monitu. 539 00:29:13,000 --> 00:29:16,000 >> To nie jest taki sam jak mój normalny John Harvard zachęty. 540 00:29:16,000 --> 00:29:19,000 Jest to szybka, że ​​się dzieje, żebym mógł kontrolować GDB. 541 00:29:19,000 --> 00:29:21,000 GDB to debugger. 542 00:29:21,000 --> 00:29:24,000 Debugger to program, który pozwala przejść przez 543 00:29:24,000 --> 00:29:27,000 wykonanie linii programowej przez linia po linii, 544 00:29:27,000 --> 00:29:30,000 po drodze robi wszystko co chcesz do programu, 545 00:29:30,000 --> 00:29:33,000 nawet wywołanie funkcji, lub patrząc, co ważniejsze, 546 00:29:33,000 --> 00:29:35,000 W różnych zmiennej wartości. 547 00:29:35,000 --> 00:29:37,000 Idziemy naprzód i to zrobić. 548 00:29:37,000 --> 00:29:40,000 Mam zamiar iść do przodu, a następnie wpisz w biegu na polecenia gdb, 549 00:29:40,000 --> 00:29:43,000 więc zauważyć, na dole po lewej stronie ekranu mam wpisane uruchomienia, 550 00:29:43,000 --> 00:29:45,000 i mam wcisnąć klawisz enter, i co z tego? 551 00:29:45,000 --> 00:29:50,000 To dosłownie pobiegł mój program, ale w rzeczywistości nie widać wiele dalej tutaj 552 00:29:50,000 --> 00:29:55,000 bo nie rzeczywiście powiedział debugera 553 00:29:55,000 --> 00:29:57,000 wstrzymać w określonym momencie. 554 00:29:57,000 --> 00:29:59,000 Wpisując run uruchamia program. 555 00:29:59,000 --> 00:30:01,000 I właściwie nie widzę. I nie można manipulować. 556 00:30:01,000 --> 00:30:03,000 >> Zamiast tego pozwól mi to zrobić. 557 00:30:03,000 --> 00:30:08,000 W tym wierszu GDB pozwól zamiast wpisać przerwę, enter. 558 00:30:08,000 --> 00:30:10,000 To nie jest to, co chciałem napisać. 559 00:30:10,000 --> 00:30:13,000 Załóżmy, zamiast wpisać przerwa main. 560 00:30:13,000 --> 00:30:15,000 Innymi słowy, chcę ustawić coś zwane przerwania, 561 00:30:15,000 --> 00:30:18,000 która jest trafnie nazwany, ponieważ będzie przerwa lub pauza 562 00:30:18,000 --> 00:30:21,000 Realizacja programu w tym konkretnym miejscu. 563 00:30:21,000 --> 00:30:23,000 Main to nazwa mojej funkcji. 564 00:30:23,000 --> 00:30:25,000 Zauważ, że GDB jest bardzo pomysłowe. 565 00:30:25,000 --> 00:30:28,000 To zorientowali się, że dzieje się z głównym rozpocząć mniej więcej na linii 18 566 00:30:28,000 --> 00:30:32,000 z buggy3.c, a następnie zauważyć tutaj, w lewym górnym rogu 567 00:30:32,000 --> 00:30:34,000 b + jest tuż obok linii 18. 568 00:30:34,000 --> 00:30:38,000 To się przypominając mi, że mam ustawić punkt przerwania na linii 18. 569 00:30:38,000 --> 00:30:42,000 Tym razem po wpisaniu bieg, zamierzam uruchomić mój program 570 00:30:42,000 --> 00:30:45,000 aż trafi tego przerwania, 571 00:30:45,000 --> 00:30:48,000 więc program zatrzyma się na mnie na linii 18. 572 00:30:48,000 --> 00:30:50,000 Zaczynamy, biegać. 573 00:30:50,000 --> 00:30:53,000 Wydaje się, że nic nie stało, ale zauważ, w lewym dolnym 574 00:30:53,000 --> 00:30:58,000 uruchamiania programu, buggy3, breakpoint 1 w głównym na linii buggy3.c 18. 575 00:30:58,000 --> 00:31:00,000 Co mogę teraz zrobić? 576 00:31:00,000 --> 00:31:03,000 >> Zauważ, mogę zacząć pisać takie rzeczy jak drukowanej, 577 00:31:03,000 --> 00:31:08,000 nie printf, x druku, a teraz, że to dziwne. 578 00:31:08,000 --> 00:31:11,000 $ 1 to tylko ciekawość, jak zobaczymy 579 00:31:11,000 --> 00:31:14,000 za każdym razem drukować coś dostać nowy $ value. 580 00:31:14,000 --> 00:31:18,000 To jest tak, że można odwołać się do poprzednich wartości tylko w przypadku, 581 00:31:18,000 --> 00:31:21,000 ale teraz to, co mi mówi print jest wartość x w tym momencie w historii 582 00:31:21,000 --> 00:31:26,000 jest najwyraźniej 134514032. 583 00:31:26,000 --> 00:31:29,000 Co? Gdzie to jeszcze pochodzi? 584 00:31:29,000 --> 00:31:31,000 [Niesłyszalne-uczeń] 585 00:31:31,000 --> 00:31:34,000 Rzeczywiście, jest to, co my nazywamy wartość śmieci, a my nie rozmawialiśmy o tym jeszcze, 586 00:31:34,000 --> 00:31:37,000 ale dlatego, że należy zainicjować zmienne 587 00:31:37,000 --> 00:31:40,000 jest oczywiście tak, że mają jakąś wartość, że chcesz je mieć. 588 00:31:40,000 --> 00:31:44,000 Ale połów jest przypomnieć, że można zadeklarować zmienne 589 00:31:44,000 --> 00:31:46,000 jak ja przed chwilą w moim przykładzie sigma 590 00:31:46,000 --> 00:31:48,000 bez faktycznie dając im wartość. 591 00:31:48,000 --> 00:31:50,000 Przypomnijmy, co zrobiłem tutaj w sigma. 592 00:31:50,000 --> 00:31:52,000 I oświadczył n, ale jaka wartość dałem go? 593 00:31:52,000 --> 00:31:56,000 Brak, ponieważ wiedziałem, że w ciągu najbliższych kilku liniach 594 00:31:56,000 --> 00:31:59,000 GetInt zajmie problemu wprowadzenie wartości wewnątrz n. 595 00:31:59,000 --> 00:32:02,000 >> Ale w tym momencie w historii linii 11 596 00:32:02,000 --> 00:32:05,000 i 12 linii i linia 13 i linia 14 597 00:32:05,000 --> 00:32:08,000 Przez te kilka linii, co jest wartością n? 598 00:32:08,000 --> 00:32:10,000 W C po prostu nie wiem. 599 00:32:10,000 --> 00:32:14,000 Jest to generalnie niektóre wartości śmieci, niektóre całkowicie losowy numer 600 00:32:14,000 --> 00:32:17,000 Pozostaje się zasadniczo z jakiejś poprzedniej funkcji 601 00:32:17,000 --> 00:32:21,000 został uruchomiony, tak jak twój program działa 602 00:32:21,000 --> 00:32:24,000 Przypomnijmy, że funkcja pobiera funkcja, funkcja, funkcja. 603 00:32:24,000 --> 00:32:27,000 Wszystkie te klatki się umieścić na pamięci, a następnie powrót tych funkcji, 604 00:32:27,000 --> 00:32:31,000 i tak jak sugerowałem gumką ich pamięć jest ostatecznie ponownie używać. 605 00:32:31,000 --> 00:32:37,000 Cóż, tak się składa, że ​​zmienna x w tym programie 606 00:32:37,000 --> 00:32:41,000 Wydaje się, że zawierała jakąś wartość śmieci jak 134514032 607 00:32:41,000 --> 00:32:44,000 z jakiejś poprzedniej funkcji, a nie taki, który napisałem. 608 00:32:44,000 --> 00:32:47,000 To może być coś, co przychodzi skutecznie z systemem operacyjnym, 609 00:32:47,000 --> 00:32:49,000 niektórych funkcji pod maską. 610 00:32:49,000 --> 00:32:52,000 >> Dobrze, że jest w porządku, ale niech teraz przejść do następnego wiersza. 611 00:32:52,000 --> 00:32:55,000 Jeśli napiszę "next" w moim wierszu GDB i wciskamy Enter, 612 00:32:55,000 --> 00:32:58,000 zauważyć, że podkreślając ruchy w dół do linii 19, 613 00:32:58,000 --> 00:33:01,000 ale logiczną implikacją jest, że linia 18 614 00:33:01,000 --> 00:33:06,000 Obecnie zakończeniu wykonywania, więc jeśli znowu wpisać "print x" 615 00:33:06,000 --> 00:33:10,000 Należy teraz widzę 1, i rzeczywiście, mam. 616 00:33:10,000 --> 00:33:14,000 Znowu $ rzeczy jest sposób GDB przypomnienia 617 00:33:14,000 --> 00:33:17,000 co historia wydruków to, że zrobiłeś. 618 00:33:17,000 --> 00:33:21,000 Teraz pozwól mi iść do przodu i wydrukować y, i rzeczywiście, y pewne szalone napięcie, jak również, 619 00:33:21,000 --> 00:33:24,000 ale to nic wielkiego, bo w linii 19 mamy zamiar przypisać 620 00:33:24,000 --> 00:33:27,000 wartość 2, więc pozwól mi wpisać "Dalej". 621 00:33:27,000 --> 00:33:29,000 A teraz jesteśmy na printf linii. 622 00:33:29,000 --> 00:33:31,000 Pozwól mi zrobić X drukowania. 623 00:33:31,000 --> 00:33:34,000 Pozwól mi zrobić r drukowania. Szczerze mówiąc, jestem już trochę zmęczony drukowania to. 624 00:33:34,000 --> 00:33:38,000 Pozwól, że zamiast wpisywać "display X" i "Y Wskaźnik", 625 00:33:38,000 --> 00:33:41,000 i teraz za każdym razem wpisać polecenie w przyszłości 626 00:33:41,000 --> 00:33:45,000 I będzie przypominał tego, co jest x, a y, co to X i Y, co jest x i y. 627 00:33:45,000 --> 00:33:48,000 >> Nie mogę również, jak z boku, typu "mieszkańców informacji." 628 00:33:48,000 --> 00:33:50,000 Info jest specjalne polecenie. 629 00:33:50,000 --> 00:33:52,000 Mieszkańców oznacza to pokazuje mi zmiennych lokalnych. 630 00:33:52,000 --> 00:33:55,000 Tylko w przypadku, zapomnieć lub jest to szalone, skomplikowana funkcja 631 00:33:55,000 --> 00:33:57,000 że ja lub ktoś inny napisał miejscowi informacji powie 632 00:33:57,000 --> 00:34:00,000 jakie są wszystkie zmienne lokalne wewnątrz tego lokalnego funkcji 633 00:34:00,000 --> 00:34:03,000 które mogą Ci zależy, jeśli chcesz grzebać. 634 00:34:03,000 --> 00:34:07,000 Teraz printf ma się wykonać, więc pozwól mi iść do przodu i po prostu wpisz "next". 635 00:34:07,000 --> 00:34:10,000 Bo jesteśmy w tym środowisku nie jesteśmy rzeczywiście widząc go 636 00:34:10,000 --> 00:34:14,000 wykonać tu, ale zauważ, robi trochę zniekształcone tutaj. 637 00:34:14,000 --> 00:34:17,000 Zauważmy jednak, to nadrzędne ekran tam, 638 00:34:17,000 --> 00:34:21,000 więc to nie doskonały program tutaj jest, ale to jest w porządku, bo zawsze mogę Kapsa 639 00:34:21,000 --> 00:34:23,000 przy wydruku, jeśli chcę. 640 00:34:23,000 --> 00:34:26,000 >> Pozwól mi napisać następny raz, a teraz znajduje się interesująca część. 641 00:34:26,000 --> 00:34:29,000 W tym momencie w historii y oznacza 2, a x oznacza liczbę 1, 642 00:34:29,000 --> 00:34:32,000 sugerowane tu i ponownie, 643 00:34:32,000 --> 00:34:35,000 Powodem tego jest automatycznie wyświetla teraz jest, ponieważ użyto polecenia 644 00:34:35,000 --> 00:34:40,000 x ekran i wyświetlacz y, więc chwila wpisuję obok 645 00:34:40,000 --> 00:34:43,000 teoretycznie xiy powinny stać zamienione. 646 00:34:43,000 --> 00:34:45,000 Teraz już wiemy, że nie będzie to przypadek, 647 00:34:45,000 --> 00:34:49,000 ale zobaczymy za chwilę, jak możemy nurkować głębiej, aby dowiedzieć się, dlaczego tak jest prawda. 648 00:34:49,000 --> 00:34:54,000 Dalej, niestety, r 2 i jest w dalszym ciągu jeszcze x 1, i może nawet i potwierdzić. 649 00:34:54,000 --> 00:34:56,000 Print x, y print. 650 00:34:56,000 --> 00:34:59,000 Rzeczywiście, nie wymieniając faktycznie się stało, więc zacznijmy od tego. 651 00:34:59,000 --> 00:35:01,000 Oczywiście Swap jest zepsuty. 652 00:35:01,000 --> 00:35:04,000 Załóżmy, zamiast wpisać "run" ponownie. 653 00:35:04,000 --> 00:35:07,000 Pozwólcie mi powiedzieć, tak, chcę, aby uruchomić go ponownie od początku, enter. 654 00:35:07,000 --> 00:35:09,000 >> Teraz jestem z powrotem na linii 18. 655 00:35:09,000 --> 00:35:11,000 Zauważcie, x i y są wartościami śmieci ponownie. 656 00:35:11,000 --> 00:35:15,000 Dalej, dalej, dalej, dalej. 657 00:35:15,000 --> 00:35:17,000 Jeśli znudzi mogę też po prostu wpisać n dla następnego. 658 00:35:17,000 --> 00:35:21,000 Możesz skrócić go do najkrótszym sekwencję znaków. 659 00:35:21,000 --> 00:35:23,000 Swap jest teraz zepsuty. 660 00:35:23,000 --> 00:35:25,000 Miejmy nurkowania w, więc zamiast wpisywać następny, 661 00:35:25,000 --> 00:35:30,000 teraz mam zamiar napisać krok tak, że jestem krok wewnątrz tej funkcji 662 00:35:30,000 --> 00:35:33,000 tak, że można przez nie przejść, więc uderzyłem krok i wpisz. 663 00:35:33,000 --> 00:35:37,000 Zauważ, że skoki podkreślające się niżej w moim programie do linii 36. 664 00:35:37,000 --> 00:35:39,000 Teraz jakie są zmienne lokalne? 665 00:35:39,000 --> 00:35:41,000 Miejscowi info. 666 00:35:41,000 --> 00:35:43,000 Nic jeszcze tylko dlatego, że nie dotarłeś do tej linii, 667 00:35:43,000 --> 00:35:47,000 więc niech śmiało powiedzieć "następny". 668 00:35:47,000 --> 00:35:50,000 Teraz wydaje się mieć TMP, TMP druku. 669 00:35:50,000 --> 00:35:52,000 Wartość śmieci, prawda? Myślę, że tak. 670 00:35:52,000 --> 00:35:55,000 Jak o drukowanie, drukowanie B, 1 i 2? 671 00:35:55,000 --> 00:35:58,000 W momencie, jak tylko ponownie wpisać następny 672 00:35:58,000 --> 00:36:02,000 tmp ma zamiar wziąć na wartości 1, miejmy nadzieję, 673 00:36:02,000 --> 00:36:05,000 bo tmp zostanie przypisana wartość. 674 00:36:05,000 --> 00:36:08,000 >> Teraz zróbmy wydrukować, B PRINT, 675 00:36:08,000 --> 00:36:11,000 ale teraz wydrukować tmp, a to rzeczywiście 1. 676 00:36:11,000 --> 00:36:14,000 Pozwól mi zrobić. Pozwól mi zrobić. 677 00:36:14,000 --> 00:36:16,000 Skończyłem funkcję wymiany. 678 00:36:16,000 --> 00:36:19,000 Jestem jeszcze w jej wnętrzu w linii 40, więc pozwól mi wydrukować, 679 00:36:19,000 --> 00:36:22,000 print b, i nie obchodzi mnie, co tmp jest. 680 00:36:22,000 --> 00:36:27,000 Wygląda na to, swap jest poprawne, jeśli chodzi o zamianę a i b. 681 00:36:27,000 --> 00:36:31,000 Ale gdybym teraz wpisać obok, I wrócić do linii 25, 682 00:36:31,000 --> 00:36:34,000 i oczywiście, jeśli wpisz x i y druku 683 00:36:34,000 --> 00:36:38,000 oni nadal bez zmian, więc nie rozwiązaniu problemu. 684 00:36:38,000 --> 00:36:41,000 Ale teraz może diagnostycznie z tym programem GDB 685 00:36:41,000 --> 00:36:44,000 mamy przynajmniej zdobyć jeden krok bliżej do zrozumienia 686 00:36:44,000 --> 00:36:47,000 co się dzieje źle bez ściółki nasz kod umieszczając printf tutaj 687 00:36:47,000 --> 00:36:50,000 printf tutaj, printf tutaj, a następnie uruchomić go ponownie i ponownie 688 00:36:50,000 --> 00:36:52,000 próbuje dowiedzieć się, co się dzieje źle. 689 00:36:52,000 --> 00:36:55,000 >> Mam zamiar iść do przodu i wyjść z tego w ogóle z wyjść. 690 00:36:55,000 --> 00:36:57,000 To będzie wtedy powiedzieć: "Przestań tak?" Tak. 691 00:36:57,000 --> 00:37:00,000 Teraz jestem z powrotem w moim normalnym polecenia, a ja zrobić za pomocą GDB. 692 00:37:00,000 --> 00:37:03,000 Tak na marginesie, nie musisz korzystać z tego-tui banderą. 693 00:37:03,000 --> 00:37:07,000 W rzeczywistości, jeśli pominąć go dostać w zasadzie dolną połowę ekranu. 694 00:37:07,000 --> 00:37:11,000 Jeśli następnie wpisz przerwa głównym, a następnie uruchom 695 00:37:11,000 --> 00:37:15,000 Wciąż mogę uruchomić mój program, ale co to będzie zrobić, to bardziej tekstowo 696 00:37:15,000 --> 00:37:18,000 Tylko pokaż mi jednego z posiadanych linii na raz. 697 00:37:18,000 --> 00:37:21,000 -Tui, tekst interfejsu użytkownika, 698 00:37:21,000 --> 00:37:25,000 po prostu pokazuje, że bardziej programu na raz, co jest prawdopodobnie nieco koncepcyjnie prostsze. 699 00:37:25,000 --> 00:37:27,000 Ale rzeczywiście, można po prostu robić dalej, dalej, dalej, 700 00:37:27,000 --> 00:37:30,000 i mam zamiar zobaczyć jeden wiersz na raz, a jeśli naprawdę chcesz zobaczyć, co się dzieje 701 00:37:30,000 --> 00:37:35,000 Mogę pisać listy i zobacz całą masę sąsiednich linii. 702 00:37:35,000 --> 00:37:39,000 >> Jest film, że prosiłem, aby obserwować problemu ustawia 3 703 00:37:39,000 --> 00:37:43,000 w którym Nate opisuje niektóre zawiłości GDB, 704 00:37:43,000 --> 00:37:46,000 i to jest jedna z tych rzeczy, szczerze mówiąc, gdzie niektóre nietrywialne procent z was 705 00:37:46,000 --> 00:37:49,000 nigdy nie dotykaj GDB, oraz że będzie źle 706 00:37:49,000 --> 00:37:53,000 bo dosłownie skończy się spędzać więcej czasu później w tym semestrze 707 00:37:53,000 --> 00:37:56,000 ścigających błędy to byś jeśli umieścić w tym pół godziny / godzina 708 00:37:56,000 --> 00:38:00,000 w tym tygodniu, a następnie uczenie się komfortowo z GDB. 709 00:38:00,000 --> 00:38:02,000 Printf był twoim przyjacielem. 710 00:38:02,000 --> 00:38:05,000 GDB powinien być twoim przyjacielem. 711 00:38:05,000 --> 00:38:08,000 >> Wszelkie pytania dotyczące GDB? 712 00:38:08,000 --> 00:38:12,000 A oto krótka lista niektórych poleceń najpotężniejszych i najbardziej użyteczne. 713 00:38:12,000 --> 00:38:15,000 Tak. >> Czy można wydrukować ciąg? 714 00:38:15,000 --> 00:38:17,000 Można wydrukować ciąg? Absolutnie. 715 00:38:17,000 --> 00:38:19,000 To nie musi być tylko liczbami całkowitymi. 716 00:38:19,000 --> 00:38:22,000 Jeżeli zmienna s jest ciągiem znaków, po prostu wpisz w s druku. 717 00:38:22,000 --> 00:38:24,000 To pokaże, co to zmienna string jest. 718 00:38:24,000 --> 00:38:26,000 [Niesłyszalne-uczeń] 719 00:38:26,000 --> 00:38:28,000 To daje adres i sam ciąg. 720 00:38:28,000 --> 00:38:32,000 Pokaże wam. 721 00:38:32,000 --> 00:38:34,000 I ostatnia rzecz, to, że są to dobrze wiedzieć, też. 722 00:38:34,000 --> 00:38:37,000 Backtrace i ramki, pozwól mi zanurkować w to ostatni raz, 723 00:38:37,000 --> 00:38:39,000 dokładnie taki sam program, z GDB. 724 00:38:39,000 --> 00:38:44,000 Pozwólcie mi iść do przodu i uruchamiania tekstową wersję interfejsu użytkownika, 725 00:38:44,000 --> 00:38:46,000 złamać main. 726 00:38:46,000 --> 00:38:49,000 Pozwól mi iść dalej i uruchomić ponownie. Oto jestem. 727 00:38:49,000 --> 00:38:55,000 Teraz pozwól mi iść dalej, następny, następny, następny, następny krok, wprowadź. 728 00:38:55,000 --> 00:39:00,000 >> A teraz załóżmy, że jestem teraz w swapu celowo, ale jestem jak "Cholera, co wartość x?" 729 00:39:00,000 --> 00:39:02,000 Nie mogę x więcej. 730 00:39:02,000 --> 00:39:05,000 Nie mogę y bo nie są w zakresie. 731 00:39:05,000 --> 00:39:07,000 Oni nie są w kontekście, ale nie ma problemu. 732 00:39:07,000 --> 00:39:09,000 Mogę pisać backtrace. 733 00:39:09,000 --> 00:39:13,000 To pokazuje mi wszystkie funkcje, które zostały wykonane do tej chwili. 734 00:39:13,000 --> 00:39:16,000 Zauważ, że jeden na dole, main, linii z głównym 735 00:39:16,000 --> 00:39:18,000 jest na spodzie obrazu o naszego. 736 00:39:18,000 --> 00:39:22,000 Fakt, że swap jest nad nią linii z Swap jest nad nim w pamięć, 737 00:39:22,000 --> 00:39:26,000 i jeśli chcę wrócić do głównego tymczasowo mogę powiedzieć "rama". 738 00:39:26,000 --> 00:39:30,000 Jaki numer? Main jest frame # 1. 739 00:39:30,000 --> 00:39:32,000 Mam zamiar iść do przodu i powiedzieć "Frame 1". 740 00:39:32,000 --> 00:39:36,000 >> Teraz jestem z powrotem w głównym i wydrukować x, a mogę drukować y, 741 00:39:36,000 --> 00:39:40,000 ale nie można wydrukować lub b. 742 00:39:40,000 --> 00:39:43,000 Ale mogę, jeśli powiem: "Dobra, czekaj. Gdzie Swap?" 743 00:39:43,000 --> 00:39:46,000 Pozwól mi iść dalej i powiedzieć "0 klatek." 744 00:39:46,000 --> 00:39:48,000 Teraz jestem z powrotem tam, gdzie chcę być, i jak na bok, 745 00:39:48,000 --> 00:39:52,000 tam też inne polecenia, jak jeśli jesteś naprawdę nudzi pisać następny, następny, następny, następny, 746 00:39:52,000 --> 00:39:56,000 można generalnie mówi "obok 10" i że będzie przejście przez kolejne 10 linii. 747 00:39:56,000 --> 00:39:59,000 Można również napisać "kontynuować", kiedy naprawdę się dość intensyfikacji przez nią. 748 00:39:59,000 --> 00:40:05,000 Nadal będzie uruchomić program bez przerwy, aż nie natrafi na kolejny punkt przerwania, 749 00:40:05,000 --> 00:40:07,000 czy w pętli lub niżej w programie. 750 00:40:07,000 --> 00:40:11,000 >> W tym przypadku mamy nadal do końca, a program zakończył się normalnie. 751 00:40:11,000 --> 00:40:13,000 To fantazyjny sposób, gorszy proces. 752 00:40:13,000 --> 00:40:16,000 Tylko program zakończył się normalnie. 753 00:40:16,000 --> 00:40:24,000 Więcej na ten temat w filmie i debugowania sesji przyjść. 754 00:40:24,000 --> 00:40:26,000 To było dużo. 755 00:40:26,000 --> 00:40:35,000 Weźmy naszą 5-minutową przerwę, tutaj, i wrócimy z kodowanym i plików. 756 00:40:35,000 --> 00:40:38,000 >> Jeśli zanurkował w tym tygodniu już Pset 757 00:40:38,000 --> 00:40:41,000 będziesz wiedzieć, że używamy w kodzie dystrybucji, 758 00:40:41,000 --> 00:40:45,000 kod źródłowy, że oferujemy Państwu jako punkt wyjścia, kilka nowych technik. 759 00:40:45,000 --> 00:40:50,000 W szczególności, wprowadził nowe słowo kluczowe struct nazwie, na konstrukcji, 760 00:40:50,000 --> 00:40:53,000 tak, że możemy tworzyć własne zmienne rodzaju. 761 00:40:53,000 --> 00:40:57,000 Wprowadziliśmy także pojęcie pliku I / O, wejścia i wyjścia plików, 762 00:40:57,000 --> 00:41:00,000 i to jest tak, że możemy zapisać stan 763 00:41:00,000 --> 00:41:03,000 danej tablicy Scramble do pliku na dysku 764 00:41:03,000 --> 00:41:06,000 tak, że chłopaki nauczania i mogę zrozumieć 765 00:41:06,000 --> 00:41:09,000 , co dzieje się wewnątrz programu, bez konieczności ręcznego grać 766 00:41:09,000 --> 00:41:11,000 kilkadziesiąt gier Scramble. 767 00:41:11,000 --> 00:41:13,000 Możemy to zrobić bardziej automatedly. 768 00:41:13,000 --> 00:41:18,000 >> Ten pomysł struct rozwiązuje dość przekonujące problem. 769 00:41:18,000 --> 00:41:21,000 Załóżmy, że chcemy zaimplementować jakiś program 770 00:41:21,000 --> 00:41:25,000 że jakoś śledzi informacje na temat studentów, 771 00:41:25,000 --> 00:41:28,000 a studenci mogą mieć, na przykład, identyfikator, nazwę 772 00:41:28,000 --> 00:41:31,000 i dom w miejscu jak Harvard, więc są 3 kawałki informacji 773 00:41:31,000 --> 00:41:34,000 chcemy, aby wokół, więc pozwól mi iść dalej i zacząć pisać mały program tutaj 774 00:41:34,000 --> 00:41:38,000 obejmują stdio.h. 775 00:41:38,000 --> 00:41:42,000 Pozwól mi zrobić to cs50.h. 776 00:41:42,000 --> 00:41:44,000 I wtedy zaczynam główną funkcję. 777 00:41:44,000 --> 00:41:46,000 Nie przejmuj się z argumentami wiersza poleceń, 778 00:41:46,000 --> 00:41:49,000 i tu chcę mieć ucznia, więc powiem 779 00:41:49,000 --> 00:41:54,000 Student ma imię, więc mam zamiar powiedzieć "nazwę ciągu." 780 00:41:54,000 --> 00:41:59,000 Potem powiem uczeń ma również identyfikator, więc int id, 781 00:41:59,000 --> 00:42:03,000 i student ma dom, więc jestem również zamiar powiedzieć "dom ciąg". 782 00:42:03,000 --> 00:42:06,000 Wtedy będę zamawiać te trochę bardziej czysty jak ten. 783 00:42:06,000 --> 00:42:11,000 Ok, teraz mam 3 zmiennych, z którymi do reprezentowania studenta, więc "student". 784 00:42:11,000 --> 00:42:15,000 >> A teraz chcę, aby wypełnić te wartości, więc pozwól mi iść dalej i powiedzieć coś w stylu 785 00:42:15,000 --> 00:42:18,000 "Id = 123". 786 00:42:18,000 --> 00:42:21,000 Nazwa ma zamiar wrócić do Dawida. 787 00:42:21,000 --> 00:42:24,000 Powiedzmy, że dom ma zamiar wrócić do Mather, 788 00:42:24,000 --> 00:42:31,000 a potem mam zamiar zrobić coś arbitralnie jak printf ("% s, 789 00:42:31,000 --> 00:42:37,000 którego ID wynosi% d, mieszka w% s. 790 00:42:37,000 --> 00:42:41,000 A teraz, co ja chcę, aby podłączyć się tutaj, jeden po drugim? 791 00:42:41,000 --> 00:42:47,000 Nazwa, id, house; return 0. 792 00:42:47,000 --> 00:42:50,000 Dobra, chyba spieprzyłem gdzieś tutaj 793 00:42:50,000 --> 00:42:54,000 Myślę, że mamy całkiem dobry program, który przechowuje jeden student. 794 00:42:54,000 --> 00:42:57,000 Oczywiście nie jest to ciekawe, że wszystkie. Co zrobić, jeśli chcę mieć 2 studentów? 795 00:42:57,000 --> 00:42:59,000 To nie jest wielka sprawa. Mogę wspierać 2 osób. 796 00:42:59,000 --> 00:43:03,000 Pozwól mi iść dalej i podkreślić to i iść na dół, 797 00:43:03,000 --> 00:43:09,000 i mogę powiedzieć, "id = 456", dla kogoś takiego jak Rob, który mieszka w Kirkland. 798 00:43:09,000 --> 00:43:12,000 >> Dobra, czekaj, ale nie mogę połączyć te samo, 799 00:43:12,000 --> 00:43:15,000 i wygląda na to będę musiał skopiować to, 800 00:43:15,000 --> 00:43:19,000 więc pozwól mi powiedzieć, że to będzie Dawida zmienne, 801 00:43:19,000 --> 00:43:23,000 i daj mi trochę kopie te dla Rob. 802 00:43:23,000 --> 00:43:27,000 Zadzwonimy do nich Roba, ale to nie będzie działać teraz 803 00:43:27,000 --> 00:43:33,000 bo-wait, zmieńmy mnie ID1, nazwa1 i House1. 804 00:43:33,000 --> 00:43:35,000 Rob będzie 2, 2. 805 00:43:35,000 --> 00:43:42,000 Muszę to zmienić, tutaj, tutaj, tutaj, tutaj, tutaj, tutaj. 806 00:43:42,000 --> 00:43:45,000 Czekaj, co Tommy? Zróbmy to jeszcze raz. 807 00:43:45,000 --> 00:43:49,000 Oczywiście, jeśli nadal uważasz, że jest to dobry sposób w ten sposób, to nie jest, 808 00:43:49,000 --> 00:43:52,000 więc kopiować / zły. 809 00:43:52,000 --> 00:43:55,000 Ale rozwiązać to tydzień temu. 810 00:43:55,000 --> 00:43:59,000 >> Jakie było nasze rozwiązanie, gdy chcemy mieć wiele instancji tego samego typu danych? 811 00:43:59,000 --> 00:44:01,000 [Studenci] tablica. 812 00:44:01,000 --> 00:44:03,000 Tablica, więc pozwól mi spróbować wyczyścić to. 813 00:44:03,000 --> 00:44:07,000 Pozwól mi zrobić trochę miejsca dla siebie na górze, i pozwól mi zrobić, a nie to tutaj. 814 00:44:07,000 --> 00:44:12,000 Nazwijmy tych ludzi, i zamiast ja powiem "INT identyfikatory" 815 00:44:12,000 --> 00:44:14,000 i zamierzam wspierać nas 3 na razie. 816 00:44:14,000 --> 00:44:18,000 Mam zamiar powiedzieć "Nazwy ciągów", a ja obsługuje 3 z nas, 817 00:44:18,000 --> 00:44:22,000 a ja powiem "domy ciąg" i mam zamiar wspierać 3 z nas. 818 00:44:22,000 --> 00:44:26,000 Teraz w tutaj zamiast David coraz własne zmienne lokalne 819 00:44:26,000 --> 00:44:28,000 możemy pozbyć się tych. 820 00:44:28,000 --> 00:44:30,000 Że czuje się dobrze, że mamy to do czyszczenia. 821 00:44:30,000 --> 00:44:35,000 Możesz wtedy powiedzieć David będzie [0] i nazwiska [0] 822 00:44:35,000 --> 00:44:38,000 i domy [0]. 823 00:44:38,000 --> 00:44:41,000 A potem Rob możemy podobnie zapisać na to. 824 00:44:41,000 --> 00:44:46,000 Ujmę to w dół tutaj, więc on będzie arbitralnie być ids [1]. 825 00:44:46,000 --> 00:44:50,000 On chce być nazwy [1], 826 00:44:50,000 --> 00:44:53,000 i wreszcie, domy [1]. 827 00:44:53,000 --> 00:44:57,000 >> Jeszcze trochę nudny, a teraz muszę to rozgryźć, 828 00:44:57,000 --> 00:45:03,000 więc powiedzmy, że "nazwiska [0], id [0], domy [0] 829 00:45:03,000 --> 00:45:06,000 i niech pluralize to. 830 00:45:06,000 --> 00:45:09,000 Identyfikatory, identyfikatory, identyfikatory. 831 00:45:09,000 --> 00:45:12,000 I znowu to robię, więc ponownie, jestem już uciekania się do kopiuj / wklej ponownie 832 00:45:12,000 --> 00:45:14,000 więc kursy są tam inne rozwiązanie tutaj. 833 00:45:14,000 --> 00:45:18,000 Prawdopodobnie mogę oczyścić to się dalej z pętli, czy coś takiego, 834 00:45:18,000 --> 00:45:21,000 Tak w skrócie, to jest trochę lepiej, ale nadal czuje się jak 835 00:45:21,000 --> 00:45:24,000 Jestem uciekania się do kopiuj / wklej, ale nawet to, jak twierdzą, 836 00:45:24,000 --> 00:45:27,000 naprawdę nie jest zasadniczo właściwym rozwiązaniem, ponieważ 837 00:45:27,000 --> 00:45:29,000 co jeśli kiedyś zdecydujemy wiesz co? 838 00:45:29,000 --> 00:45:32,000 Naprawdę należało przechowywania adresów e-mail dla Dawida i Rob 839 00:45:32,000 --> 00:45:34,000 i wszyscy w tym programie. 840 00:45:34,000 --> 00:45:36,000 Należy również zapisać numery telefonów. 841 00:45:36,000 --> 00:45:39,000 Należy również zapisać numery alarmowy. 842 00:45:39,000 --> 00:45:41,000 Mamy te wszystkie fragmenty danych, które chcemy przechowywać, 843 00:45:41,000 --> 00:45:43,000 więc jak się do tego zabrać? 844 00:45:43,000 --> 00:45:46,000 >> Zadeklarować kolejną tablicę na szczycie, a następnie ręcznie dodać 845 00:45:46,000 --> 00:45:49,000 Adres e-mail [0], e-mail [1] 846 00:45:49,000 --> 00:45:51,000 dla Dawida i Rob i tak dalej. 847 00:45:51,000 --> 00:45:56,000 Ale jest naprawdę założeniem tego projektu 848 00:45:56,000 --> 00:45:59,000 że używam systemu zaszczyt wiedzieć, że 849 00:45:59,000 --> 00:46:03,000 [I], w każdym z kilku tablic 850 00:46:03,000 --> 00:46:06,000 tak się dzieje w odniesieniu do tej samej osoby, 851 00:46:06,000 --> 00:46:10,000 tak [0] w IDS jest numer 123, 852 00:46:10,000 --> 00:46:13,000 i mam zamiar założyć, że nazwy [0] 853 00:46:13,000 --> 00:46:16,000 to samo nazwisko osoby i domy [0] 854 00:46:16,000 --> 00:46:21,000 jest tą samą osobą w domu i tak dalej dla wszystkich różnych tablic, które tworzę. 855 00:46:21,000 --> 00:46:24,000 Zauważmy jednak, że nie ma fundamentalne powiązania 856 00:46:24,000 --> 00:46:27,000 wśród tych 3 elementów informacji, id, nazwisko i dom, 857 00:46:27,000 --> 00:46:32,000 chociaż jednostka staramy się modelu w tym programie nie jest tablicami. 858 00:46:32,000 --> 00:46:35,000 Tablice są tylko ten programowy sposób to zrobić. 859 00:46:35,000 --> 00:46:38,000 Co naprawdę chcemy modelować w naszym programie jest to osoba 860 00:46:38,000 --> 00:46:41,000 jak Dawid, osoba jak Rob wewnątrz której 861 00:46:41,000 --> 00:46:46,000 lub dokonującym jest nazwa i ID i house. 862 00:46:46,000 --> 00:46:49,000 >> Czy możemy w jakiś sposób wyrazić tę ideę enkapsulacji 863 00:46:49,000 --> 00:46:52,000 którą osoba ma identyfikator, nazwę i dom 864 00:46:52,000 --> 00:46:55,000 , a nie uciekać się do naprawdę ten hack której właśnie 865 00:46:55,000 --> 00:46:58,000 ufać, że coś wspornika 866 00:46:58,000 --> 00:47:02,000 odnosi się do samej istoty ludzkiej w każdym z tych odrębnych tablic? 867 00:47:02,000 --> 00:47:04,000 Rzeczywiście możemy to zrobić. 868 00:47:04,000 --> 00:47:08,000 Pozwól mi iść wyżej główny na teraz, i pozwól mi stworzyć mój własny typ danych 869 00:47:08,000 --> 00:47:10,000 w bardzo po raz pierwszy. 870 00:47:10,000 --> 00:47:14,000 Wykorzystaliśmy tę technikę w Scramble, 871 00:47:14,000 --> 00:47:17,000 ale tutaj mam zamiar iść dalej i utworzyć typ danych, 872 00:47:17,000 --> 00:47:19,000 i wiesz co, będę nazywać to student lub osoba, 873 00:47:19,000 --> 00:47:23,000 i mam zamiar używać typedef dla określenia typu. 874 00:47:23,000 --> 00:47:25,000 I powiem, że jest to struktura, 875 00:47:25,000 --> 00:47:29,000 a ta struktura będzie studenta typu, to mówimy, 876 00:47:29,000 --> 00:47:31,000 nawet jeśli jest to trochę stary teraz na mnie. 877 00:47:31,000 --> 00:47:33,000 Powiemy "int id". 878 00:47:33,000 --> 00:47:35,000 Powiemy "nazwę ciągu." 879 00:47:35,000 --> 00:47:37,000 Wtedy możemy powiedzieć, "dom", ciąg 880 00:47:37,000 --> 00:47:40,000 więc teraz do końca tych kilku linii kodu 881 00:47:40,000 --> 00:47:45,000 Właśnie uczy dzyń, że istnieje 882 00:47:45,000 --> 00:47:49,000 typ danych oprócz wskazówki, oprócz łańcuchów, oprócz podwójna, oprócz pływaków. 883 00:47:49,000 --> 00:47:54,000 >> W tej chwili w linii czasu 11, jest teraz nowy typ danych o nazwie studenci, 884 00:47:54,000 --> 00:47:58,000 i teraz mogę zadeklarować zmienną studentów gdziekolwiek chcę, 885 00:47:58,000 --> 00:48:01,000 więc pozwól mi przejść tu ludzi. 886 00:48:01,000 --> 00:48:05,000 Teraz mogę się pozbyć tego, i mogę iść z powrotem do Dawida tutaj 887 00:48:05,000 --> 00:48:10,000 i dla Dawida faktycznie mogę powiedzieć, że David, 888 00:48:10,000 --> 00:48:13,000 możemy dosłownie nazwać zmienną po sobie, 889 00:48:13,000 --> 00:48:16,000 będzie studenta typu. 890 00:48:16,000 --> 00:48:18,000 To może wyglądać trochę dziwnie, ale to nie wszystko, co różni 891 00:48:18,000 --> 00:48:22,000 od deklarowania coś jako int lub łańcucha lub pacą. 892 00:48:22,000 --> 00:48:24,000 Tak się na miano ucznia teraz 893 00:48:24,000 --> 00:48:28,000 i jeśli chcę umieścić coś wewnątrz tej struktury 894 00:48:28,000 --> 00:48:31,000 Mam teraz korzystać z nowego fragmentu składni, ale to jest bardzo proste, 895 00:48:31,000 --> 00:48:39,000 david.id = 123, david.name = "David" w stolicy D 896 00:48:39,000 --> 00:48:42,000 i david.house = "Mather" 897 00:48:42,000 --> 00:48:46,000 i teraz mogę się pozbyć tych rzeczy tutaj. 898 00:48:46,000 --> 00:48:51,000 Zauważ teraz mamy przeprojektowany nasz program w sposób naprawdę dużo lepiej 899 00:48:51,000 --> 00:48:54,000 że teraz nasz program odzwierciedla rzeczywisty świat. 900 00:48:54,000 --> 00:48:57,000 >> Jest rzeczywistym świecie pojęcie osoby lub studenta. 901 00:48:57,000 --> 00:49:02,000 Tutaj mamy teraz wersję C osoby lub dokładniej jako student. 902 00:49:02,000 --> 00:49:05,000 Wewnątrz tej osoby są te istotne cechy, 903 00:49:05,000 --> 00:49:10,000 ID, name i dom, więc Rob istocie staje się samo i tutaj, 904 00:49:10,000 --> 00:49:14,000 rob tak uczeń, a teraz rob.id = 456, 905 00:49:14,000 --> 00:49:17,000 rob.name = "Rob". 906 00:49:17,000 --> 00:49:20,000 Fakt, że zmienna nazywa się Rob jest trochę bezsensowne. 907 00:49:20,000 --> 00:49:22,000 Mogliśmy nazwał x lub y lub z. 908 00:49:22,000 --> 00:49:25,000 My po prostu nazwał go Rob być semantycznie spójne, 909 00:49:25,000 --> 00:49:28,000 ale naprawdę nazywa się wewnątrz tego samego pola, 910 00:49:28,000 --> 00:49:30,000 więc teraz mam to. 911 00:49:30,000 --> 00:49:33,000 To też nie ma ochoty na najlepszy projekt w, że mam twarde zakodowanej Dawida. 912 00:49:33,000 --> 00:49:35,000 Mam stałe zakodowany Rob. 913 00:49:35,000 --> 00:49:39,000 I wciąż muszą uciekać się do jakiś skopiuj i wklej za każdym razem chcę nowe zmienne. 914 00:49:39,000 --> 00:49:43,000 Ponadto muszę najwyraźniej dać każdej z tych zmiennych nazwę, 915 00:49:43,000 --> 00:49:46,000 chociaż wolałbym opisać te zmienne 916 00:49:46,000 --> 00:49:48,000  bardziej ogólnie jako studentów. 917 00:49:48,000 --> 00:49:52,000 >> Teraz możemy połączyć idee, które działa dobrze dla nas 918 00:49:52,000 --> 00:49:56,000 i zamiast powiedzieć: "Wiesz co, daj mi zmienną studentów, 919 00:49:56,000 --> 00:50:01,000 i niech się to być wielkości 3 ", więc teraz mogę ulepszyć ten dalej, 920 00:50:01,000 --> 00:50:04,000 pozbyć się ręcznie deklarowanej Dawida 921 00:50:04,000 --> 00:50:08,000 a ja zamiast powiedzieć coś studentów [0] tutaj. 922 00:50:08,000 --> 00:50:11,000 Możesz wtedy powiedzieć studentom [0] tutaj 923 00:50:11,000 --> 00:50:14,000 studentów [0] tutaj, i tak dalej, i mogę obejść 924 00:50:14,000 --> 00:50:16,000 i czyste, że się na Roba. 925 00:50:16,000 --> 00:50:19,000 Mogłem też iść o teraz może dodanie pętli 926 00:50:19,000 --> 00:50:23,000 i korzystania getString i getInt rzeczywiście dostać te wartości od użytkownika. 927 00:50:23,000 --> 00:50:27,000 Mogę iść o dodanie stałej, ponieważ na ogół jest to zła praktyka 928 00:50:27,000 --> 00:50:29,000 na twardym kod jakiś dowolny numer jak 3 tutaj 929 00:50:29,000 --> 00:50:33,000 a potem po prostu pamiętać, że należy umieścić nie więcej niż 3 uczniów w nim. 930 00:50:33,000 --> 00:50:36,000 Prawdopodobnie byłoby lepiej użyć # define na górze mojego pliku 931 00:50:36,000 --> 00:50:40,000 i czynnikiem, który obecnie, więc rzeczywiście, pozwól mi iść do przodu i generalizować to. 932 00:50:40,000 --> 00:50:43,000 >> Pozwól mi otworzyć się przykładem, który znajduje się między dzisiejszym 933 00:50:43,000 --> 00:50:46,000 przykłady z góry, structs1. 934 00:50:46,000 --> 00:50:49,000 To jest bardziej kompletny program, który wykorzystuje się tutaj # define 935 00:50:49,000 --> 00:50:51,000 i mówi, że będziemy mieć 3 studentów domyślnie. 936 00:50:51,000 --> 00:50:54,000 Tutaj jestem uznająca wartość klasy uczniów, 937 00:50:54,000 --> 00:50:57,000 tak w klasie uczniów, a teraz jestem za pomocą pętli 938 00:50:57,000 --> 00:51:00,000 tak aby kod trochę bardziej elegancki, zapełnić klasy 939 00:51:00,000 --> 00:51:05,000 z wyjścia użytkownika, więc iteracyjne od i = 0 dalej do studentów, co stanowi 3. 940 00:51:05,000 --> 00:51:07,000 A potem pyta użytkownika w tej wersji 941 00:51:07,000 --> 00:51:10,000  co studenta ID, i mogę go z getInt. 942 00:51:10,000 --> 00:51:13,000 Co znajduje się nazwisko studenta, a potem dostać się getString. 943 00:51:13,000 --> 00:51:15,000 Co studenta dom? Rozumiem ze getString. 944 00:51:15,000 --> 00:51:19,000 A następnie na dole tutaj właśnie zdecydowaliśmy się na zmianę 945 00:51:19,000 --> 00:51:22,000 jak mam je z drukowania i faktycznie używać pętli, 946 00:51:22,000 --> 00:51:24,000 i kto ja drukowania? 947 00:51:24,000 --> 00:51:27,000 Zgodnie z komentarzem Jestem drukowania nikogo w Mather, 948 00:51:27,000 --> 00:51:30,000 i to jest tak Rob i Tommy, i tak dalej, a właściwie Tommy w Mather. 949 00:51:30,000 --> 00:51:34,000 Tommy i David będą drukowane w tym przypadku, ale jak jest to działa? 950 00:51:34,000 --> 00:51:40,000 Nie widzieliśmy tej funkcji przed, ale zgadywać, co to robi. 951 00:51:40,000 --> 00:51:42,000 Porównuje łańcuchy. 952 00:51:42,000 --> 00:51:45,000 >> To trochę nieoczywisty jak to porównać ciągi bo okazuje się, 953 00:51:45,000 --> 00:51:49,000 jeżeli zwraca 0 co oznacza, że ​​łańcuchy są równe. 954 00:51:49,000 --> 00:51:53,000 Jeśli zwróci -1 oznacza przychodzi alfabetycznie przed drugim, 955 00:51:53,000 --> 00:51:57,000 i jeżeli zwraca 1 oznacza to, że inne słowo pochodzi alfabetycznie 956 00:51:57,000 --> 00:52:00,000 przed innymi, i można sprawdzić online lub na stronie man 957 00:52:00,000 --> 00:52:04,000 dokładnie sprawdzić, w jaki sposób jest który, ale to wszystko jest teraz robi to jest mówi 958 00:52:04,000 --> 00:52:09,000 jeśli [i]. dom jest równa "Mather" 959 00:52:09,000 --> 00:52:13,000 śmiało i wydrukować tak i tak jest w Mather. 960 00:52:13,000 --> 00:52:16,000 Ale tu jest coś, czego nie widziałem wcześniej, i wrócimy do tego. 961 00:52:16,000 --> 00:52:21,000 Nie przypominam sobie, nigdy o to zrobić w jednym z moich programów. 962 00:52:21,000 --> 00:52:24,000 Bezpłatne najwyraźniej myśli pamięci, zwalniając pamięć, 963 00:52:24,000 --> 00:52:31,000 ale co ja mam pamięć najwyraźniej uwolnieniu w tej pętli na końcu tego programu? 964 00:52:31,000 --> 00:52:34,000 Wygląda to tak, jakbym uwalniając nazwisko osoby 965 00:52:34,000 --> 00:52:37,000 a człowiek w domu, ale dlaczego tak jest? 966 00:52:37,000 --> 00:52:41,000 >> Okazuje się, że te wszystkie tygodnie używałeś getString 967 00:52:41,000 --> 00:52:45,000 mamy trochę wprowadzało błąd w każdym z programów. 968 00:52:45,000 --> 00:52:51,000 GetString według projektu przydziela pamięć tak, że może wrócić do Ciebie strun 969 00:52:51,000 --> 00:52:55,000 jak David, czy Rob, i można wtedy robić, co chcesz 970 00:52:55,000 --> 00:52:59,000 z tym ciąg w programie, ponieważ mamy zarezerwowanej pamięci dla Ciebie. 971 00:52:59,000 --> 00:53:02,000 Problem jest cały czas za każdym razem wywołać getString 972 00:53:02,000 --> 00:53:05,000 my, autorzy getString, pytali system operacyjny 973 00:53:05,000 --> 00:53:07,000 dać nam trochę pamięci RAM dla tego łańcucha. 974 00:53:07,000 --> 00:53:09,000 Daj nam trochę pamięci RAM dla tego kolejnego łańcucha. 975 00:53:09,000 --> 00:53:11,000 Daj nam trochę więcej pamięci RAM dla tego kolejnego łańcucha. 976 00:53:11,000 --> 00:53:13,000 Co ty, programista, nigdy nie robi 977 00:53:13,000 --> 00:53:15,000 daje nam to z powrotem pamięci 978 00:53:15,000 --> 00:53:17,000 więc dla tych kilku tygodni wszystkie programy napisałeś 979 00:53:17,000 --> 00:53:20,000 mieli co nazywa skok pamięci za pomocą których należy korzystać 980 00:53:20,000 --> 00:53:24,000 więcej i więcej pamięci za każdym razem wywołać GetString, i to jest w porządku. 981 00:53:24,000 --> 00:53:27,000 Celowo nie jest to w pierwszych tygodniach, ponieważ nie jest tak interesujące 982 00:53:27,000 --> 00:53:29,000 mają się martwić, gdzie łańcuch pochodzi. 983 00:53:29,000 --> 00:53:34,000 Wszystko czego chcę to słowo Rob wrócić, gdy użytkownik wpisze go w. 984 00:53:34,000 --> 00:53:38,000 >> Ale naprzód teraz musimy zacząć bardziej wyrafinowane o tym. 985 00:53:38,000 --> 00:53:42,000 Za każdym razem możemy przydzielić pamięci lepiej ostatecznie oddać go z powrotem. 986 00:53:42,000 --> 00:53:45,000 W przeciwnym razie w świecie rzeczywistym na komputerze Mac lub PC możesz mieć czasami doświadczonym 987 00:53:45,000 --> 00:53:50,000 objawy, gdzie komputer jest szlifowanie do zatrzymania ostatecznie 988 00:53:50,000 --> 00:53:54,000 lub głupi przędzenia piłka plaża jest po prostu zajmując komputera 989 00:53:54,000 --> 00:53:56,000 cała uwaga i nie można robić różne rzeczy. 990 00:53:56,000 --> 00:54:00,000 , Które mogą być wyjaśnione przez dowolną liczbę błędów, ale wśród tych możliwych błędów 991 00:54:00,000 --> 00:54:03,000 Są rzeczy, których nazywa się wycieki pamięci kogoś, kto napisał ten kawałek oprogramowania 992 00:54:03,000 --> 00:54:07,000 używasz nie pamiętam w celu zwolnienia pamięci 993 00:54:07,000 --> 00:54:10,000 że on lub ona zwróciła się do systemu operacyjnego dla, 994 00:54:10,000 --> 00:54:14,000 nie używając getString, bo to CS50 rzecz, ale stosując podobne funkcje 995 00:54:14,000 --> 00:54:16,000 że zawiera system operacyjny dla pamięci. 996 00:54:16,000 --> 00:54:19,000 Jeśli ty lub oni zepsuć i nigdy nie wrócić, że pamięć 997 00:54:19,000 --> 00:54:24,000 objawem, który może być, że program spowalnia i spowalnia i spowalnia 998 00:54:24,000 --> 00:54:26,000 chyba pamiętasz zadzwonić darmo. 999 00:54:26,000 --> 00:54:28,000 >> Wrócimy do tego, kiedy i dlaczego nazywacie wolne, 1000 00:54:28,000 --> 00:54:32,000 ale niech śmiało tylko środek na dobre i spróbuj uruchomić ten konkretny program. 1001 00:54:32,000 --> 00:54:35,000 Nazywało structs1 wprowadzić. 1002 00:54:35,000 --> 00:54:40,000 Pozwólcie mi iść do przodu i uruchamiania structs1, 123, David Mather, 1003 00:54:40,000 --> 00:54:47,000 456, Rob Kirkland, 789, 1004 00:54:47,000 --> 00:54:50,000 Tommy Mather i widzimy Dawida w Mather, Tommy w Mather. 1005 00:54:50,000 --> 00:54:53,000 To jest po prostu trochę Sprawdzanie poprawności, że program działa. 1006 00:54:53,000 --> 00:54:56,000 Teraz, niestety, ten program jest trochę frustrujące, że w 1007 00:54:56,000 --> 00:55:00,000 Zrobiłem wszystko, co praca, wpisałem w 9 różnych ciągów, wciskamy Enter, 1008 00:55:00,000 --> 00:55:04,000 powiedziano mi, kto był w Mather, ale oczywiście wiem, kto był już w Mather bo wpisałeś. 1009 00:55:04,000 --> 00:55:07,000 To jest, jeśli co najmniej przyjemne Program jest bardziej bazie 1010 00:55:07,000 --> 00:55:10,000 i faktycznie pamięta, co mam wpisać w 1011 00:55:10,000 --> 00:55:12,000 więc nigdy nie musiały ponownie input te zapisy studentów. 1012 00:55:12,000 --> 00:55:15,000 Może to jest jak registrarial systemu. 1013 00:55:15,000 --> 00:55:21,000 >> Możemy to zrobić za pomocą tej techniki znanej jako pliku I / O, wejścia i wyjścia plików, 1014 00:55:21,000 --> 00:55:24,000 bardzo ogólny sposób powiedzieć, kiedy tylko chcesz do odczytu plików lub zapisu plików 1015 00:55:24,000 --> 00:55:26,000 można to zrobić z pewnym zestawem funkcji. 1016 00:55:26,000 --> 00:55:29,000 Pozwólcie mi iść do przodu i otworzyć structs2.c przykład, 1017 00:55:29,000 --> 00:55:33,000 który jest niemal identyczne, ale zobaczymy, co teraz robi. 1018 00:55:33,000 --> 00:55:36,000 Na początku pliku Oświadczam studentów klasę. 1019 00:55:36,000 --> 00:55:38,000 Następnie wypełnić klasę wyjścia użytkownika, 1020 00:55:38,000 --> 00:55:41,000 więc te linie kodu są takie same jak wcześniej. 1021 00:55:41,000 --> 00:55:45,000 Następnie jeśli przewiń tutaj wydrukować każdy, kto jest w Mather arbitralnie, jak poprzednio, 1022 00:55:45,000 --> 00:55:47,000 ale jest to interesująca nowa funkcja. 1023 00:55:47,000 --> 00:55:51,000 Te wiersze kodu są nowe i wprowadzają coś tu 1024 00:55:51,000 --> 00:55:55,000 Pliku, wszystkie czapki, i to * w tutaj również. 1025 00:55:55,000 --> 00:55:58,000 Pozwól przenieść to tutaj, a * tu również. 1026 00:55:58,000 --> 00:56:00,000 >> Ta funkcja nie widzieliśmy wcześniej, fopen, 1027 00:56:00,000 --> 00:56:03,000 ale to oznacza plik otwarty, więc niech przejrzeć te, 1028 00:56:03,000 --> 00:56:05,000 i to jest coś, wrócimy w przyszłym psets, 1029 00:56:05,000 --> 00:56:10,000 ale ta linia tutaj zasadniczo otwiera plik o nazwie bazy danych, 1030 00:56:10,000 --> 00:56:13,000 i to specjalnie otwiera go w taki sposób, że może robić to, co do niego? 1031 00:56:13,000 --> 00:56:15,000 [Niesłyszalne-uczeń] 1032 00:56:15,000 --> 00:56:19,000 Dobra, więc "w" oznacza po prostu to mówi systemu operacyjnego 1033 00:56:19,000 --> 00:56:21,000 otworzyć plik w taki sposób, że można w nim zapisu. 1034 00:56:21,000 --> 00:56:23,000 Nie chcę, aby ją przeczytać. Nie chcę po prostu patrzeć. 1035 00:56:23,000 --> 00:56:26,000 Chcę to zmienić i dodać rzeczy potencjalnie do niego, 1036 00:56:26,000 --> 00:56:28,000 a plik ma być nazywany bazy danych. 1037 00:56:28,000 --> 00:56:30,000 To można nazwać nic. 1038 00:56:30,000 --> 00:56:32,000 To może być database.txt. To może być. DB. 1039 00:56:32,000 --> 00:56:37,000 Może to być słowo jak foo, ale samowolnie wybrał nazwę pliku bazy danych. 1040 00:56:37,000 --> 00:56:42,000 To jest trochę Sprawdzanie poprawności, że wrócimy do bardzo szczegółowo w czasie, 1041 00:56:42,000 --> 00:56:47,000 jeżeli fp, dla wskaźnika pliku, nie jest równa NULL oznacza to wszystko jest dobrze. 1042 00:56:47,000 --> 00:56:51,000 >> Długa historia krótkiego, funkcje takie jak fopen czasami nie. 1043 00:56:51,000 --> 00:56:53,000 Może plik nie istnieje. Może jesteś z miejsca na płycie. 1044 00:56:53,000 --> 00:56:55,000 Może nie ma uprawnień do tego folderu, 1045 00:56:55,000 --> 00:56:58,000 więc jeśli fopen zwraca null coś się stało. 1046 00:56:58,000 --> 00:57:02,000 Natomiast jeśli fopen nie zwróci null wszystko jest dobrze 1047 00:57:02,000 --> 00:57:04,000 i mogę zacząć pisać do tego pliku. 1048 00:57:04,000 --> 00:57:06,000 Oto nowy trick. 1049 00:57:06,000 --> 00:57:08,000 To jest dla pętli, które jest Iterowanie nad każdym z moich studentów, 1050 00:57:08,000 --> 00:57:10,000 i wygląda to tak podobne do tego, co zrobiliśmy wcześniej, 1051 00:57:10,000 --> 00:57:15,000 ale ta funkcja jest kuzynem printf nazywa fprintf dla pliku printf, 1052 00:57:15,000 --> 00:57:18,000 i zauważ, że jest inaczej w zaledwie 2 sposoby. 1053 00:57:18,000 --> 00:57:20,000 Jednym, zaczyna f zamiast P 1054 00:57:20,000 --> 00:57:23,000 ale to jego pierwszy argument jest najwyraźniej co? 1055 00:57:23,000 --> 00:57:25,000 [Studenci] Plik. >> To jest plik. 1056 00:57:25,000 --> 00:57:30,000 To coś nazywa fp, które będziemy w końcu odciąć co wskaźnik pliku jest 1057 00:57:30,000 --> 00:57:35,000 ale teraz fp prostu reprezentuje plik, że mam otwarte, 1058 00:57:35,000 --> 00:57:41,000 tak fprintf tutaj mówi Wydrukuj to ID użytkownika do pliku, a nie na ekranie. 1059 00:57:41,000 --> 00:57:44,000 Drukuj nazwę użytkownika do pliku, a nie na ekranie, 1060 00:57:44,000 --> 00:57:47,000 dom do pliku, a nie na ekranie, a następnie tu, oczywiście, 1061 00:57:47,000 --> 00:57:50,000 zamknij plik, a następnie w dół tutaj wolne pamięci. 1062 00:57:50,000 --> 00:57:53,000 >> Jedyna różnica między tą wersją i wersją 1 2 1063 00:57:53,000 --> 00:57:58,000 jest wprowadzenie fopen i ten plik z * 1064 00:57:58,000 --> 00:58:01,000 i to pojęcie fprintf, więc zobaczymy, co efekt końcowy jest. 1065 00:58:01,000 --> 00:58:03,000 Pozwól mi iść do mojego okna terminala. 1066 00:58:03,000 --> 00:58:06,000 Pozwólcie mi biegać structs2 wprowadzić. 1067 00:58:06,000 --> 00:58:09,000 Wygląda na to, że wszystko jest dobrze. Miejmy powtórka structs2. 1068 00:58:09,000 --> 00:58:15,000 123, David Mather, 456, Rob Kirkland, 1069 00:58:15,000 --> 00:58:19,000 789, Tommy Mather, enter. 1070 00:58:19,000 --> 00:58:23,000 Wygląda tak, jak zachowywał się tak samo, ale jeśli teraz zrobić ls 1071 00:58:23,000 --> 00:58:28,000 zauważyć, co plik jest tutaj wśród całego kodu, bazy danych, 1072 00:58:28,000 --> 00:58:32,000 więc otwórzmy, że gedit z bazy danych, a popatrz na to. 1073 00:58:32,000 --> 00:58:34,000 Nie najseksowniejszą formatów plików jest. 1074 00:58:34,000 --> 00:58:38,000 Jest to naprawdę jeden kawałek linii danych w jednej linii na linię, 1075 00:58:38,000 --> 00:58:42,000 ale ci z was, którzy korzystają z programu Excel lub CSV plików oddzielone przecinkami wartości, 1076 00:58:42,000 --> 00:58:47,000 Mogę z pewnością stosowane fprintf, aby zamiast być może coś jak to zrobić 1077 00:58:47,000 --> 00:58:50,000 tak, że mogę rzeczywiście stworzyć odpowiednik pliku Excel 1078 00:58:50,000 --> 00:58:53,000 oddzielając przecinkami rzeczy, nie tylko nowych linii. 1079 00:58:53,000 --> 00:58:56,000 >> W tym przypadku, gdybym zamiast stosować przecinków zamiast nowe linie 1080 00:58:56,000 --> 00:59:01,000 Mogłem dosłownie otworzyć plik bazy danych w programie Excel, jeśli zamiast wygladalo to tak. 1081 00:59:01,000 --> 00:59:03,000 Krótko mówiąc, teraz, że mamy prawo do zapisu plików 1082 00:59:03,000 --> 00:59:07,000 możemy zacząć utrzymujących dane, uniemożliwiając jej okolice na płycie 1083 00:59:07,000 --> 00:59:10,000 tak, że możemy przechowywać informacje wokół ponownie i ponownie. 1084 00:59:10,000 --> 00:59:14,000 Zauważyć kilka innych rzeczy, które są teraz nieco bardziej znajome. 1085 00:59:14,000 --> 00:59:16,000 W górnej części tego pliku C mamy typedef 1086 00:59:16,000 --> 00:59:21,000 ponieważ chcieliśmy stworzyć typ danych, który reprezentuje słowo, 1087 00:59:21,000 --> 00:59:25,000 więc ten typ nazywany jest słowem, a wewnątrz tej struktury 1088 00:59:25,000 --> 00:59:27,000 to trochę hodowcy teraz. 1089 00:59:27,000 --> 00:59:30,000 Dlaczego słowo składa się z pozornie tablicy? 1090 00:59:30,000 --> 00:59:33,000 Co to słowo po prostu intuicyjnie? 1091 00:59:33,000 --> 00:59:35,000 >> Jest to tablica znaków. 1092 00:59:35,000 --> 00:59:37,000 Jest to ciąg znaków z powrotem do tyłu do tyłu. 1093 00:59:37,000 --> 00:59:41,000 Listów, wszystkie czapki dzieje się nam arbitralnie powiedzieć maksymalna długość 1094 00:59:41,000 --> 00:59:44,000 każdego słowa w słowniku, które używamy do Scramble. 1095 00:59:44,000 --> 00:59:46,000 Dlaczego mam 1? 1096 00:59:46,000 --> 00:59:48,000 Znak null. 1097 00:59:48,000 --> 00:59:51,000 Przypomnijmy, gdy zrobiliśmy przykład Bananagrams potrzebowaliśmy szczególną wartość 1098 00:59:51,000 --> 00:59:55,000 na końcu, w celu słowa śledzić 1099 00:59:55,000 --> 00:59:59,000 , gdzie słowa rzeczywiście skończyło, a jak mówi specyfikacja zestaw problemem 1100 00:59:59,000 --> 01:00:03,000 tutaj mamy skojarzenie z danym słowem wartość logiczną, 1101 01:00:03,000 --> 01:00:05,000 flag, by tak rzec, prawda lub fałsz. 1102 01:00:05,000 --> 01:00:09,000 Znalazłeś już tego słowa, ponieważ zdajemy sobie sprawę, 1103 01:00:09,000 --> 01:00:13,000 naprawdę potrzebujemy sposobu pamiętania nie tylko to, co słowo to w Scramble 1104 01:00:13,000 --> 01:00:15,000 ale czy ty, człowiek, znalazłem go 1105 01:00:15,000 --> 01:00:20,000 tak, że jeśli nie znajdziesz słowa "" nie można po prostu wpisać, wejść,, enter, wprowadź 1106 01:00:20,000 --> 01:00:23,000 i uzyskać 3 punkty, 3 punkty, 3 punkty, 3 punkty. 1107 01:00:23,000 --> 01:00:26,000 Chcemy być w stanie do czarnej listy to słowo poprzez bool 1108 01:00:26,000 --> 01:00:29,000 true jeśli już znalazłem, więc dlatego 1109 01:00:29,000 --> 01:00:31,000 obudowane to w tej strukturze. 1110 01:00:31,000 --> 01:00:35,000 >> Teraz, tutaj w Scramble istnieje ten inny struct nazwie słownika. 1111 01:00:35,000 --> 01:00:39,000 Nieobecny jest tu słowo typedef ponieważ w tym przypadku 1112 01:00:39,000 --> 01:00:43,000 musieliśmy ująć ideę słownika 1113 01:00:43,000 --> 01:00:46,000 i Słownik zawiera całą masę słów, 1114 01:00:46,000 --> 01:00:49,000 jak wynika z tej tablicy, i jak wiele z tych słów są tam? 1115 01:00:49,000 --> 01:00:51,000 Cóż, cokolwiek ta zmienna nazywa rozmiar mówi. 1116 01:00:51,000 --> 01:00:53,000 Ale wystarczy jeden słownik. 1117 01:00:53,000 --> 01:00:55,000 Nie musimy typ danych o nazwie słownika. 1118 01:00:55,000 --> 01:00:58,000 Potrzebujemy tylko jednego z nich, więc okazuje się, w C 1119 01:00:58,000 --> 01:01:03,000 że jeśli nie mówisz typedef, po prostu powiedzieć, struct, a następnie wewnątrz nawiasów klamrowych 1120 01:01:03,000 --> 01:01:05,000 umieścić swoje zmienne, a następnie umieścić nazwę. 1121 01:01:05,000 --> 01:01:09,000 Ten deklaruje jeden zmienną słownik 1122 01:01:09,000 --> 01:01:11,000 który wygląda tak. 1123 01:01:11,000 --> 01:01:16,000 Natomiast linie te są wielokrotnego użytku, tworząc strukturę danych o nazwie słowo 1124 01:01:16,000 --> 01:01:19,000 że można tworzyć wiele kopii, jak stworzyliśmy 1125 01:01:19,000 --> 01:01:22,000 wiele kopii studentów. 1126 01:01:22,000 --> 01:01:24,000 >> Co to w końcu pozwoli nam to zrobić? 1127 01:01:24,000 --> 01:01:30,000 Pozwól mi wrócić do, powiedzmy, prostszy przykład z prostszych czasów, 1128 01:01:30,000 --> 01:01:34,000 i pozwól mi otworzyć się, powiedzmy, compare1.c. 1129 01:01:34,000 --> 01:01:38,000 Problem w kasie jest faktycznie odwinąć 1130 01:01:38,000 --> 01:01:41,000 warstwa ciąg i rozpocząć wyłączyć te kółka 1131 01:01:41,000 --> 01:01:44,000 bo okazuje się, że ciąg ten cały czas 1132 01:01:44,000 --> 01:01:47,000 jest jak obiecaliśmy w tydzień 1 tak naprawdę pseudonim, 1133 01:01:47,000 --> 01:01:51,000 synonim od CS50 bibliotece dla czegoś, co wygląda trochę bardziej tajemniczy, 1134 01:01:51,000 --> 01:01:53,000 char *, a my widzieliśmy ten gwiazda przed. 1135 01:01:53,000 --> 01:01:55,000 Widzieliśmy to w kontekście plików. 1136 01:01:55,000 --> 01:01:59,000 >> Spróbujmy teraz zrozumieć, dlaczego mamy ukrywał tę informację od jakiegoś czasu. 1137 01:01:59,000 --> 01:02:02,000 Tutaj jest plik o nazwie compare1.c, 1138 01:02:02,000 --> 01:02:07,000 i najwyraźniej prosi użytkownika o 2 ciągi, S i T, 1139 01:02:07,000 --> 01:02:11,000 , a następnie stara się porównać tych ciągów dla równości w linii 26, 1140 01:02:11,000 --> 01:02:14,000 i czy są one równe, że mówi: "wpisane samo" 1141 01:02:14,000 --> 01:02:17,000 i jeśli nie są one równe mówi "Wpisano różne rzeczy." 1142 01:02:17,000 --> 01:02:19,000 Pozwól mi iść dalej i uruchomić ten program. 1143 01:02:19,000 --> 01:02:23,000 Pozwól mi iść do mojego katalogu źródłowego, zrobić compare1. Jest opracowany w porządku. 1144 01:02:23,000 --> 01:02:25,000 Pozwólcie mi biegać compare1. 1145 01:02:25,000 --> 01:02:27,000 Ja powiększyć, enter. 1146 01:02:27,000 --> 01:02:29,000 Powiedz coś. Hello. 1147 01:02:29,000 --> 01:02:32,000 Powiem coś jeszcze raz. Hello. 1148 01:02:32,000 --> 01:02:34,000 Zdecydowanie nie wpisać różne rzeczy. 1149 01:02:34,000 --> 01:02:37,000 >> Pozwól mi spróbować jeszcze raz. BYE BYE. 1150 01:02:37,000 --> 01:02:40,000 Zdecydowanie nie inna, więc to, co tu się dzieje? 1151 01:02:40,000 --> 01:02:44,000 Cóż, to, co naprawdę jest w porównaniu z linią 26? 1152 01:02:44,000 --> 01:02:46,000 [Niesłyszalne-uczeń] 1153 01:02:46,000 --> 01:02:49,000 Tak, więc okazuje się, że łańcuch, typ danych, to rodzaj białego kłamstwa. 1154 01:02:49,000 --> 01:02:53,000 Ciąg jest char *, ale co jest char *? 1155 01:02:53,000 --> 01:02:56,000 Char *, jak mówią, jest wskaźnik, 1156 01:02:56,000 --> 01:03:00,000 i wskaźnik jest skutecznie adres, 1157 01:03:00,000 --> 01:03:05,000 lokalizacja suma w pamięci, a jeśli zdarzy się, że wpisane w słowa jak HELLO, 1158 01:03:05,000 --> 01:03:08,000 pamiętam z poprzednich dyskusji ciągów 1159 01:03:08,000 --> 01:03:16,000 to jest jak słowo hello. 1160 01:03:16,000 --> 01:03:19,000 Pamiętaj, że słowo takie jak Halo może być reprezentowany 1161 01:03:19,000 --> 01:03:22,000 jako tablica znaków, podobnie jak to 1162 01:03:22,000 --> 01:03:25,000 , a następnie w postaci specjalnego koniec zwany znak pusty, 1163 01:03:25,000 --> 01:03:27,000 jako \ oznacza. 1164 01:03:27,000 --> 01:03:29,000 Co to jest rzeczywiście ciąg? 1165 01:03:29,000 --> 01:03:32,000 Zauważ, że jest to kolejne fragmenty pamięci, 1166 01:03:32,000 --> 01:03:36,000 i faktycznie, jego koniec jest znany jedynie raz przejrzeć cały ciąg 1167 01:03:36,000 --> 01:03:38,000 szukasz specjalnego znaku pustego. 1168 01:03:38,000 --> 01:03:41,000 Ale jeśli jest to fragment pamięci z mojej pamięci komputera, 1169 01:03:41,000 --> 01:03:44,000 niech arbitralnie powiedzieć, że ten ciąg po prostu mieliśmy szczęście, 1170 01:03:44,000 --> 01:03:47,000 i dostałem umieszczony na samym początku mojej pamięci RAM komputera. 1171 01:03:47,000 --> 01:03:54,000 Ten bajt jest 0, 1, 2, 3, 4, 5, 6 ... 1172 01:03:54,000 --> 01:04:02,000 >> Kiedy mówię, że coś takiego getString i zrobić string s = getString 1173 01:04:02,000 --> 01:04:04,000 co tak naprawdę są zwracane? 1174 01:04:04,000 --> 01:04:08,000 Dla tych ostatnich kilku tygodni, co naprawdę są przechowywane w s 1175 01:04:08,000 --> 01:04:13,000 nie jest to łańcuch per se, ale w tym przypadku, co jest przechowywane 1176 01:04:13,000 --> 01:04:18,000 0 liczba, ponieważ to, co faktycznie robi GetString 1177 01:04:18,000 --> 01:04:20,000 jest to fizycznie nie zwracać ciąg. 1178 01:04:20,000 --> 01:04:22,000 To nawet nie naprawdę koncepcyjny sens. 1179 01:04:22,000 --> 01:04:24,000 Co robi zwrot jest liczba. 1180 01:04:24,000 --> 01:04:28,000 Ta liczba jest adres WITAJ w pamięci, 1181 01:04:28,000 --> 01:04:32,000 i ciąg s wtedy, jeśli ta warstwa odwinąć, string nie istnieje naprawdę. 1182 01:04:32,000 --> 01:04:35,000 To tylko uproszczenie w CS50 biblioteki. 1183 01:04:35,000 --> 01:04:38,000 >> To naprawdę jest coś, co nazywa char *. 1184 01:04:38,000 --> 01:04:41,000 Char ma sens, bo co to słowo, podobnie jak Halo? 1185 01:04:41,000 --> 01:04:44,000 Cóż, to jest seria znaków, ciąg znaków. 1186 01:04:44,000 --> 01:04:47,000 Char * oznacza adres znaku, 1187 01:04:47,000 --> 01:04:50,000 więc co to znaczy zwracać ciąg? 1188 01:04:50,000 --> 01:04:53,000 Ładny, prosty sposób powrotu ciąg 1189 01:04:53,000 --> 01:04:57,000 to zamiast spróbować dowiedzieć się, jak wrócę do 5 lub 6 różnych bajtach 1190 01:04:57,000 --> 01:05:01,000 Pozwól mi wrócić do adresu, który bajt? 1191 01:05:01,000 --> 01:05:03,000 Pierwszy. 1192 01:05:03,000 --> 01:05:06,000 Innymi słowy, dam ci adres znaku w pamięci. 1193 01:05:06,000 --> 01:05:10,000 To, co char * reprezentuje, adres jednego znaku w pamięci. 1194 01:05:10,000 --> 01:05:12,000 Zadzwoń do tej zmiennej s. 1195 01:05:12,000 --> 01:05:15,000 Sklep w s, że dany adres, którą arbitralnie powiedział jest 0, 1196 01:05:15,000 --> 01:05:19,000 żeby zachować rzeczy proste, ale w rzeczywistości jest to zazwyczaj większa liczba. 1197 01:05:19,000 --> 01:05:21,000 >> Chwileczkę. 1198 01:05:21,000 --> 01:05:23,000 Jeśli tylko daje mi adres pierwszego znaku, czy ja wiem, co adres 1199 01:05:23,000 --> 01:05:25,000 drugi znak, trzeci, czwarty i piąty? 1200 01:05:25,000 --> 01:05:27,000 [Niesłyszalne-uczeń] 1201 01:05:27,000 --> 01:05:31,000 Musisz tylko wiedzieć, gdzie koniec łańcucha jest w drodze tej poręcznej trick, 1202 01:05:31,000 --> 01:05:35,000 więc kiedy używać coś jak printf, co printf dosłownie wymaga jako argumentu, 1203 01:05:35,000 --> 01:05:39,000 Przypomnijmy, że używamy tego zastępczy% s, a następnie przechodzą w 1204 01:05:39,000 --> 01:05:41,000 Zmienna jest przechowywanie ciąg. 1205 01:05:41,000 --> 01:05:47,000 Co naprawdę przechodzącej jest adres pierwszego znaku tego łańcucha. 1206 01:05:47,000 --> 01:05:50,000 Printf wykorzystuje następnie do pętli lub pętli while po otrzymaniu tego adresu, 1207 01:05:50,000 --> 01:05:53,000 na przykład 0, więc pozwól mi to zrobić teraz, 1208 01:05:53,000 --> 01:06:02,000 printf ("% s \ n", s); 1209 01:06:02,000 --> 01:06:07,000 Kiedy dzwonię do printf ("% s \ n", s); co jestem naprawdę dostarczanie printf z 1210 01:06:07,000 --> 01:06:13,000 to adres pierwszego znaku w s, który w tym przypadku jest arbitralny H. 1211 01:06:13,000 --> 01:06:16,000 >> Jak printf wiedzieć, co dokładnie, aby wyświetlić na ekranie? 1212 01:06:16,000 --> 01:06:19,000 Osoba, która realizowana printf realizowane pętli while lub do pętli 1213 01:06:19,000 --> 01:06:23,000 mówi, że to ma charakter szczególny charakter równy NULL? 1214 01:06:23,000 --> 01:06:25,000 Jeśli nie, to wydrukować. Jak o tym? 1215 01:06:25,000 --> 01:06:28,000 Jeśli nie drukować, drukować, drukować, drukować. 1216 01:06:28,000 --> 01:06:32,000 Oh, ten jest wyjątkowy. Zatrzymaj drukowanie i powrócić do użytkownika. 1217 01:06:32,000 --> 01:06:35,000 I to dosłownie wszystko, co dzieje się pod maską, 1218 01:06:35,000 --> 01:06:38,000 i to dużo do strawienia w pierwszym dniu klasy, 1219 01:06:38,000 --> 01:06:43,000 ale teraz to naprawdę budulcem wszystkiego zrozumienia 1220 01:06:43,000 --> 01:06:46,000 który jest już od wewnątrz naszej pamięci komputera, 1221 01:06:46,000 --> 01:06:49,000 i ostatecznie będziemy drażnić to apart z niewielką pomocą 1222 01:06:49,000 --> 01:06:51,000 od jednego z naszych przyjaciół w Stanford. 1223 01:06:51,000 --> 01:06:56,000 >> Profesor Nick Parlante w Stanford zrobił ten wspaniały sekwencji wideo 1224 01:06:56,000 --> 01:06:58,000 od wszelkiego rodzaju różnych językach, które wprowadziły 1225 01:06:58,000 --> 01:07:00,000 ten mały znak Claymation Binky. 1226 01:07:00,000 --> 01:07:03,000 Głos masz zamiar usłyszeć w kilku podglądu sekund zaskoczenia 1227 01:07:03,000 --> 01:07:05,000 jest to, że z Stanford profesora i dostajesz 1228 01:07:05,000 --> 01:07:07,000 tylko 5 lub 6 sekund to teraz, 1229 01:07:07,000 --> 01:07:09,000 ale to jest uwaga na której możemy stwierdzić dziś 1230 01:07:09,000 --> 01:07:11,000 i rozpocznie się w środę. 1231 01:07:11,000 --> 01:07:15,000 Daję ci Fun wskaźnik z Binky, podglądu. 1232 01:07:15,000 --> 01:07:18,000 [♪ Muzyka ♪] [Profesor Parlante] Hey, Binky. 1233 01:07:18,000 --> 01:07:21,000 Obudź się. To jest czas na zabawę wskaźnika. 1234 01:07:21,000 --> 01:07:24,000 [Binky] Co to jest? Dowiedz się o wskaźniki? 1235 01:07:24,000 --> 01:07:26,000 Oh, cukierek! 1236 01:07:26,000 --> 01:07:29,000 >> Do zobaczenia w środę. 1237 01:07:29,000 --> 01:07:32,000 [CS50.TV]