[MUZYKA GRA] David J. MALAN: Wszystko w porządku. To CS50. I to jest początek tygodnia 5. I jak można zauważyć, niektóre materiały jest trochę więcej kompleks, trochę gęstsza. I to jest bardzo proste, zwłaszcza jeśli masz w zwyczaju od jakiegoś czasu, próbuje się mazać się najbardziej cokolwiek robimy, mówimy w klasie. Ale sobie sprawę, że być może nie jest idealne podejście pedagogiczne do uczenia się tego rodzaju materiału, i materiał bardziej ogólnie. I tak jesteśmy zadowoleni, informujemy, że CS50 własnego Gheng Gong rozpoczęto przygotować kanoniczny zestaw nut na kurs, nadzieja która jest taka, że ​​jeden, to służyć nie tylko jako odniesienia i źródło do przeglądu i będzie materiał z powrotem przez materiał, który może mieć uciekł ci za pierwszym razem, ale również tak, że głowice mogą być bardziej w górę niż w dół, gdy go przychodzi czas na wykład, tak, że może zaangażować więcej w zamyśleniu, jak przeciwieństwie do bardziej scribbly. Z powiedział, że to, co znajdziesz na Strona jest takie dokumenty jak ten. Oraz informacja, w lewym górnym rogu, tam nie tylko spis treści, ale również kody czasowe które Ci natychmiast przeskoczyć do odpowiedniej części w wideo online. I co tu zrobiła Chang jest w istocie, udokumentowane co wydarzyło się w tym szczególności wykład. I wiele wykładów są już teraz z tego adresu URL. A my nadal dodawać pozostałą tych końca tego tygodnia więc nie skorzystać z tego zasobu. Więc bez zbędnych ceregieli, zaczęliśmy obierać powrót Warstwa, która ma być Ciąg na jakiś czas. A co możemy powiedzieć ciąg faktycznie jest w zeszłym tygodniu? Tak char gwiazda. I gwiazda char, dobrze, co czy to naprawdę oznacza? Cóż, tym razem, jeśli mamy było wywołanie funkcji, jak i przechowywania getString Tak zwane ponowne Wartość w getString zmienna-- to się nazywa s Typ string-- byliśmy pisania linii kodu tam powyżej. I to tylko wtedy, gdy widzę powiększony o pisma mogę sobie sprawę, jak okropna jest. Jednak załóżmy, że, po stronie prawej jest jednak, uzasadnione obraz tego, co jest trwa to wszystko razem z getString. getString oczywiście dostaje ciąg. Ale co to tak naprawdę oznacza? Oznacza to, że dostaje kawałek z pamięci systemu operacyjnego przez wywołanie funkcji, zwany malloc. Ale o tym później. A następnie zapełnia że fragment pamięci z literami użytkownik ma wpisany, a następnie, oczywiście, znak null, lub odwrotny ukośnik zera na samym końcu. W tym czasie, po stronie lewej tej historii, przez cały ten czas, byliśmy deklarowanie zmiennej, jak s. I to jest to, co teraz o zmiennej rozpocznie wywołanie wskaźnik. To nie pudełko, wewnątrz którego kładziemy ciąg, Daven, per se, ale raczej stawiamy w tym placu pole po lewej stronie, co dokładnie? Tak? PUBLICZNOŚCI: adres w którym to znajduje się w pamięci. David J. MALAN: Dokładnie. Adresu miejsca daven znajduje się w pamięci. , A nie tam, gdzie wszyscy Daven znajduje się, per se, ale w szczególności adres z czego? Tak? PUBLICZNOŚCI: Pierwszy znak. David J. MALAN: pierwszy znak w Daven, który, w tym przypadku, Zaproponowałem był arbitralnie i nierealistycznie 1, OX1, co oznacza po prostu liczba szesnastkowa z 1. Ale to prawdopodobnie będzie być znacznie większa liczba że możemy wyciągnąć z 0x na początku, reprezentujący znak szesnastkowy. A ponieważ nie musimy wiedzieć, gdzie Reszta bohaterów Daven są to, co prosta konstrukcja Decyzja, że ​​powstał wiele lat temu? Tak? PUBLICZNOŚCI: Backslash 0. David J. MALAN: Tak, dokładnie. Odwrotny ukośnik 0 pozwala, choć w czas liniowy, przemierzać ciąg, spacerem od lewej do prawej, z pętli for, lub chwilę pętla, czy coś , że i określić, o, tutaj jest koniec tego konkretnego napisu. Tak, tylko z adresu w początek łańcucha, możemy uzyskać dostęp do całości to, ponieważ przez cały ten czas, Ciąg został właśnie gwiazda char. Więc to na pewno dobrze, aby kontynuować korzystanie z Biblioteka CS50 i to abstrakcja, że tak powiem, ale będzie rozpocząć, aby zobaczyć dokładnie, co się dzieje pod tym cały czas. Więc może pamiętacie ten przykład, też, od ostatniego czasu, porównać 0, które rzeczywiście nie porównać. Ale zaczęliśmy rozwiązać. Ale jak może odświeżające, I może zainteresować kogoś w różowym słoniu dziś również przez Chang? Jak o tobie z przodu? [Niesłyszalne]. Chodź na górę. A w międzyczasie, jak można wymyślić, niech rozważyć na chwilę, co Kod ten faktycznie robi. To deklarując dwie zmienne się Najwięcej, s i t, i wzywając getString. Nie jest bardzo przyjazne dla użytkownika program dlatego, że nie mówi ci co masz robić. Ale niech tylko zakładać, że jesteśmy koncentrując się na soczyste części. A potem my, jeśli s jest równa wynosi t, należy powiedzieć printf, wpisane to samo. Witaj. Jak masz na imię? Janelle: Janelle. David J. MALAN: Janelle, Miło cię poznać. Więc twoim wyzwaniem Ręka do tego słonia jest najpierw zwrócić nam obraz tego, co znajduje się są reprezentowane w tych pierwszych dwóch linie. Więc s i t mogą być reprezentowane, jak na ekranie? A może po prostu wyciągnąć go z palec na tym dużym ekranie. Więc nie dwie połówki do każda strona tego równania. Więc nie ma a po lewej stronie, a następnie getString po prawej stronie. A wtedy nie t po lewej stronie, i GetString prawej. Więc jak możemy zacząć rysunek obraz, który reprezentuje to, co się dzieje tutaj w pamięci, można by powiedzieć? I niech mi pozwolić wyjaśnić to, co robisz, jak jesteś. Janelle: OK. Cóż, po pierwsze, że będzie pytać , aby uzyskać ciąg wejściowy. I to store-- och, przepraszam. David J. MALAN: OK. Dobry. I to się nazywa, co? Och, OK. Trzymaj się. Nie chciałam przeszkadzać. Janelle: Przepraszam. Więc to go do wejścia Adres nie of-- pewno. Nie potrafię dokładnie pamiętam numeru, ale uważam, że to było od 0. David J. MALAN: To wszystko prawda, bo zrobiłem numery się, więc nie ma dobrej odpowiedzi. Janelle: Począwszy od 0 łuku. David J. MALAN: OK, więc elementem 0. Jasne. Janelle: A jeśli było jak tylko dwa-letter-- David J. MALAN: OK, z powrotem do Ciebie. Janelle: Tak Element 0, a następnie elementem 1 lub 2 Element. David J. MALAN: A który kawałek obraz rysujesz teraz? Wezwanie do getString? Lub deklaracja s? Janelle: deklaracja S, wierzę. Och, getString, bo to by być wprowadzane do każdego [? obszar. ?] David J. MALAN: Dobra. Dokładnie. Pomimo tego, że skuteczny Zwraca tablicę, przypomnieć, gdy wrócimy ciąg, możemy Indeks do tego łańcucha przy użyciu 01 i 2. Technicznie, to prawdopodobnie przedstawiciele poszczególnych adresów, ale to jest w porządku. Więc przypuszczam, jeśli mogę tak szybko przesyłają którym skończyliśmy Ostatnim razem, gdy jedna z struny było g b e, backslash 0, a tym samym stanowiących Gabe'a Wejście, jak możemy reprezentować s teraz? Jeśli jest to pamięć, która jest zostały zwrócone przez getString? Janelle: Czy jest reprezentowane przez łuk? David J. MALAN: łukiem? Cóż, nie. Powiedzmy tylko, obrazowo, Pozwólcie mi iść do przodu i zaproponowanie, że jeżeli jest to, ten jest wartość zwracana getString. A ty, jak wyciągnąć to 0, 1, 2, które jest całkowicie uzasadnione, ponieważ my może wskaźnik do łańcucha, jako takie. Ale tylko być zgodne z Ostatni raz, pozwól mi iść do przodu i zaproponować, że arbitralnie jest adres 1, to jest adres 2, jest to adres 3 i tak dalej. I tak, po prostu, aby być super jasne, co się dzieje iść s w wyniku tego Pierwsza linia kodu, można by powiedzieć? Janelle: Adres 1? David J. MALAN: Dokładnie. Więc zająć 0x1. A tymczasem, pozwól mi iść do przodu i powielić wiele z tego, co zrobiłeś i dodać moje własne t tutaj. Gdybym wpisać Gabe znowu, po raz drugi, gdy pojawi się monit z getString, gdzie, Oczywiście, jest Gabe zamiar iść? Cóż, presumably-- Janelle: Podobnie jak tutaj? David J. MALAN: Tak. Janelle: Albo jest to również w tych samych polach? David J. MALAN: Pozwól mi zaproponować, tak, dokładnie, a więc w tych dodatkowych pól. Ale co jest teraz to, że klucz, nawet choć mam wyciągnąć te całkiem blisko together-- 0x1, to jest 0x2-- w rzeczywistości, Teraz może być to adres 0x10, na przykład, a 0x11 i 0x12, i tak dalej. I tak, jeśli o to chodzi, co się w końcu tutaj w t? Janelle: 0x10? David J. MALAN: Dokładnie. Więc 0x10. I tak teraz, ostatnie pytanie. Zostały, jak dotąd, musiały pracować Najtrudniejszą dla słonia do tej pory. Teraz, jeśli podciągnąć kod ponownie, gdy ja, w trzeciej linii, jeśli y jest równa jest równa t, co ja właściwie porównanie, że mamy wyciągnąć tutaj? Janelle: Dwa adresy? David J. MALAN: Dokładnie. Więc mówię, jest y równa równa t? Innymi słowy, jest równa 1 równą 10? Oczywiście, Oczywistą odpowiedzią jest teraz, nie. I tak ten program jest ostatecznie będzie drukować, co, można by powiedzieć? Janelle: Czy byłoby, wpisane to samo? David J. MALAN: Więc jeśli s oznacza 1, a t wynosi 10? Janelle: Wpisano różne rzeczy. David J. MALAN: Dokładnie. Wpisano różne rzeczy. Wszystko w porządku. Więc brawa, jeśli można, tutaj. [Aplauz] To było bolesne. Wiem. Ładnie wykonane. Teraz zobaczmy, czy nie możemy odciąć to, co było naprawić. I oczywiście, kiedy stała to-- które będę teraz reprezentować w green-- zrobiliśmy kilka ulepszeń tutaj. Po pierwsze, tak jak normalności sprawdzić, jestem pierwszym sprawdzeniu jeśli y jest równa wartości null i t równa NULL. I żeby była jasność, kiedy może s lub t być null w kodzie jak to? Kiedy może s lub t być null. Tak? PUBLICZNOŚCI: [niesłyszalne]. David J. MALAN: Dokładnie. Jeśli ciąg znaków, który użytkownik wpisany jest zbyt długi w celu dopasowania do pamięci, albo niektóre dziwna sprawa rogu tak, getString, jak zobaczymy, dosłownie dzisiaj, w jego dokumentacji, mówi, że zwróci null jako Szczególna wartość sentinel, lub po prostu rodzaj specjalny symbol co oznacza, że ​​coś poszło nie tak. Dlatego chcemy, aby sprawdzić, , że z powodu okazuje że wartość null jest bardzo niebezpieczne. Często, jeśli starają się zrobić coś z wartość null udziałem function-- przekazania go jako wejście dla instance-- tej funkcji może bardzo padnie, a wraz z nim, zdjąć cały program. Więc to trzecia linia jest teraz po prostu zdrowy rozsądek sprawdzić, sprawdzanie błędów, jeśli będzie. To jest dobry zwyczaj teraz nam się dostać do każdej chwili możemy spróbuj użyć wartości, które może potencjalnie być null. Teraz, w czwartej linii tutaj, "Jeśli strcmp (s, t)," dobrze, co to na myśli? Cóż, powiedział, że to bardzo krótko o nazwie funkcja porównania ciągów. A jego celem w życiu jest do porównania jej pierwszy argument przeciwko nim drugi, , ale nie pod względem ich adresami jak my nieświadomie chwila temu z czerwonego kodu, ale raczej porównać te dwie sznurki w intuicyjny po ludzku Sposób porównując to na tym, wobec tego na tym, a Następnie zatrzymywania wtedy, gdy jeden lub oba palce uderza odwrotny ukośnik 0. Więc ktoś lat temu realizowane strcmp do wdrożenia dla nas funkcjonalność że mamy nadzieję, że dostaliśmy tylko przez porównanie dwóch prostych wartości. Teraz szczerze, trzymam rysunek wszystkie z tych różnych ilościach. Ale rzeczywistość jest taka, że ​​byli co to się cały czas. A więc pozwól mi tylko iść do przodu i mazać te z do punktu, że na końcu dnia i do przodu, nie jesteśmy naprawdę będzie dbać o co dotyczy rzeczy są rzeczywiście w pamięci. Więc nie będę rysować te rodzaje numerów już tak dużo, Jestem tylko to streszczenie dala trochę bardziej przyjazny, z zaledwie strzałkami. Innymi słowy, gdy s jest wskaźnik, dobrze, po prostu wyciągnąć go, dosłownie, jako wskaźnik, strzałka skierowana z Sam na coś innego, i nie martw się o zbyt wiele bardziej minucja z tych adresów które ponownie, zrobiłem się tak. Ale zobaczymy te adresy, Czasami, podczas debugowania kodu. Teraz zaś, w ramach programu tu poprawki, oczywiście, ten problem przez porównanie te dwa ciągi. Ale wpadł na inny problem. To był z kopii zaprogramować ostatni raz, przy czym, starałem się wykorzystać tylko pierwszy znak w ciągu znaków. Ale to, co było objawem widzieliśmy ostatni raz, kiedy użytkownik wpisze w wartości, jak Gabe małymi literami, na południe, potem przypisane s do t, w trzecim wierszu, a następnie próbowałem wykorzystać t wspornik 0? Jaki był efekt zmianę t wspornik 0 tutaj? PUBLICZNOŚCI: To zmieniło s. David J. MALAN: Tak, Zmienione S, jak również. Bo to, co się naprawdę dzieje? Cóż, pozwól mi zobaczyć, czy mogę wyczyścić do tego obrazu, jak następuje. Jeśli S jest znowu słowo g A, B, E, odwrotny ukośnik, 0 i y będziemy kontynuować rysunku jako pole tutaj, ale nie więcej adresów. Zatrzymajmy dokonywania rzeczy. Po prostu narysować obrazek uproszczenie świat. Kiedy Oświadczam t sznurkiem t, który tworzy ten fragment pamięci. Plac dzieje się 32 bity w większości komputerów. W rzeczywistości, jeśli kiedykolwiek słyszał Komputer ma strukturę 32-bitowego bardzo fantazyjne-mówią, że tylko oznacza to, że korzysta z adresów 32-bitowych. I jako techniczne na bok, Jeśli kiedykolwiek zastanawialiście się, dlaczego starsze komputery, jeśli rzeczywiście próbował zupy je z dużą ilością pamięci RAM, może mieć tylko maksimum czterech gigabajtów pamięci RAM, dobrze, że to, dlatego, że dosłownie, Twój stary komputer może tylko Ilość aż 4 miliardów, 4 miliardy bajtów, dlatego, że był przy użyciu 32-bitowego Numery adresów. Ale w każdym przypadku, w tym przykład, historia jest o wiele prostsze. t tylko kolejny wskaźnik, lub naprawdę gwiazda char, aka ciąg. I jak chcę zaktualizować tego obrazu teraz z tej drugiej linii kodu, po kropce, kropka, kropka? Kiedy zrobić łańcuch t jest równa s średnik, W jaki sposób zmienić ten obraz? Tak? PUBLICZNOŚCI: [niesłyszalne]. David J. MALAN: Tak. Dokładnie. I po prostu umieścić strzałę z t Skrzynka na ten sam adres, sama pierwsza litera w dali. Lub technicznych, jeżeli Facet wciąż na 0x1, To tak, jakbym miał 0x1 i 0x1 tutaj, tutaj. Ale znowu, kto dba o adresy? To tylko pomysł, który teraz liczy. Więc to jest to, co się tutaj dzieje. Tak, oczywiście, jeśli nie t wspornika 0, co jest zapis tablicy, z course-- i szczerze mówiąc, wygląda jak jest tu tablica, ale teraz nie jest to dziwne. Wiedzieć, że język programowania, C, oferuje tę funkcję, w którym nawet, jeśli t Wskaźnik lub S jest wskaźnikiem, nadal można korzystać, które zna, wygodne nawias kwadratowy notacji, aby przejść do pierwszego elementu, lub drugi element lub każdy element , które wskazuje, że wskaźnik się, bo zapewne go jest, jak w tym przypadku, wskazując na jakąś tablicę. Jak więc rozwiązać ten problem? Szczerze mówiąc, to gdzie to ma trochę przytłaczająca na pierwszy rzut oka. Ale tutaj jest nowa i ulepszona wersja. Więc po pierwsze, jestem coraz pozbyć biblioteki CS50, żeby odsłonić że s jest rzeczywiście gwiazdkowy char, po prostu synonimem. I t jest również gwiazdą char. Ale to, co dzieje się na po prawej stronie tej linii gdzie t jest przypisana wartość? Co to jest malloc? Co to strlen? Co to jest sizeof (char)? Dlaczego do cholery robi to Linia tak skomplikowane spojrzenie? Co on robi na wysokim poziomie? Co to przechowywanie w t? Tak? PUBLICZNOŚCI: To przydzielania pewna ilość pamięci. To jest do przechowywania, jak sądzę, Litery [niesłyszalne]. David J. MALAN: Perfect. Idealny. To alokacji pewne ilość miejsca w pamięci do przechowywania, przypuszczalnie przyszłe liter. A w szczególności, malloc jest zatem powrót co? PUBLICZNOŚCI: Przywracanie [niesłyszalne]? David J. MALAN: Dokładnie. Wracając adres tej pamięci, która jest fantazyjny sposób na powiedzenie, zwraca adres Pierwszy bajt tej pamięci. Spoczywa na mnie, aby pamiętać, ile pamięci faktycznie przyznane lub zapytał malloc dla. Teraz, ile to jest? Cóż, nawet jeśli nie Wiele nawiasach tutaj malloc zajmuje tylko jeden argument. A ja określając strlen S, więc dać mi, jak wiele bajtów, ile jest w sekundach, ale dodać. Dlaczego? Tak? PUBLICZNOŚCI: backslash 0. David J. MALAN: Dokładnie. Musimy zrobić trochę sprzątanie. Tak, bo jest odwrotny ukośnik 0, to lepiej o tym pamiętać. W przeciwnym razie będziemy aby utworzyć ciąg nie ma to specjalnego terminator. Tymczasem, po prostu być super anal, mam sizeof (char), tylko w przypadku gdy ktoś uruchamia Mój Kod nie na urządzeniu CS50, ale może inny komputer łącznie, gdzie znaki to jeden bajt, zgodnie z konwencją, ale dwa bajtów, lub coś większego niż to. To jest po prostu być super, bardzo niechętna do błędów. Mimo, że w rzeczywistości jest to najprawdopodobniej będzie 1. Teraz, w międzyczasie, śmiało i skopiować ciąg, t wynosi t uchwyt i wspornik s. A ja odłożyć do zeszłotygodniowej kod źródłowy, aby zobaczyć, co się dzieje. Ale klucz na wynos, i Powodem umieścić kod teraz w kolorze zielonym, Jest tak dlatego, że w ostatniej linii, t Uchwyt 0 równa toupper, skutkuje kapitalizacji, które ciąg? t i / lub s? Ta ostatnia linia kodu. Tylko t, bo to, co jest się tym razem, jeśli nieco cofnąć ostatni krok, co się stało jest, gdy zgłoszę malloc, I w zasadzie dostać kawałek pamięci , że ma taki sam rozmiar jak oryginał, bo to arytmetyka zrobiłem. Jestem przechowywania t adres tego fragmentu pamięci. Pomimo tego, że ładnie wygląda i ładne, ładne i puste, Rzeczywistość jest tam, co będzie wzywasz, wartości śmieci tutaj. Że kawałek pamięci może bardzo dobrze zostały wykorzystane wcześniej, kilka sekund, kilka minut temu. Więc nie może absolutnie być liczbami lub litery tam, po prostu przez przypadek. Ale nie są ważne, dopóki nie ja zapełnić ten fragment pamięci z rzeczywistych znaków, jak atrakcje, które dla pętli tam. Wszystko w porządku? Więc teraz, punkt kulminacyjny Te trzy przykłady które pozornie uszkodzony ostatni raz, Przykład ten wymiany, funkcja pracował w tym sensie, że zamieniłem a i b. Ale to nie działa w jakim innym sensie? Tak? PUBLICZNOŚCI: [niesłyszalne]. David J. MALAN: Dokładnie. Gdybym miał wywołać tę funkcję od another-- na przykład z funkcji, takich jak główne, gdzie Mam zmienne X i Y, jak w zeszłym tygodniu, sam kod, i przechodzą w x i y do wymiany, a następnie zadzwonić Swap-- tego, Oczywiście, jest poprawna wersja jest to, co mamy zamiar see-- to nie działa. Więc co jest poprawka? Cóż, tak właśnie być jasne, pozwól mi iść do przodu i-- dać mi chwilę tutaj i zobacz czy mogę pokazać ci ostatni, który będzie in-- zobaczmy, czy mogę znaleźć to prawdziwy fast-- OK, [niesłyszalne]. OK, nie jest to. Więc ignorować polecenia Ja tylko pisać. Chcę, aby pobrać na Przykładem ostatniej chwili z ostatniego czasu, które nazywa się teraz nie zmienne. Zmiennych jest tak, gdzie nie skończyliśmy ostatnim razem, przy czym, to zainicjowany x i y na 1 do 2. Następnie zadzwonić Zamień, przekazując 1 i 2. I wtedy ta funkcja pracował w pewnym sensie, ale nie miał stałego Wpływ na x i y. Więc pytanie pod ręką jest, jak teraz możemy rzeczywiście rozwiązać ten problem? Jakie jest rozwiązanie w zasięgu ręki? Cóż, w swap.c, który jest nowy dzisiaj dostrzec kilka różnic. x i y są takie same. Ale to, co jest wyraźnie różne o linię 25? Co nowego jest, jeśli pamiętać jak to wyglądało godziny temu? PUBLICZNOŚCI: [niesłyszalne]. David J. MALAN: Tak. Tak więc Ampersands są nowe piece składni nie tylko w tym programie, ale także bardziej ogólnie w CS50. Do tej pory, nie sądzę, widzieliśmy żadnych przykładów czy naprawdę mówił o nich w dowolny szczegóły, inne niż, być może, zapobiegawczo w przekroju, handlowego i tak. Cóż, okazuje się, handlowego i jest jednym z ostatnich kawałków nowej składni będziemy się uczyć. Wszystko to oznacza, adres jakiejś zmiennej. Na jaki adres ma x żyć? Ale jaki adres ma y mieszka? Bo jeśli Podstawowym problemem przed było to, że X i Y były przekazywane jak kopie, co tak naprawdę chcemy robić jest zapewnienie SWAP z jak skarb mapę, która prowadzi do miejsca, gdzie x i y faktycznie znajdują się w pamięci RAM, żeby Zmienne mogą śledzić tę mapę i iść tam, gdzie x i y oznacza miejsce i zmienić wartości rzeczywiste 1 i 2 tam. Zmienne musi więc lekko zmienić też. I na pierwszy rzut oka, to siła wydawać się nieco podobna do gwiazdy char. I rzeczywiście tak jest. Tak jest wskaźnikiem do jakiego typu danych, na podstawie tego zaznaczonego fragmentu? Więc jest to int. Więc już nie jest int, to adres wew. Podobnie, B będzie teraz być adres int. Więc kiedy teraz zadzwonić Zamień z główną, Nie zamierzam dać SWAP 1 i 2. Mam zamiar dać go jak Wół Wół coś i coś, dwa adresy, które będą prowadzić Zmienne do ich rzeczywistych lokalizacjach w pamięci mojego komputera. Więc teraz, mój pozostały realizacji musi się zmienić odrobinę. Co jest oczywiście inna teraz w tych trzech linii kodu? Nie wszystkie te cholerne gwiazdkowych na miejscu, wszystko w porządku? Więc co tu się dzieje? Tak? PUBLICZNOŚCI: To oczywiście [niesłyszalne]. David J. MALAN: Dokładnie. Tak więc w tym context-- i nie było najlepsza decyzja projektowa, prawda, lat temu. W tym kontekście, w którym wystarczy gwiazdę, i nie ma typu danych, jak int, bezpośrednio po lewej stronie, a nie masz znak równości, jasno, w związku z tym, kiedy mówisz gwiazda, to znaczy przejść do adres, który znajduje się w. Śledzić mapę skarbów, że tak powiem. A tymczasem w linii 37, oznacza to samo. Idź do adresu A, i umieścić to, co tam jest? Cokolwiek jest miejsce, które b określa. Innymi słowy, przejdź do b. Uzyskać tę wartość. Przejdź do, a na równi podpisać, operator przypisania, umieścić tę wartość tam. Podobnie, int temp jest tylko int. Nic nie musi się zmienić o temp. To tylko szkło z Annenberg zapasowe jakiegoś mleka lub soku pomarańczowym. Ale trzeba powiedzieć, przejdź do b. Idź do tego celu i umieścić wartość w temperaturze nie. Więc co się dzieje potem? Kiedy rzeczywiście wywołać Zamień ten czas, jeśli ten pierwszy reprezentuje Główny podajnik tutaj, ten drugi podajnik oznacza swap, gdy Mijam Ampersand X oraz handlowego y z Main do wymiany, tak aby było jasne, co to jest ramka stosu odbiorcza? Tak? PUBLICZNOŚCI: [niesłyszalne]. David J. MALAN: Dokładnie. Adres adres x i y. A może myślisz o nich jak adresy pocztowe. 33 Oxford Street i 35 Oxford Street, a ty chcą przenieść dwa budynki które są w tych miejscach. To trochę śmiesznej idei, ale to wszystko rozumiemy przez adres. Gdzie na świecie można można znaleźć te dwa ints? Gdzie na świecie można znaleźć te dwa budynki? Więc jeśli w końcu, po tak długim czasie I idź do dzisiejszego kodu źródłowego i skompilować Zmienne i uruchomić ./swap wreszcie na raz pierwszy możemy zobaczyć, że w rzeczywistości Rzeczywiście moje wartości mają zostały zamienione pomyślnie. A teraz możemy nawet zabrać Wzmiankę o tym, powiedzmy, w gdb. Więc pozwól mi iść do tego samego pliku. Pozwól mi iść dalej i uruchomić gdb z ./swap. A teraz, w swap, mam zamiar iść do przodu i ustawić punkt przerwania w Main. A teraz mam zamiar iść dalej i uruchomić program. A teraz widzimy, mój kod Przerwał na tej linii. Jeśli pójdę do przodu i drukuj x, co powinienem zobaczyć tutaj? To jest pytanie. Jeszcze raz? PUBLICZNOŚCI: [niesłyszalne]. David J. MALAN: Tak liczby losowe, może. Może mi się poszczęści, i to ładne i proste, jak 0. Ale być może jest to jakiś losowy numer. W tym przypadku, mam szczęście. To właśnie dzieje się 0. Ale to jest naprawdę szczęście, ponieważ dopóki nie wpisz obok print x, a następnie, że ma linii kodu, linia 19, zostały wykonane. Tymczasem, jeśli napiszę następny raz, i teraz wydrukować y, mam zamiar zobaczyć 2. Teraz, jeśli napiszę następny, to będzie trochę mylące, bo teraz, printf będzie umieszczony na Ekran, jak to zrobił. x oznacza 1. Zróbmy to jeszcze raz. A teraz, tutaj, gdzie robi się ciekawie. Zanim zadzwonię Zamień lub nawet krok do niego, weźmy trochę zerknąć. x jest znów 1. Y jest oczywiście szybkie rozsądku sprawdzić, 2, więc nie trudno tam. Ale to, co jest Ampersand x? Odpowiedź, to rodzaj funky patrząc. Ale int gwiazdki w nawiasach jest tylko sposób GDP mówiąc to jest adres. To nie int, to wskaźnik do int, lub w inny sposób znany jako adres. Co to jest szalone rzeczy? Nigdy nie widziałem czegoś zupełnie jak wcześniej. Więc jest to adres w moim komputerze jest pamięci, gdzie x dzieje się żyć. Wół to jest coś. I to jest, szczerze mówiąc, dlaczego Zacząłem strzałki rysunek, zamiast cyfr bo kto naprawdę troszczy się że int jest w szczególności adres, który jest tak duży. Ale bffff0c4, to wszystko rzeczywiście cyfry szesnastkowe, które są od 0 do f. Więc nie będziemy mieszkać zbyt długo na to, co te rzeczy są. Ale jeśli mogę wydrukować y, Oczywiście, widzę 2. Ale Ampersand y, widzę ten adres. Oraz informacja, na nowoczesny, jak daleko od siebie są X i Y? Można zignorować większość adres. Cztery bajty. I to jest zgodne z naszymi wcześniej twierdzą, że jak duże jest int? Cztery bajty. Wygląda więc na to wszystko za okładziny ładnie, jak można mieć nadzieję, w pamięci. Więc teraz, po prostu do przodu do końca tej historii. Idziemy dalej i wpisz krok, do nurkowania w swap. Zauważcie, jeśli typ, to identyczne pod adresem x. Gdybym typu B, to jest identyczne na adres R. Więc co mam sprawdzić, czy ja powiedzieć, przejdź do adresu w? Więc drukować gwiazda. Więc tam gwiazda oznacza w tym kontekście. Handlowe oznacza co adres. Więc gwiazda środki 1. I gwiazda druku b daje mi 2. I pozwól mi zakładać, w tej chwili, że co najmniej kod przystępuje do wykonania może być teraz uzasadniona przez w ten sposób. Ale my ponownie ten pomysł przed długo. Więc ta wersja swap jest poprawne i pozwala nam zamienić ten szczególny typ danych. Więc jakieś pytania to na swap? Na gwiazdy? Na adres? A zobaczysz, ze Problem zestaw 4, rodzaj, ale problem, zestaw 5, na pewno, jak to rzeczy są przydatne i dostać dużo więcej wygodne z nich, w wyniku. Cokolwiek? Wszystko w porządku. Więc się przydzielić jest znowu funkcja że po prostu przydziela pamięć, pamięć alokacji. I dlaczego jest to przydatne? Cóż, przez cały ten czas, już przy malloc. Jeżeli uważasz, że teraz, jak getString prace, prawdopodobnie, to pytali kogoś na fragmencie pamięci, w każdej chwili użytkownik wpisze ciąg w, bo na pewno nie wiem, jak personel CS50, jak duże te struny, które ludzie zamiar wpisać może być. Warto więc, po raz pierwszy, od początku do oderwij jak działa biblioteka CS50, za pomocą kilku przykładów, że doprowadzi nas tam. Więc jeśli ja otworzyć gedit i otworzyć scanf 0, jedziemy zobaczyć następujący kod. Scanf 0, dostępne na stronie internetowej dzisiaj, ma stosunkowo mało linii kodu o, 14 do 20. I zobaczmy, co robi. Deklaruje, zwany int x. To mówi coś takiego, numer należy. A teraz mówi, scanf% i, i x. Więc jest kilka nowych rzeczy tam. Ale scanf, można trochę pomyśleć jako przeciwieństwo printf. printf, oczywiście, druki do ekranu. scanf rodzaj skanowania od użytkownika coś klawiatury on lub ona wpisana. % I jest jak printf. Oznacza to spodziewać użytkownikowi wpisać int. A teraz, dlaczego myślisz, że może być przechodząc scanf & X? Jeśli celem w życiu scanf jest dostać coś od użytkownika, jaki jest sens mijając go, & x, teraz? Tak? PUBLICZNOŚCI: [niesłyszalne]. David J. MALAN: Dokładnie. Cokolwiek, ludzki, wpisać, moje wejście zostanie zapisany w tej lokalizacji. To nie wystarczy, przypominam, po prostu przejść w X, bo już widać, za każdym razem przechodzą tylko zmienną surowego, jak int, do innej funkcji, Oczywiście, że może się zmienić zmienne, ale nie na stałe. To nie może mieć wpływu na główną. Może tylko zmienić swoją lokalną kopię. Ale jeśli zamiast, nie musisz daj mi rzeczywiste int, ale możesz dać mi wskazówki do że int, I teraz, będąc scanf, pewnie, że mogę podążać adres i umieścić tam kilka więc masz do niego dostęp, jak również. Więc kiedy uruchomić ten program, zobaczymy. Dodać scanf 0 dot slash, scanf 0. I jeśli teraz wpisać liczbę jak 50, dzięki za 50. Gdybym teraz jak wpisać numer ujemny 1 ujemnej 1. Teraz wpisz numer jak 1,5, hm. Dlaczego mój program ignoruje mnie? No, bo po prostu, powiedziałem to można oczekiwać tylko int. Wszystko w porządku. Więc to jest jedna wersja tego. Weźmy się w garść i zaproponować, że to nie jest dobre. I tu leży bardzo prosty przykład w jaki sposób możemy rozpocząć pisanie kodu że inni ludzie mogą wykorzystywać lub kompromisu robiąc złe rzeczy. Tak więc linia 16, tak podobny w duchu, aby wcześniej, ale nie jestem oświadczając, że int ten czas. Jestem deklarowania char gwiazdę, aka ciąg. Ale co to tak naprawdę oznacza? Tak więc, jeśli nie określić address-- i Dzwonię go dowolnie, bufor, ale mogę nazwać to s, być simple-- , a następnie zrobić to, wyjaśnij mi, jeśli można, w oparciu o poprzednie logika, co robi w scanf linii 18, Jeśli upłynie% s i buforem, który jest adres? Co to jest scanf, jeśli stosuje się dokładnie taka sama logika jak w wersji 0, Spróbuję zrobić tutaj, kiedy coś, co użytkownik wpisze w? Tak? PUBLICZNOŚCI: [niesłyszalne]. David J. MALAN: Dokładnie. Scanf, przez logikę wcześniej, zajmie ciąg że ludzki pisanych in-- to teraz ciąg, to nie jest liczba, prawdopodobnie, jeśli on lub ona cooperates-- i to będzie starał się umieścić, że ciąg w pamięci na dowolnym adresem bufora określa. I to jest wspaniałe, ponieważ bufor jest rzeczywiście przeznaczona do adresu. Ale twierdzą, ten program jest wadliwy w bardzo poważny sposób, ponieważ to, co jest wartością Domyślnie bufor? Co ja zainicjowany w? Co kawałek pamięci? I nie ma, prawda? Więc nawet jeśli mam przydzielone char, że gwiazda nie nazywa s, to zamiast nazwie, buffer-- tak narysujmy nazwę zmiennej teraz jak buffer-- jeśli nie mają nazywa getString lub malloc tutaj że w rzeczywistości oznacza, że Bufor to tylko niektóre wartości śmieci. Teraz co to oznacza? Oznacza to, że powiedziałem scanf oczekiwać ciąg od użytkownika. I wiesz co? Niezależnie od tego, co wskazuje to-- i rysuję znak zapytania, ale w rzeczywistości, to będzie coś OX1, 2, 3, prawda? To niektóre fałszywe wartości, które po prostu dzieje się tam z przed. Więc innymi słowy, jest to jakby bufora tylko wskazując na coś w pamięci. Nie mam pojęcia co. Więc jeśli teraz wpisać Gabe, to będzie próbować umieścić g-a-b-e / 0 tam. Ale kto wie, co to jest? I w przeszłości, każde czas staraliśmy się dotknąć pamięcią, które nie należą do nas, co się stało? Lub prawie za każdym razem. Błąd segmentacji, prawda? Ta strzałka, nie mam pojęcia, gdzie jest to wskazującego. to tylko kilka losowych wartości. I oczywiście, jeśli interpretować wartość losowa jak adres, masz zamiar udać się do jakiś przypadkowy przeznaczenia. Więc mógłby rzeczywiście katastrofa Gabe mój program w tym przypadku. Więc co możemy zrobić, to prawie tak złe? Rozważ to trzeci i Ostatnim przykładem scanf. Ta wersja jest lepsza w jakim sensie? Jeśli są wygodne z poprzednie problem ten jest lepszy. Dlaczego? PUBLICZNOŚCI: [niesłyszalne]. David J. MALAN: Dobra. Więc w tym przypadku linii 16 jest korzystniejsze, w sensie że jesteśmy wyraźnie alokacji trochę pamięci. Nie używasz malloc, używamy tygodniu 2 podejście po prostu deklarując tablicę. A my już powiedziałem, że ciąg tylko szereg znaków tak, to jest całkowicie legalne. Ale to, oczywiście, jak pamiętać, stały rozmiar, 16. Więc ten program jest całkowicie bezpieczne, jeśli typ w ciągi jednego znaku, dwóch znaków łańcuchy, 15 łańcuchów znaków. Ale jak tylko zaczniesz wpisywać 16, 17, 18, 1000 ciągi znaków, gdzie jest, że łańcuch skończy? To się w końcu częściowo tutaj. Ale kto wie, co jeszcze jest poza granicami tej konkretnej tablicy? To tak, jakbym zadeklarowane 16 pola. Więc zamiast wyciągnąć wszystkie 16, to będzie udawać, że mam wyciągnąć 16. Ale jeśli spróbuj przeczytać ciąg to o wiele dłużej, jak 50 znaków, Mam zamiar rozpocząć wprowadzanie , b, c, d, x, y, z. A to przypuszczalnie inny segment pamięci które znów może powodować mój program do katastrofy, bo ja nie prosiłem o coś więcej niż tylko 16 bajtów. Więc kogo to obchodzi? Cóż, tutaj jest biblioteka CS50. I większość z tego jest tylko jak instrukcje do góry góry. Biblioteka CS50, przez cały ten czas, miał ten wiersz w wierszu 52. Widzieliśmy typedef lub zobaczysz typedef w Pset 4, który właśnie tworzy synonimem którym gwiazda char może być więcej określany po prostu jako ciąg. Tak więc jest to jeden z Kilka kółka używaliśmy potajemnie pod maską. Tymczasem tutaj jest funkcja getchar. Teraz widać, że nie ma do niej ciało. I rzeczywiście, jeśli trzymam przewijanie, nie wiem właściwie zobacz wszystkie realizacje z tych funkcji. Jako kontrola poprawności, to dlaczego? PUBLICZNOŚCI: [niesłyszalne]. David J. MALAN: Tak. Więc to jest nagłówek pliku. I pliki nagłówkowe zawierają prototypy, plus kilka innych rzeczy, jak się wydaje, jak typedefs. Ale w CS50.c, które mamy Nigdy wam wprost, ale nie było w ogóle urządzenia CS50 Tym razem, w głębi swoich folderów, zauważyć, że istnieje cały kilka funkcji w tutaj. W rzeczywistości, niech przewijać. Zignorujmy większość z nich, do teraz. Ale przejdź do getInt i zobaczyć, jak getInt działa. Więc tutaj jest getInt. I jeśli kiedykolwiek naprawdę zależało, jak uzyskać int działa, tutaj jest jego dokumentacja. I wśród rzeczy mówi, to mówi, jakie są zakresy wartości może powrócić. Jest to w zasadzie negatywne 2000000000 do pozytywnego 2000000000, lub dać. I jak się okazuje, to wszystko czas, mimo że nigdy nie nie można sprawdzić na nim, jeśli coś pójdzie nie tak, okazuje się, że wszystkie Ten czas ma getInt powróciła specjalne stała, nie jest pusta, lecz INT_MAX, który jest Konwencja tylko programisty. Oznacza to, tutaj jest szczególną wartością. Upewnij się, aby sprawdzić, czy to po prostu w przypadku gdyby coś poszło nie tak. Ale nigdy nie przeszkadzało konsekwencji do tej pory ponieważ, tym Ma to uprościć. Ale jak getInt się wdrożyć? Cóż, jeden, że nie wymaga żadnych argumentów. Wiemy, że. Zwraca int. Wiemy, że. Więc jak to działa pod maską? Więc nie ma widocznie nieskończony Pętla przynajmniej jednego wygląd. Zauważ, że używamy getString. Więc to jest interesujące. getInt zwraca nasza funkcja, getString. A teraz, dlaczego to może być przypadek? Dlaczego jest defensywa tutaj w linii 165? Co może się stać w kolejce 164, po prostu być jasne? To ta sama odpowiedź, jak wcześniej. Może być tylko z pamięci. Coś jest nie tak z getString, Musimy być w stanie sobie z tym poradzić. I powodem nie wrócę null jest że, technicznie, null jest wskaźnik. getInt musi powrócić int. Więc mam arbitralnie zdecydował, zasadniczo, że 2 mld euro, lub dać, będzie za szczególną wartość, że nie mogę rzeczywiście się od użytkownika. To tylko jedna wartość idę odpadów do reprezentowania kod błędu. Więc teraz, robi się trochę kręci. I to nie jest to samo, funkcja jak wcześniej, ale to jest bardzo podobne. Więc zauważyć, oświadczam tutaj, w linii 172, zarówno int n i char c. A potem użyć tego modny linię, sscanf, który okazuje się nie skanuje ciąg znaków z klawiatury. To oznacza, że ​​istniejący ciąg użytkownik został już wpisany. Więc ja już, co nazywa getString Oznacza mam ciąg w pamięci. sscanf jest to, czego bym wywołać funkcję analizowania. To wygląda na ciąg Mam wpisany, znak po znaku, i robi coś pożytecznego. Ten ciąg jest przechowywany w jednej linii. I wiem, że tylko przechodząc kopię zapasową tutaj i mówiąc, oh, OK, Nazwałem go nie s to czas, ale linia. A teraz to jest trochę inaczej. Praktycznie oznacza to jednak, ze względów my trochę pomachać na dziś nasze ręce, które sprawdzają się sprawdzić, czy użytkownik wpisał w i int a może inny charakter. Jeśli użytkownik wpisze w int, to zamierza się przechowywać w N, ponieważ ja przechodzącej przez ten adres, nowa sztuczka widzieliśmy dzisiaj. Jeśli użytkownik wpisze także w jak 123x, że x zamierza skończyć List w postaci c. Teraz okazuje się, że sscanf powie mi, inteligentny, jak wielu zmiennych została sscanf powodzeniem w stanie wypełnić. Tak by tej logiki, jeśli funkcja Jestem wykonawczych jest getInt, ale mam kontroli, potencjalnie w użytkownik na wpisaniu w int następnie przez coś innego, co chcę w sscanf Wartość zwracana naprawdę być? Jeśli celem jest uzyskanie tylko int od użytkownika? Więc jeśli sscanf zwrotów 2, co to oznacza? Użytkownik wpisze w coś, dosłownie, 123x, która jest po prostu nonsensem. Jest to stan błędu, a Chcę sprawdzić, że. Więc jeśli użytkownik wpisze w to, by to logiczne, co robi sscanf powrócić, można by powiedzieć? Tak to się zwróci 2, ponieważ 123 ma zamiar udać się tutaj, i x zamierza skończyć tutaj. Ale ja nie chcę x aby wypełnione. Chcę sscanf tylko uda się napełniania pierwszej kolejności jego zmienne. I tak to jest, dlaczego chcesz sscanf powrotu 1. I, jeśli jest to nieco nad głową w tej chwili, to jest całkowicie w porządku. Sobie sprawę jednak, że jednym z Wartości getInt i getString jest to, że robimy kawał Wiele błędów sprawdzania tak więc że do tej pory, można dość dużo wpisz cokolwiek w klawiaturze a my go złapać. A my na pewno, personel, na pewno nie będzie być źródłem błędu w swoim Program, ponieważ jesteśmy w defensywie sprawdzanie wszystkich głupi rzeczy, które użytkownik może zrobić, jak wpisując ciąg, kiedy naprawdę chciał int. Więc dla teraz-- przyjdziemy Przed powrotem do tego long-- ale przez cały ten czas, ma getString i getInt było pod maską za pomocą tego Podstawową ideą adresów pamięci. Więc teraz, zróbmy wszystko trochę bardziej przyjazny dla użytkownika. Jak być może pamiętacie, z Binky ostatniego time-- jeśli mysz będzie cooperate-- tak mieliśmy ten kod, który szczerze mówiąc, to dość bezsensowne. Kod ten osiąga nic przydatne, ale to był przykład że profesor Parlante stosuje się w celu reprezentowania co się dzieje w Program z udziałem pamięci. Warto więc opowiedzieć to historia bardzo krótko. Te dwie pierwsze linie, w Angielski, czy co, można by powiedzieć? Tylko w przystępnej człowieka, ale nieznacznie terminy techniczne, warto ukłucie. PUBLICZNOŚCI: [niesłyszalne]. David J. MALAN: OK, jesteś ustanawiającego Adresy swoim x i y. zmiennych Nie całkiem, bo x i y nie są zmienne w tradycyjnym sensie. x i y są adresami lub będzie przechowywać adres. Więc spróbujmy jeszcze raz. Nie zły początek, choć. Tak? PUBLICZNOŚCI: [niesłyszalne]. David J. MALAN: Dobra. Myślę, że to trochę czystsze. Deklarowanie dwa wskaźniki, dwie liczby całkowite. A my nazywając je x i y. Albo gdybyśmy remis Ten jako obraz znowu Przypomnijmy, że po prostu wszystko robimy z tej pierwszej linii jest rysunek okno tak, z niektórych wartości w nim śmieci, i nazywając ją X, a następnie kolejne okno tak, z niektórych wartości śmieci w niej, nazywając ją y. Mamy oświadczył dwa wskaźniki, które ostatecznie będzie przechowywać adres int. Więc to wszystko. Więc kiedy Binky to zrobił, gliny po prostu wyglądał jak ten. Nick tylko rodzaj zawinięte strzałki, tak, jakby nigdzie nie wskazujesz w szczególności dlatego, że są po prostu Wartości śmieci. Nie są one jawnie zainicjowana gdziekolwiek w szczególności. Teraz następny wiersz Kod, przypomnieć, było to. Więc w przystępnej łatwy w obsłudze, ale nieco techniczny angielski, co to jest linia kodu robi? Tak? PUBLICZNOŚCI: [niesłyszalne]. David J. MALAN: Perfect. To alokacji kawał Pamięć to rozmiar wew. I to jest połowa odpowiedzi. Odpowiedziałeś sobie prawo połowy ekspresji. Co dzieje się na Po lewej stronie od znaku równości? Tak? PUBLICZNOŚCI: i przypisuje to zmiennej x? David J. MALAN: i przypisuje to zmiennej x. Przypomnę więc, prawe boczne przydziela mało pamięci do przechowywania int. Ale malloc specjalnie zwraca adres tego fragmentu pamięci, które już tylko proponowany dostaje przechowywane w x. Więc to, co ostatnio zrobił Nick z Binky jest wlókł ten wskaźnik z, glina, wskazać teraz w białym fragmencie pamięci który jest równy wielkości int. I rzeczywiście, to się rozumie do reprezentowania cztery bajty. Teraz, obok linii kodu to zrobił, gwiazda x dostaje 42. Tak 42 jest proste na prawa strona, sens życia. Lewa strona, gwiazda x oznacza co? To też może mieć gone-- to jest OK. OK. PUBLICZNOŚCI: Zasadniczo, przejdź do [niesłyszalne] David J. MALAN: Dobra. PUBLICZNOŚCI: [niesłyszalne]. David J. MALAN: Dokładnie. Lewa strona oznacza iść do x. x to adres. To jak 33 Oxford Street, lub OX1. I gwiazda x oznacza, że ​​iść do adres i umieścić to, co tam jest? 42. Tak naprawdę, to właśnie Nick zrobił. Zaczął By, zasadniczo, psychicznie wskazując palcem x, zgodnie ze strzałką na białym polu po prawej z boku, a wprowadzenie numeru 42 nie. Ale potem zrobiło trochę niebezpieczne, prawda? Binky na temat stracić głowę. Gwiazda y jest równa 13, pech, czyli co? Więc gwiazdkowe y środki przejść do adresu w y. Ale co to jest adres y? Dobrze, że to wartość śmieci, prawda? Narysowałem go jako znak zapytania. Nick wyciągnął go jako zwinięty strzałką. I tak szybko, jak spróbować Czy Star y, mówiąc, tam, ale nie jest uzasadniony adres, to niektóre fałszywe położenie, Program będzie katastrofy. I szef Binky jest zamiar odlecieć tutaj, jak to zrobił. Więc w końcu tego programu było po prostu płaskim się wada. Był to program buggy. I to musiała być ustalona. A jedynym sposobem, naprawdę, to naprawić Chodzi tu na przykład linia, które nawet nie dostać się do, ponieważ Program rozbił się zbyt szybko. Ale gdybyśmy to naprawić, co Efekt nie robi r równe x mają? Cóż, w zasadzie wskazuje y niezależnie od wartości x wskazuje na. Więc w historii Nicka, lub historia Binky, zarówno x i y były wskazując na biały fragment pamięci, tak, że w końcu, kiedy Czy Star y wynosi 13 raz skończyć się wprowadzenie 13 odpowiednia lokalizacja. Tak więc wszystkie te linie są całkowicie uzasadnione, z wyjątkiem tego jednego, kiedy to się stało przed tobą faktycznie przypisane pręd jakąś wartość. Teraz na szczęście, nie musisz ma się rozumieć, przez wszystkie z tych rodzajów problemów na własną rękę. Pozwólcie mi iść do przodu i otworzyć okno terminala tutaj i otworzyć się na chwilę, bardzo krótki program, który również jest rodzajem sensu. Jest brzydki. To nie ma nic użytecznego osiągnąć. Ale to nie wykazywać problemy z pamięci, więc rzućmy okiem. Głównym, super proste. To najwyraźniej wywołuje funkcję, f, a następnie zwraca 0. To trochę trudne do bałaganu to. Tak więc główna jest bardzo dobry, jak na razie. Tak więc f jest problematyczne. I po prostu nie umieścić wiele nazywając go do wysiłku tutaj, aby zachować ostrość na kodzie. f ma dwie linie. I zobaczmy, co się teraz dzieje. Tak więc z jednej strony tutaj-- i pozwól mi Ten zgodny z poprzedniego example-- jednej strony lewa strona jest robi to, co w języku angielskim? To jest-- PUBLICZNOŚCI: Tworzenie wskaźnika. David J. MALAN: Tworzenie wskaźnik do int i nazywając to x. Więc jest stworzenie jednego z tych pól Wciąż rysowanie na ekranie dotykowym. A teraz, na prawej bocznym się przydzielić Oczywiście przeznacza kawałek pamięci. I po prostu być jasne, w jaki sposób ilość pamięci jest najwyraźniej alokacji, jeśli tylko niby do matematyki tutaj? Więc jest to 40 bajtów. I wiem, że tylko dlatego, że wiem, int, na urządzeniu CS50 Przynajmniej to cztery bajty. Tak 10 razy 4 to 40. Więc to jest przechowywanie x, adres pierwszego z 40 wskazówki, które zostały przydzielone miejsce z powrotem, do tyłu, do tyłu, do tyłu. I to właśnie jest klucz o malloc. Nie ma mało pamięci tu, trochę tu, trochę tu. To daje jeden fragment pamięci, w sposób ciągły, z działalności operacyjnej System. Teraz to, co na ten temat, x Uchwyt 10 jest równa 0? Dowolna linia kodu. To nie ma nic użytecznego osiągnąć. Ale ciekawe jest to, ponieważ x wspornika 10--? Tak? PUBLICZNOŚCI: [niesłyszalne]? David J. MALAN: x wspornik 10 nie musi być wartością pustą. Null szczegóły w grę wchodzi tylko z tekstem, na końcu łańcucha. Ale dobra myśl. Jak duża jest ta tablica, nawet choć mam przydzielone 40 bajtów? To od 0 do dziewiątej, tak? To 10 ints, całkowita. 40 bajtów, ale 10 ints, indeksowane od 0 do 0. Więc co to jest x wspornik 10? To rzeczywiście niektóre wartość nieznana śmieci. Jest to pamięć, która nie należy do mnie. Nie należy dotykać, że Liczba bajtów 41, 42, 43, 44. Idę trochę za daleko. I rzeczywiście, jeśli uruchomię to Program, to może bardzo dobrze upaść. Ale czasem, będziemy mieli szczęście. I tak po prostu, aby wykazać To-- i szczerze mówiąc, nigdy nie wiesz, przed tobą nie to-- uciekajmy to. To faktycznie nie upaść. Ale jeśli mogę to zmienić, dla Przykładowo, aby być jak 1000, aby to naprawdę celowe, zobaczmy jeśli uda nam się go rozbić ten czas. OK, to nie błąd. Jak o 100.000? Miejmy przerobić go, a teraz ponownie uruchomić go. OK. Uff. Wszystko w porządku. Tak więc widać, znowu, są segmenty pamięci, że tak powiem, są dość duże, więc możemy miał szczęście ponownie. Ale w końcu, kiedy już się śmieszne i bardzo daleko się na ekranie, Dotknięcie pamięci, które naprawdę, naprawdę nie należy do ciebie. Ale szczerze mówiąc, to rodzaje błędów będą być trudniej dowiedzieć się na własną rękę. Ale na szczęście, jak programiści, mamy narzędzia, które pozwalają nam zrobić to za nas. Tak to jest, być może, jeden z poważniejszymi programami, jeszcze brzydszy niż wyjście GDB za. Ale to zawsze jest linia lub dwa, które są bardzo przydatne. Valgrind to program, który pomaga nie debugować program, per se, ale znaleźć związane pamięci problemy, w szczególności. Zostanie ona automatycznie uruchomić kod ty i wygląda na co najmniej dwie rzeczy. Jeden, coś zrobiłeś przypadkowe jak pamięci dotykowym które nie należą do ciebie? To pomoże Ci znaleźć te przypadki. A dwa, że ​​to pomoże można znaleźć coś, co nazywa wycieki pamięci, które mamy całkowicie ignorowane, naiwnie, przez jakiś czas i błogo. Ale okazuje się, wszystko Tym razem, ilekroć już w nazwie getString tak wielu z naszych programów, pytasz o eksploatacji system pamięci, ale masz jakieś wspomnienia od zawsze daje to powrotem, robiąc UNALLOC, lub za darmo, jak to się nazywa. Nie, ponieważ nigdy nie poprosił Cię, aby to zrobić. Ale przez cały ten czas, programy Pisałeś w C zostały wyciek pamięci, zwracając się do eksploatacji System coraz Pamięć na smyczki i etażerka, ale nigdy nie podając go. A teraz jest to nieco z uproszczeń, ale jeśli kiedykolwiek uruchomić komputera Mac lub komputer od jakiegoś czasu, otwarcia wiele programów, może i zamykania programów, i mimo, że Twój Komputer nie rozbił, robi się tak wiele wolniej, tak, jakby to naprawdę przy użyciu dużo pamięci lub Środki, chociaż jeśli nie jesteś jeszcze dotykając klawiatury, które mogą być: ale nie always-- mógł się, że programy używasz mają sobie wycieków pamięci. I prosić o więcej i OS więcej pamięci, ale zapominając o tym, właściwie nie używając go, ale Dlatego biorąc pamięć dala z innych programów, które mogą go chcą. Więc to jest wspólne wyjaśnienie. Teraz tutaj jest gdzie Valgrind jest Wyjście jest całkowicie okropna do tych mniej i bardziej komfortowe podobnie. Ale ciekawe rzeczy jest aż tutaj. Jest on mówi mi pisać z nieprawidłową rozmiar cztery dzieje się w tym programie, w szczególności, linia 21 memory.c. Jeśli pójdę do linii 21, hm, to rzeczywiście jest nieważny zapis wielkości czterech. Dlaczego rozmiar cztery? Cóż, to number-- i może być anything-- jest int. Więc to cztery bajty. Więc zamieszczam cztery bajty gdzie oni nie należą. To Valgrind rzeczywiście mówi mi. Ponadto będzie również powiedz mi, jak zobaczymy, jak uruchomić to w przyszłym Pset, czy i kiedy już wyciekły pamięć, która rzeczywiście Mam, bo już o nazwie malloc, ale w rzeczywistości nie ma nazwie, w tym przypadku, za darmo, które będziemy w końcu zobaczyć jest przeciwieństwem malloc. Więc teraz, myślę, że ostateczny przykład. Więc ten jest nieco bardziej Arcane, ale to być może Największym powodem do uważaj z pamięci, i dlatego, że wiele programów i / lub serwery internetowe, nawet do dnia dzisiejszego, zostały przejęte przez złych facetów gdzieś w Internecie, które są w jakiś wysyłanie fałszywych pakietów do serwera próby kompromisu kont, lub zabrać swoje dane, lub po prostu ogólnie przejąć maszyna. Przepełnienie bufora, jak nazwa wskazuje, środki przepełnione nie int, ale bufor. I bufor jest tylko fantazyjny sposób powiedzieć, że to banda pamięci. I rzeczywiście, zadzwoniłem ciąg przed buforem, zamiast s. Bo jeśli to jest bufor, W tym sensie, jak YouTube, lub za każdym razem, czy oglądasz film, Może widzieliście buforowanie słowo, kropka, kropka, kropka. Jest to niezwykle irytujące. I to właśnie oznacza że odtwarzacz wideo próbuje pobrać wiele bajtów, wiele bajtów z filmów z Internetu. Ale to powoli, tak że próbuje pobrać kilka z nich do wypełnienia bufora, pojemnik, tak, że masz wystarczająco dużo bajtów, że może to pokazać film, bez wstrzymywania stale. Ale okazuje się, możesz posiada bufor na ten wielki. Ale staram się umieścić to dużo danych w to, i bardzo złe rzeczy mogą się zdarzyć. Tak na przykład, spójrzmy na ten ostatni teaser przykład. Jest to inny program które na pierwszy rzut oka, ma coś bardzo przydatne nie. Jest tam główną funkcją , który wywołuje tę funkcję, f. I że funkcja f, tutaj, ma Tablica char, zwany c, o wielkości 12. A potem jest za pomocą tego Nowa funkcja o nazwie strncpy. Okazuje się, że w ten prosty, prosta linia kodu, tylko dwie linie, zrobiliśmy mój cały program, iw związku z tym, cały mój komputer, i moje konto użytkownika, a mój dysk prowadzić potencjalnie narażone na nikogo kto wie i jest wystarczająco dobry, aby uruchomić ten program z pewnym wierszu poleceń Argument. Innymi słowy, jeżeli zły stawia wewnątrz argvargv [1], wpisując na klawiaturze bardzo specjalnie spreparowany ciąg, nie abc, 123, ale w istocie, Symbole binarne reprezentujące wykonywalny Kod, program, który on napisał, z tego prostego programu, który jest Przedstawiciel tysięcy programów które są podobnie narażone, śmiem twierdzić, on lub ona może ostatecznie usunąć wszystkie pliki na dysku twardym, uzyskać miga wiersz tak, że on lub ona może wpisz komendy na własną rękę, napisz wszystkie pliki do siebie. Wszystko, co mogę zrobić, to lub ona może zrobić z tym kodem. Nie będzie to jednak zupełnie rozwiązać. A w rzeczywistości, to będzie obejmować trochę obraz jak ten, który będziemy wkrótce zrozumieć, tym lepiej. Ale na dzisiaj, niech zakończy się w co, miejmy nadzieję, nieco bardziej zrozumiałe XKCD żart, aż wznowić następnym razem. Wszystko w porządku. Do zobaczenia w środę. [MUZYKA GRA] Głośnik: A teraz, głęboko myśli, by Daven Farnham. Pamięć jest jak skoki w stos złote liście na niedzielne popołudnie. Wiatr wieje, rzucając swoje hair-- oh, tęsknię dni when-- [Śmiech]