[Powered by Google Translate] [Tydzień 4, ciąg dalszy]
[David J. Malan - Harvard University]
[To jest CS50. - CS50.TV]
>> To CS50, i to jest koniec 4 tygodniu.
Tak dobre wieści i złe wieści.
No wykład w poniedziałek, nie ma problemu ustawić w przyszłym tygodniu. [Studenci doping]
Nie spodoba ci się, gdzie to będzie.
Ale mamy to zamiast w środę,
i nie jest też za Syllabus 1 wykładu piątek następny piątek, abyśmy mogli utrzymać się na torze.
Ale wszystko będzie filmowany, jak zwykle, więc nie martw się.
>> , Aw odniesieniu do quizu 0 co zrobimy w kierunku koniec tygodnia
jest post na kursie w cs50.net homepage wyjaśnienie
z jakiego rodzaju oczekiwania powinno być, jeśli chodzi o pierwszy quiz.
Ogólnie rzecz biorąc, będzie to test wielokrotnego wyboru, prawda-fałsz, krótka odpowiedź, krótkie problemy kodowania.
Nie zamierzasz się spodziewać wdrożenia równowartość
problemu, który można zobaczyć na PSET, dla których masz komputer
i debugger i tym podobne, ale nie będą małe problemy kodowania.
>> I rzeczywiście, najlepszym przewodnikiem do zorientować się co CS50 quizy są jak
to udać się do cs50.net, przejdź do quizy link
i można zobaczyć kilka ostatnich lat warto quizy.
Wystarczy uświadomić sobie, że program nauczania nie zawsze była taka sama na przestrzeni lat.
Czasami możemy dodać, czasem odejmowanie,
więc jeśli widzisz jakiś temat na jednym z tych starych quizy
że nie masz pojęcia, co to mówi, to albo, że nie obejmują go
lub że nie obejmuje go.
Ale w formie opinii, to niedziela, poniedziałek i wtorek
jak również oczywiście-szerokiej sesji przeglądarki w niedzielę wieczorem -
Czas i miejsce zostanie ogłoszone na stronie głównej kursu -
wszyscy mają możliwość zapoznania się z przebiegiem bliźnich dydaktycznych
Materiał tego roku, zarówno w sekcji i w pełnym klasy
a te będą filmowane jak zwykle, jak również.
>> Dobrze. Więc bez zbędnych ceregieli, jeden komentarz na pass / fail i dodaj / upuść.
Może widzieliście moje notatki w nocy, i to jest tak naprawdę tylko niektóre dodatkowe uspokojenie
że jeśli jesteś wśród tych, szczególnie mniej wygodne lub gdzieś pomiędzy
i czujesz tylko trochę się nad głową,
sobie sprawę, że rzeczywiście jest to normalne, i jest tam duży struktura wsparcia w miejscu,
z których jeden dyżur byli zdecydowani poprawę wszystkich więcej na mój adres e ostatniej nocy,
i uświadomić sobie, też, że opcja jak pass / fail dla klasy, podobnie jak to
naprawdę ma jako mechanizm stępić kursu jak ta,
tak, że ponownie jeśli wydatki te 10, 15, 20 godzin
po prostu staramy się zdobyć Pset do pracy i wiesz, że 90-95% z drogi tam
ale nie można znaleźć jakiś cholerny błąd, w pass / fail model, który znajduje się jakby w porządku.
>> Chodzi o to, że z tego mechanizmu można następnie przejść skupić na innych psets
ani spać, czy cokolwiek to jest, że chcesz się skupić.
Tak więc okazuje się, że mają do tego nadchodzący wtorek - technicznie 5-gie poniedziałek,
ale to jest święto, więc wtorek nadchodzi - przejście z przełęczy / nie lub vice versa stopniowanych.
A jeśli jesteś naprawdę nad przepaścią i myśli spada całkowicie,
proszę złap mnie po wykładzie lub wyślij mi wiadomość.
Chcielibyśmy przynajmniej czacie przed licytować Adieu.
Dobrze. Zaczęliśmy więc podjęcie kółka off po raz ostatni.
W szczególności koncentruje się na ciąg.
String jest coś, co jest deklarowane w bibliotece CS50,
specjalnie w tym pliku o nazwie cs50.h które zaczniemy patrzeć na ten tydzień i następny.
Ale łańcuch jest tak naprawdę tylko uproszczenie coś
To trochę więcej arcanely opisany jako char *.
Char jesteśmy zaznajomieni. To jest tylko jeden znak.
Ale * od poniedziałku oznaczone co? >> [Uczeń] wskaźnik.
Wskaźnik. A co to jest wskaźnik? >> [Uczeń] adres.
>> To jak adres, lokalizację w pamięci.
Co znajduje się adres lub miejsce lub pamięci?
Ponownie, wszystkie z nas są w laptopy z koncertu lub 2 gigabajty pamięci RAM najprawdopodobniej te dni,
i oznacza, że ​​masz miliard lub 2 miliard bajtów warte pamięci.
I to naprawdę nie ma znaczenia, co to fizycznie wygląda,
ale wziąć na wiarę, że można liczyć wszystkich pojedynczych bajtów własny laptop -
Ten bajt jest 0, to bajt 1, to bajt 2000000000 -
i to jest dokładnie to, co robi komputer.
Po przydzielić miejsce dla jednej postaci, na przykład,
to oczywiście musi żyć gdzieś w pamięci komputera,
a może to jest w liczbie bajtów 12345,
i to jest gdzieś tutaj, w pamięci komputera.
Oraz adres, a następnie z tego znaku to 12345.
>> Teraz, w tydzień 0 przez teraz do tej pory, nie mamy naprawdę zależało
gdy w pamięci są przechowywane rzeczy, bo zazwyczaj używamy symboli,
Zmienne i tablice rzeczywiście dostać w naszych danych.
Ale od poniedziałku, a tym bardziej dziś, jesteś teraz będzie musiał
tym bardziej ekspresyjne możliwości z programów piszących
naprawdę manipulować pamięci komputera jednak widać pasuje,
zarówno dla dobrych celów i na złe,
błędy są bardzo często wynikiem w tym momencie w naukę tego rzeczy.
Ale co to tak naprawdę znaczy być char *?
Idziemy naprzód z powrotem - i wrócimy do Binky jak obiecałem dzisiaj.
Chodźmy na prosty przykład tutaj.
Pozwól mi zapisać ten plik jako compare.c, i niech mi tylko trochę kod szablonu tutaj
tak jak stdio.h, niech również oddaję obejmują cs50.h. Będę powiększyć tam.
Zacznę pisać główny int main (void), a teraz chcę zrobić coś takiego:
printf ("Podaj mi napis:"), a potem użyję ciąg s pobiera getString
aby ciąg od użytkownika, a następnie zamierzam poprosić użytkownika o innym.
("Daj mi jeszcze napis:") i mam zamiar zapytać je za pośrednictwem getString to dostać.
Nazwijmy go t bo t jest po s i s to ładne imię dla łańcucha, jeśli jest to dość ogólne.
Więc GetString, a teraz po prostu chcę zrobić test sanity i mam zamiar powiedzieć
if (s == t) wtedy ja tylko powiem instrukcji printf ("Wpisano samo \ n");
jeszcze mam zamiar wydrukować coś takiego ("wpisałeś coś innego! \ n")
lub cokolwiek zdanie będzie. Więc coś w tym stylu.
Potem, jak zwykle, wrócę 0, które po prostu oznaczało, że nic złego się nie stało,
i mam zamiar iść do przodu i skompilować i uruchomić ten program.
>> Ale w poniedziałek prowadziliśmy ten program,
i rzeczywiście powiedziano nam, że nie jest WITAJ cześć i do widzenia nie jest pożegnanie.
Zachowanie widzieliśmy było trochę więcej jak to.
Pozwól mi iść do mojego katalogu źródłowego, powiększyć tutaj, a niech robią porównania.
Zestawione w porządku. Pozwólcie mi biegać porównać. Daj mi tekst: Hello.
Daj mi jeszcze napis: Hello.
Wpisałeś coś innego!
Cóż, pozwól mi spróbować czegoś prostszego, jak 50, 50 lat. Wpisałeś coś innego!
hi, hi. Tak wyraźnie, coś się tu dzieje.
Ale co było wyjaśnienie, dlaczego?
Najwyraźniej, linia 12 jest całkowicie dysfunkcjonalne.
Co jest podstawowym problemem tutaj? Tak. >> [Uczeń] To porównywanie adresów.
Tak, dokładnie. To faktycznie porównując adresy
, w którym cześć i WITAJ są przechowywane.
To nie jest porównanie litery Witam ponownie i ponownie,
ponieważ to, co się naprawdę stało, cały czas używaliśmy getString -
Ta tablica jest znowu naszym pamięci komputera,
i powiedzmy, że ja nazywam getString po deklaracji zmiennej s.
Co moja pamięć wygląda?
Miejmy arbitralnie powiedzieć, że s wygląda. Jest to kwadrat.
I prawie za każdym razem mam wyciągnąć kawałek pamięci na ekranie
jeśli jest to 32 bity byłem rysowanie kwadratów, jak to, bo rzeczywiście w urządzenie,
wskaźnik, adres, jest 32 bitów. To tak samo jak int.
, Które mogą się zmieniać w zależności od systemu komputerowego.
Ci z was, którzy są jakby znajome z faktem, że komputer Mac lub PC jest 64 bitów,
faktycznie oznacza, że ​​komputer korzysta z 64-bitowych,
64-bitowe adresy, a wśród upsides o to komputery
może mieć znacznie więcej pamięci RAM niż przeszłości.
Krótko mówiąc, z powrotem w dzień, gdy komputery używane tylko 32 bity
do reprezentowania adresów, największą liczbę bajtów można reprezentować
w tym przypadku było to, co, jeśli masz 32 bity?
Więc 4 mld rację, bo 2 do 32 wynosi 4 mld euro.
Ta liczba jest ponownie w ciągu.
>> Więc jeśli masz tylko 32 bitów, najwięcej można liczyć na to około 4 mld euro.
Ale to było fundamentalne ograniczenie komputerów dopiero kilka lat temu
bo czy można liczyć tylko tak wysoka, jak 4 miliardy,
to nie ma znaczenia, jeśli kupisz 8 GB pamięci RAM, a nawet 5 GB pamięci RAM;
nie można liczyć, że wysoki, więc to było bezużyteczne.
Można było tylko przejść pierwsze 3 lub 4 gigabajtów pamięci komputera.
To jest mniejszy problem teraz, a możesz kupić Zalety MacBook i Dells
z 8 GB pamięci RAM, a nawet więcej tych dni.
Ale jeśli mogę przeznaczyć po prostu w tym programie wskaźnik, wskaźnik nazywane s,
może to wyglądać na ekranie, bo rzeczywiście trzeba odwinąć tej warstwy.
Trzymam ciąg mówi, ale od poniedziałku, ciąg jest bardzo char *,
adresy niektórych postaci.
Więc weźmy to koło szkolenia off chociaż będziemy nadal korzystać getString teraz.
Tak już zadeklarowane s, a to jest fragment pamięci, 32 bitów.
Co tu w pamięci domyślnie? >> [Niesłyszalne odpowiedź uczeń]
Co to jest? >> [Uczeń] Garbage. Garbage. >> Dokładnie.
Jeśli programista nie umieścić wartość w zmiennej, który wie, co to jest?
Czasami masz szczęście i to jest 0, co jest raczej miłym, czystym wartości domyślnej
ale jak widzieliśmy poniedziałek, czasami jest to kompletna bzdura,
niektóre naprawdę duże dodatnią lub ujemną, który przyszedł skąd?
Tak. >> [Uczeń] Funkcja wcześniej. >> Tak.
>> Często nazywa się funkcja, ale wcześniej, bo pamiętam,
jak wywoływanie funkcji w pamięci, że zajmują coraz więcej przestrzeni od dołu do góry,
i jak tylko funkcja zwróci wartość, że pamięć zostanie ponownie
przez kolejnego faceta, który zostanie wywołany, który jest przy użyciu tego samego kawałek pamięci.
A jeśli masz lewy śmieci tam, poprzednie wartości,
możemy pomylić s jako posiadające pewną wartość, gdy naprawdę nie mamy umieścić coś tam.
Więc nasz RAM w tym momencie wygląda tak.
Teraz na prawej stronie linii 7 mamy wywołanie getString,
co robiliśmy teraz na tydzień, ale to, co jest naprawdę getString robisz?
GetString napisany przez CS50 personelu jest mało inteligentny
na tym, że jak tylko użytkownik uruchamia pisania klawisze i wciśnie ENTER,
Liczby getString, ile klawiszy zrobili hit użytkownika,
ile znaków muszę przydzielić pamięci RAM.
I gdy RAM pochodzi, kto wie?
Jest gdzieś w komputerze 2 GB lub etażerka pamięci.
Ale załóżmy, że komputer znaleziono miejsca na słowo HELLO tutaj.
Wpisałem słowo było H-E-L-L-O.
A jeśli rysujemy to jako ciąg znaków, który może wyciągnąć to tak.
Ale muszę zrobić 1 ekstra rzeczy. Co należy w końcu dowolny ciąg w C?
Znak null, który piszemy jako \ 0.
To technicznie 0 numer, ale backslash robi zrozumiałość
że jest to dosłownie liczbę 0, liczbę całkowitą 0;
to nie jest, na przykład, cytuję-koniec cytatu 0, że możesz wpisać z klawiatury.
Więc to jest Halo.
>> A co możemy powiedzieć w poniedziałek, że funkcjonują jak getString
faktycznie wszystkie te tygodnie wraca?
To nie jest powrót ciąg per se, ponieważ tak naprawdę nie mają znaczenie
bo struny nie istnieją. Są swego rodzaju produkcji w CS50 biblioteki.
Co tak naprawdę jest string, bardziej technicznie? >> [Uczeń] To pierwszy znak.
Dokładnie. Jest to po prostu adres pierwszego znaku, który użytkownik wpisze w.
Więc jeśli moje słowo WITAJ kończy go na bajt nr 123, a następnie w bajcie numer 124,
125, 126, i tak dalej, tak, jeśli liczba bajtów moje na się od 0,
co naprawdę GetString wraca jest dosłownie 123 numer.
Więc co zostaje umieszczone w s jest 123 numer nie, H pismo, nie słowo HELLO,
po prostu adres, pod którym można znaleźć pierwszą literę Hello.
Ale to nie wydaje się wystarczająco. Poprosiłem cię o ciąg, a nie charakter.
Jak więc albo komputer wie, że ello rodzaj przyjść z H?
Co jest rodzajem porozumienia mamy? Tak.
[Uczeń] To powtarza się znaleźć trochę więcej znaków. >> Dokładnie.
>> Jest to człowiek-komputer konwencja której gdy masz do czynienia z tekstem,
inaczej znany teraz jako char gwiazd, po prostu dowiedzieć się,
gdzie koniec każdy ciąg w życiu jest tak naprawdę Iterowanie nad nim z pętli for
pętla, cokolwiek, tak, że kiedy znajdziesz koniec łańcucha
teraz można wywnioskować, że, och, całe słowo było Hello.
Ci z was, z wcześniejszego doświadczenia programowania może wiedzieć w Javie
można po prostu zadzwonić. długość oraz w innych językach można zadzwonić długość lub podobnego.
To dlatego, że w wielu językach, szczególnie rzeczy zwane języki obiektowe,
długość jest rodzaj coś zatopiony wewnątrz elementu danych się,
podobnie jak my enkapsulacji identyfikatory i nazwiska i domy wewnątrz studenta w poniedziałek.
C jest jednak znacznie niższy poziom. Nie ma obiektów lub klasy, jeśli nie słyszałem tych terminów wcześniej.
Wszystko co musisz naprawdę adresy pamięci.
Jest to więc rodzaj staromodnego sposobu przedstawiania ciekawych struktur danych.
Masz wartość początkową jak adres pierwszego znaku
a potem po prostu jakiś dowolny konwencja, że ​​każdy zgodzi się przestrzegać.
Więc jak jest długość ciągu realizowane, nie proponujemy?
Strlen, strlen, co niektórzy z was teraz używane kilka razy. Jest to dość proste, prawda?
To jest jak 2 linii kodu.
To bardzo dużo dla pętli jakiejś, być może z dodatkowej zmiennej lokalnej.
Ale strlen tylko musi podjąć wskaźnik, a następnie rozpocząć poszukiwania \ 0.
>> I jak tylko go znajdzie, to może wrócić całkowitą liczbę kroków, które to wykonane w tym ciągu.
Można więc z tego wywnioskować, co dzieje się dalej.
Załóżmy następnie Oświadczam t jak zrobiłem w linii 10.
To jest jakaś wartość śmieci. Kto wie, co w pierwszej kolejności?
Ale na prawej stronie linii 10 dzwonię getString ponownie.
Kto wie gdzie to kończy?
Miejmy arbitralnie powiedzieć, że system operacyjny nie znaleziono miejsca na sposób tutaj.
Tak się przypadkiem typ H-e-l-l-O znowu
i tak można wyciągnąć ten sam rodzaj obrazu.
Ale fakt, że mam przerysowany ten obraz jest celowe
bo to jest inna WITAJ niż ten.
Więc może to być miejsce 456, jest 457, i tak dalej.
Więc co pobiera umieścić gdzie znak zapytania było kiedyś?
W tym przypadku 456.
Jesteśmy zbierając te liczby dowolnie bo tak naprawdę po dziś
nie będziemy dbać o to, co tak bardzo, adres cokolwiek.
Wszyscy dbamy o to, że możemy dowiedzieć się adres jakiegoś kawałka danych jak Halo.
>> Tak naprawdę to, co większość ludzi robi w informatyce, gdy mówimy o adresy pamięci
i mówić o wskaźniki konkretnie
zamiast niepokoić zastanawianie się 123 - kogo to obchodzi, gdzie te rzeczy w rzeczywistości,
Wiemy tylko, że jest to w pewnym numerycznego adresu -
upraszczamy świat i po prostu powiedzieć, że jest skierowany do tej postaci
i t jest skierowany w tym charakterze.
A fakt, że jest to główna jest całkiem zamierzone
bo dosłownie teraz s wskazuje na H i T jest wskazując na inny H
, ponieważ na końcu dnia, to nie ma znaczenia, adres,
ale to ma znaczenie, że mamy zdolność do wyrażania tego adresu z jakimś kawałkiem kodu.
Tak naprawdę nie manipulował te adresy tylko jeszcze
więc zobaczymy, gdzie możemy wtrącić i rodzaju robić rzeczy z wskaźników,
ale teraz w kolejce 12 dosłownie jakie wartości mamy porównanie
według tej historii w linii 12?
Mówimy to 123 równa równa 456? I to na pewno nie przypadek.
I nawet koncepcyjnie, wskaźnik ten na pewno nie jest taka sama, jak ta
bo nazywa getString dwukrotnie i GetString nie stara się być super mądry,
nie staramy się realizować, oh, wpisałeś WITAJ 5 minut temu;
pozwól mi dać taki sam wskaźnik jak dałem ci wcześniej,
to tylko alokuje nowy kawałek pamięci za każdym razem kiedy to nazwać.
>> Jak więc rozwiązać ten problem?
Jeśli wyższy poziom chcę porównać ciągi Witam i Hello -
Nie dbam o wskaźniki - jak mam go o udzielenie odpowiedzi na pytanie,
czy użytkownik wpisz to samo? Co jest tu potrzebne? Tak.
[Uczeń] Użyj funkcji. >> Mogę użyć funkcji z pudełka.
Można użyć funkcji nazwie strcmp, S-R-T-C-m-P,
tylko skrócona wersja mówiąc ciąg porównania.
I, jeśli się go, na przykład, porównaj 2, który jest jednym z dzisiejszych ulotek,
I właśnie do tego.
Ciągle wszystko inne samo z linii 1 na dół do 26 lub tak,
i teraz to zauważyć, część zmieniła tylko trochę.
Zignorujmy linii 28 na chwilę i skupić się tylko na tej jednej.
Co możemy powiedzieć w poniedziałek, że str porównywania robi?
Zajmuje proces podejmowania 2 wskaźniki, S i T w tym przypadku,
rodzaj praktycznie oddanie jej palec na tych 2 liter,
i to, co musi zrobić, to coś w pętli while lub do pętli,
i mówi, są te same? Jeśli tak, to porusza palcami lub odsyłacze do przodu.
Są one takie same, te same, to sam,
te same, to sam? I ooch, jestem na końcu łańcucha, zarówno na s i t.
Nie znalazłem żadnych sprzeczności. Tak, te słowa są takie same.
A co str porównać zwrot, jeśli 2 ciągi są takie same, podobno? Zero.
Więc 0 jest dobry w tym przypadku, ponieważ jeżeli zwraca -1 lub 1,
oznacza to, że jest po prostu dzieje się przyjść przed t alfabetycznie lub po t.
A dlaczego miałoby to być przydatne funkcję informujący, który ciąg znaków jest przed
po lub w słowniku?
[Uczeń] Wyszukiwanie. >> Wyszukiwanie i sortowanie.
>> Tak można robić takie rzeczy jak binarny wyszukiwania lub sortowania bąbelkowego lub scalania sortowanie
gdzie trzeba porównać rzeczy.
Jak dotąd mamy rodzaj wyciąć niektóre rogi i tylko mówił o sortowaniu
w kontekście liczb, ponieważ jest ładne i łatwe do powiedzenia,
ale z pewnością można porównać ciągi, jabłko i banan,
ponieważ jeśli jabłkowy są znane przed banana, podobnie
można przejść wokół ciągów w pamięci, tak jak Rob zrobił z sortowanie korespondencji seryjnej w teledysku
i my tutaj, na scenie z rodzaju selekcji, sortowania wstawiania, i sortowania bąbelkowego.
Więc gdzie jeszcze można wziąć? Spróbujmy tego.
Miejmy rodzaj zapomnieć tej lekcji na chwilę i spróbować teraz i skopiować 1.c, wykonaj następujące czynności.
Zgodnie 21 Mówię coś druku
potem dostaję ciąg od użytkownika,
to ja jestem sprawdzenia tego.
Tak naprawdę nie dostał jeszcze do tego nawyku, ale niech teraz to zrobić.
Miejmy faktycznie odwinąć tej warstwy. To jest naprawdę char *. Ten facet jest naprawdę char *.
Więc co to znaczy być sprawdzenie, czy s == NULL?
Okazuje się, że podczas wywoływania funkcji takich jak getString
lub bardziej ogólnie po prostu zapytać komputer dać trochę pamięci,
coś może się nie udać.
Możesz być szalony i zapytać komputer dla terabajt pamięci
prosząc o bilionów bajtów pamięci, które po prostu nie istnieją w komputerze,
ale i inne funkcje getString Potrzebuję sposób krzyczy na ciebie
jeśli już prosić o zbyt wiele.
A sposób GetString robi to jest, jeśli prosić o więcej pamięci
niż jest dostępne w komputerze, nawet jeśli to jest super, super niskie prawdopodobieństwo
bo nikt z nas nie będą wpisywać bilionów znaków, a następnie naciśnij klawisz Enter,
ale mało prawdopodobne, choć może to być nadal chcę sprawdzić to tylko w przypadku,
oraz specjalny wartość getString, odpowiedź, i inne funkcje powraca
jeśli coś jest nie tak jest NULL we wszystkich czapkach.
>> A co to jest NULL? NULL tak się reprezentować wskaźnik. Jest 0 adres pamięci.
Świat uznał, że w sposób arbitralny, czy to mój komputer w pamięci - wiesz co? -
mamy zamiar ukraść tylko 1 bajt w każdym pamięci komputera, a to położenie 0.
Zamierzamy dać mu przydomek NULL, i będziemy obiecywać
że nigdy nie faktycznie umieścić tam prawdziwych danych
ponieważ po prostu arbitralnie potrzebują specjalnej wartości, 0, NULL, aka
tak, że możemy krzyczeć na użytkowników, jeśli coś pójdzie źle.
W przeciwnym razie może nie wiedzieć ma 0 oznacza już coś tutaj
czy to znaczy, coś poszło nie tak?
Musimy wszyscy zgadzają się, że nic nie oznacza NULL został zwrócony,
żaden rzeczywisty adres został zwrócony.
Teraz, tutaj jestem po prostu przyjęcie mej ludzkiej konwencji wrócę 1 z głównym
Jeśli coś pójdzie nie tak.
To dlatego, że konwencja Main powrót jest do powrotu 0, jeśli dobry,
1 lub inna wartość, jeśli źle.
Ale GetString i każda funkcja, która zajmuje w pamięci wraca NULL, jeśli coś pójdzie źle.
>> Okay. Więc niestety, linia 27, super proste choć to zupełnie nie skopiować ciąg.
Dlaczego? Widzimy to w następujący sposób.
Jestem twierdząc w wierszu 27 do wykonywania kopii s, a nazywając to t.
Więc nie pytam użytkownika o 2 łańcuchów to czasowych; Mówię tylko wartość w s
należy umieścić w t, jak również.
Więc teraz po prostu pokazać, jak złamane jest to, w wierszu 29 i nowsze, co ja robię?
Najpierw jestem sprawdzenie czy długość t jest większy niż 0.
Jest jakiś ciąg tam. Użytkownik wpisze coś w.
Co to jest linia 32 robi, podobno?
[Niesłyszalne odpowiedź uczeń] Prawo. >> Można wywnioskować, to trochę z tego, co mi powiedział, że to robi.
Ale technicznie, co to robi? t [0] oznacza co?
[Uczeń] znak 0-sza. >> [Malan] znak 0-cia.
Lub, bardziej ludzkie, pierwszy znak w t, cokolwiek to jest, H może w tym przypadku.
I toupper robi to, co mówi. To aktywuje się 0-cie charakter ton i zmienia ją.
Więc oznacza to, wziąć 0-gie charakter t sprawiają, że wielkie litery,
i umieścić go z powrotem w tym samym miejscu.
Więc jeśli wpisz witam małymi literami, to powinien zmienić małą h do literą H.
Ale problemem jest to, że w linii 35 i 36, co mam zrobić, to wydrukować nam s i t.
A jakie jest twoje przeczucie?
Co ja faktycznie się zobaczyć, czy mogę wpisać w cześć we wszystkich małych liter?
Co się wydrukowany? >> [Niesłyszalne reakcja studentów] >> Co to jest?
[Uczeń] Big H, a reszta mała. >> Duże H, a reszta mała, dla których s lub t?
[Uczeń] Both. >> Both. Dokładnie. Zobaczmy więc, co się tutaj dzieje.
>> Pozwólcie mi iść do przodu i skompilować. To Copy1, więc upewnij Copy1. Dobrze.
Powiększyć Pozwól mi iść do przodu i uruchamiania Copy1, Enter, Powiedz coś: witam małe.
Jest aktywowane kopię, ale najwyraźniej kapitalizowane oryginału, jak również,
bo to, co teraz dzieje się w tej historii?
W wierszu 27 nie faktycznie wydaje się być kopiowanie ciąg,
ale nawet możesz mieć nadzieję, że intuicyjnie się w przypadku,
jeśli myślisz o tym zdjęciu, co tak naprawdę zrobiłem?
Połowa rysunku jest taka sama.
Warto więc cofnąć się w czasie tak, że t nie istnieje jeszcze w historii.
S może istnieć w historii, ale niech małe halo ten czas.
Więc pozwól mi naprawić to, co tak naprawdę wpisane w.
W tym przypadku mamy tu h-e-l-l-o.
Będziemy rysować ją jako ciąg znaków, umieścić moje wiersze separatora tutaj i mój \ 0.
Tak to jest, gdzie jesteśmy, jak tylko linii 1 przez 24-ish, lub dać, nie wykonywane.
To jest zdjęcie mojej pamięci.
Kiedy dostanę się do linii 27, co się dzieje?
Tak jak wcześniej, mam wskaźnik, co narysuję, jak ten plac.
To się nazywa t. A co jest jego wartość domyślnie? Kto wie? Niektóre wartości śmieci.
>> Tak abstrakcyjna, że ​​będę z dala jak znak zapytania.
I jak tylko prawej stronie linii 27 wykonuje, co ja umieszczenie wewnątrz t?
Samo, co jest w tych.
Jeśli więc na chwilę usunąć tę abstrakcję strzałki i mówimy:
Och, to jest adres obciążenie pamięci 123, kiedy mówisz t dostaje s, średnik,
jesteś dosłownie oddanie 123 tutaj.
Teraz jeśli rodzaj uprościć nasz świat ponownie ze zdjęciami,
czego się tak naprawdę stało, to się po prostu dodaje kolejną strzałę do swojego świata
który jest skierowany od t do tej samej dokładnie ciąg.
Kiedy więc w linii 31 i 32 I faktycznie go o zmianę t [0],
co t [0] wydaje się synonimem? a [0]
Tak się to wszystko, co się dzieje.
I chociaż ten rodzaj jest trochę niski poziom i arcane
i tego rodzaju uczucie być może intuicyjnie powinno to właśnie działa -
Zrobiłem kopie rzeczy przed i to po prostu działa -
Jeśli naprawdę myślisz o tym, co naprawdę jest ciągiem, to char *.
No, co jest? Jest adres jakiegoś znaku.
Wtedy być może większy sens, że gdy próbujesz coś zrobić
Super pozornie proste tak, wszystko co robisz jest kopiowanie adres pamięci.
Nie jesteś rzeczywiście robi coś z samego łańcucha.
Więc nawet jeśli nie masz pojęcia, jak można rozwiązać ten problem w kodzie,
wysoki poziom, koncepcyjnie, co musimy zrobić, aby uczynić ta kopia s, najwyraźniej?
Tak. >> [Uczeń] Daj mu nową lokalizację? >> Dokładnie.
>> Musimy dać t zupełnie nową lokalizację.
Musimy jakoś stworzyć świat, w którym możemy uzyskać nowy kawałek pamięci,
co tylko dla jasności narysuję tuż pod tym jednym, ale to nie musi być.
Ale to musi być w tym samym rozmiarze, więc rysuję te linie pionowe w tym samym miejscu.
To jest w porządku, jeśli to wszystko śmieci początkowo. Kto wie, co tam było?
Ale krok 1 będzie trzeba dać mi tyle pamięci, jak trzeba
aby zmieścić kopię hello, a następnie dowiedzieć się, jak skopiować h tutaj, e tutaj,
l o i tak dalej.
Ale to już powinien czuć trochę oczywiste, nawet jeśli niektóre szczegóły są wciąż abstrakcyjne.
Aby skopiować ten ciąg do tego, że to tylko na pętli lub pętli while
lub coś, z którym stałeś się jeszcze bardziej znany.
Warto więc spróbować. Pozwólcie mi iść do copy2.c.
W copy2.c mamy prawie ten sam program, z wyjątkiem linii 27.
Wygląda to trochę skomplikowane, ale jeśli mamy rozbicie go kawałek po kawałku,
lewa strona jest taka sama.
Char * t tworzy to coś w pamięci, choć ze znakiem zapytania
ponieważ nie mamy pojęcia, co tam jest domyślnie.
Z prawej strony mamy teraz wprowadza nową funkcję, malloc,
dla pamięci przydzielić mi pamięć,
i to podobno ma jak wiele argumentów, jak wiele rzeczy w nawiasach?
Słyszałem szemranie o 1 i 2, ale to jest tylko 1.
Nie ma przecinek, co oznacza, że ​​tylko 1 rzecz w nawiasie.
Nawet jeśli nie ma innych nawiasów, pozwól mi zaznaczyć
co jest w środku z najbardziej oddalonych nawiasach, i to jest to wyrażenie:
(Strlen (s) + 1) * sizeof (char).
Jeśli więc faktycznie to przemyśleć, to mówi mi długości s.
Dlaczego jestem, choć dodając 1 na długości? >> [Niesłyszalne odpowiedź uczeń]
Dokładnie. Potrzebujemy miejsca dla tego faceta na ogonie, szósty znak, że nie ma znaczenia angielskiego
ale ma specjalny programowy znaczenie.
>> Więc potrzebujemy + 1 za to, bo strlen zwraca ludzkie oczekiwanie długości,
komentarzy lub 5, nie dają dodatkowy znak null.
Więc ręcznie dodać to ze + 1.
A potem to, * rozmiar (char), nie widziałem tego wcześniej.
To nie jest technicznie funkcji.
Jest to specjalne słowo, że po prostu mówi, co rozmiar jest pewnego typu danych na komputerze
ponieważ w rzeczywistości, niektórzy z nas mają 32-bitowe komputery.
Mam dość stary komputer w domu, a używa tylko 32 bitów do reprezentowania wskaźniki.
A jeśli tak zrobiłem rozmiar typu danych, może to być 32 bity.
Ale jeśli używam mojego nowego ozdobnego komputer, być może wrócę wartość 64 bitów
na coś takiego adresu.
Więc w tym przypadku, po prostu jest super bezpieczny, nie idziemy na dysku coś podobnego kodu -
dobrze, co to jest rozmiar char zgodnie z tym co mówiliśmy do tej pory?
Mamy dość dużo mówi ustnie, że to 1 bajt, i to dość dużo prawda całej planszy.
Ale znowu, założenia wydają się być złe.
Prowadzą one do wadliwego oprogramowania, jeśli ludzie używają oprogramowania w sposób, który nie powinien.
Więc to stąd abstrakcyjny i tylko bardziej ogólnie powiedzieć
Muszę to wiele fragmentów pamięci
a każdy fragment pamięci powinny odpowiadać wielkości charakteru
która w rzeczywistości jest równa 1 w tym przypadku, ale jest to bardziej ogólny sposób pisania.
Więc jeśli jest słowo hello, ile bajtów ma malloc podobno przeznaczyć komentarzy
[Uczeń] Six. >> Six. Dokładnie tyle, ile mamy znaki zapytania na ekranie.
A następnie podjąć Chyba teraz oparte na zrozumieniu getString
co to malloc prawdopodobnie wrócić? >> [Uczeń] adres.
Adres z czego? Pierwszy fragment pamięci.
>> Nie mamy pojęcia, co tam jest, ponieważ niektóre inne funkcje
można było za pomocą tej pamięci wcześniej.
Ale malloc, jak getString, zwraca adres pierwszego bajtu pamięci
że ona zarezerwowana dla Ciebie.
Jednak to, co nie zrobić, to wypełnić puste ze znaku pustego odwrotnym ukośnikiem
bo okazuje się, można użyć malloc przeznaczyć wszystko: wskazówki, ciągi znaków, tablice,
pływaków, konstrukcje studentów.
Możesz użyć malloc zupełnie ogólnie.
To nie obchodzi lub wiedzieć, co masz przydzielania pamięci dla.
Więc byłoby aroganckie dla malloc umieścić \ 0
na koniec każdego kawałka pamięci, że daje ci
bo to \ 0 jest to tylko konwencja ciągów.
To nie jest używany do wskazówki, to nie jest używane dla pływaków, to nie jest używane dla studentów.
I tak gotcha z malloc jest to, że ciężar jest wyłącznie od Ciebie programista
pamiętać ile bajtów Ci przydzielone i nie kiedykolwiek użyć pętli for
lub pętla i przejść obok granicy fragmencie pamięci, którą ci dał.
Innymi słowy, jak najszybciej przydzielić pamięci,
nie można prosić system operacyjny, och, tak przy okazji, jak duży fragment pamięci to było?
To zależy wyłącznie od Ciebie, aby pamiętać, jeśli chcesz tę wartość.
>> Zobaczmy więc, jak ja przystąpić do korzystania z tej pamięci.
W linii 28 i 29, dlaczego ja to robię?
Wystarczy całkowita kontrola poprawności.
Tylko w przypadku, coś poszło nie tak, proszę o jakiś szalony ilości pamięci
czy ja tak wiele rzeczy działa na komputerze, który nie tylko nie jest za mało pamięci,
coś w tym stylu, to przynajmniej chcesz sprawdzić, null.
W rzeczywistości, większość komputerów daje złudzenie, że każdy program
może korzystać z całości pamięci RAM,
ale i tak, jeśli użytkownik wpisze w jakiś szalony ciąg długi Może dlatego, że jesteś złym człowiekiem
i są one rzeczywiście próbuje awarię programu lub włamać się do niego,
chcesz przynajmniej sprawdzić wartość zwracaną malloc i czy jest równa null.
A jeśli tak, to niech po prostu rzucić się teraz, bo nie wiem co zrobić w tym przypadku.
Jak mogę skopiować ciąg? Jest kilka sposobów, aby to zrobić.
Istnieje str skopiować funkcje w C, ale jest to bardzo proste dla nas, aby to zrobić w staromodny sposób.
>> Pozwól mi najpierw dowiedzieć się, co długość s jest.
Mógłbym umieścić to w pętli, ale zamiast po prostu umieścić go tutaj dla jasności.
N zapisuje się więc długość oryginalnego łańcucha, który jest pozornie 5.
Wtedy w mojej pętli for Mam iteracji od 0 o do n,
i na każdej iteracji Kładę s [i] wewnątrz t [i].
Więc to, co ja z moimi 2 dorozumianych palców wskazujących na strunach przed.
Jak to dla pętli iteracji tak, idę do kopiowania h do tutaj,
e się tu do l, ponieważ ten jest S, to T.
I wtedy wreszcie w linii 35, dlaczego ja to robię?
Muszę się upewnić, że jestem kończąc t string.
I zrobiłem to w ten sposób, aby być super wyraźne.
Ale proponuję, kogoś, jeśli można, inny sposób to robi.
I naprawdę nie trzeba wiersz 35. Jest inny sposób aby to zrobić.
Tak. >> [Niesłyszalne reakcja studentów] >> Powiedz to głośniej.
[Uczeń] Mniej niż lub równe. >> Dokładnie.
Można powiedzieć, że po prostu mniej niż lub równe N, który w ogóle nie było złe
ponieważ niemal zawsze, gdy idziemy do równa rzeczy Liczymy
idziemy 1 krok za daleko.
Ale pamiętaj, jak wiele bajtów mogliśmy przeznaczyć?
Mamy przyznane strlen S, więc 5 + 1, w sumie 6.
Więc w tym przypadku można było zrobić coś takiego
tak, że jesteśmy nie tylko kopiowanie, ale również cześć \ 0 na samym końcu.
Alternatywnie, możemy użyć funkcji o nazwie str kopiowanie, strcpy,
ale to nie będzie aż tak dużo zabawy.
Ale to wszystko robi się pod maską.
Wtedy wreszcie możemy zrobić to samo, co wcześniej.
I wykorzystać t, a potem twierdzą, że oryginał wygląda i kopia wygląda.
Więc spróbujmy to teraz. Puść mnie tutaj. Producent copy2. Będziemy powiększać i uruchomić copy2.
Zamierzam wpisać witam małymi literami, i rzeczywiście mam małe halo jak oryginał
ale stolica Witaj na kopii.
Ale ja nie skończyłem jeszcze. Muszę zrobić 1 ostatnią rzeczą tutaj.
46 i 47 jest wyraźnie zwalniania pamięci, ale co to właściwie znaczy?
Co robię, myślisz, dzwoniąc linii 46 i linii 47?
Jaki wpływ to ma? Tak.
[Niesłyszalne reakcja studentów] >> Dokładnie.
>> Jesteś po prostu mówiąc system operacyjny, hey, dzięki za tą pamięcią.
Teraz można używać go do kogoś innego.
I tutaj jest doskonałym przykładem wartości śmieci.
Właśnie tę pamięć używana do zapisywania słowo hello w 2 miejscach,
tutaj, tutaj, tutaj i tutaj.
Tak więc jest to H-L-e-l-o-\ 0.
Ale potem zadzwonić linii 46 i linii 47, a wiesz, co tam się dzieje pod względem obrazu?
Właściwie, czekaj, to zdjęcie jest stare.
Kiedy wykonać kopię, ten facet jest faktycznie skierowany tutaj
więc niech usunąć numery i po prostu streszczenie dala jak nasze strzały ponownie.
Co się dzieje na tym zdjęciu, gdy zgłoszę darmo?
[Niesłyszalne reakcja studentów] >> Nawet.
Jeśli zadzwonić pod bezpłatny S i T - rodzaj podchwytliwe pytanie - to obraz nie zmienia się w ogóle
bo dzwoni s oraz wzywając t tylko informuje system operacyjny,
hej, można użyć tej pamięci na nowo, ale to nie zmienia to null
lub jakiś znak specjalny, to nie ma to zmienić,
to nie zmienia h lub E lub L lub L lub O w każdym miejscu, do niczego innego.
Jeśli chodzi o zdjęcia, jak tylko zadzwonić bezpłatne, nic nie zmienia.
I na tym polega pochodzenie wartości śmieci bo jeśli potem w tym programie
zwrócić się do systemu operacyjnego, aby uzyskać więcej pamięci z getString lub malloc czy coś takiego
i system operacyjny, mówi, na pewno, mam 12 bajtów pamięci tylko uwolnionych,
korzystać z tych, co mają zamiar być przekazane?
Masz zamiar zostać wydany kawałek pamięci, że będziemy rysować zazwyczaj
ze znakami zapytania, ale co to są te znaki zapytania?
Przebywają h-l-e-l-O-H-l-e-l O.
To są nasze nowe wartości śmieci jak najszybciej zwolnić tej pamięci.
>> Jest prawdziwa implikacja świat tutaj.
Dzieje się to zrobić z pamięci RAM, ale komputery
faktycznie zrobić to samo z dysku.
Porozmawiamy o tym w szczególności przyszłego zbioru problemowego, który skupia się na kryminalistyce.
Ale to, co naprawdę się dzieje, jeśli masz jakieś poufne finansowej plik na pulpicie
lub niektórych szkicowy JPEG i przeciągnij ją do kosza,
co się dzieje po przeciągnięciu go do kosza lub kosza?
Wiedziałeś, co miałem na myśli. [Śmiech]
Co się dzieje, kiedy już wyciągnął, że dowody w kosza lub kosza?
[Niesłyszalne odpowiedź uczeń]
Cóż, więc uważaj. Co się dzieje, kiedy to zrobić?
Krótka odpowiedź brzmi: nic, prawda?
Sketchy lub wrażliwe plik jest nadal tylko siedzi gdzieś tam w dysku twardym.
Większość z nas przynajmniej nauczyłem się na własnej skórze, że trzeba opróżnić kosz
lub twój kosz faktycznie usunąć pliki.
I rzeczywiście, po kliknięciu prawym przyciskiem myszy lub Sterowanie Kliknij na śmietniku
lub wybierz Plik, Opróżnij kosz lub cokolwiek
i rzeczywiście opróżnienia kosza lub kosza, co faktycznie dzieje się potem do tego obrazu?
Więcej nic. Więc nic faktycznie dzieje się na dysku.
>> I jeśli tylko tymczasowo dygresję i pisać - ll wystarczy użyć tył to.
Więc teraz historia się zmienia z pamięci RAM, co jest gdzie programy istnieją
podczas biegu je na dysku, czyli tam, gdzie są one przechowywane długoterminowo
nawet wtedy, gdy zgaśnie światło, teraz - i wrócimy do tego w przyszłości -
niech po prostu udawać, że jest to dysk wewnątrz napędu komputera
bo już w dzień kiedyś okrągłe tarcze, tak jak dyskietki.
Więc jeśli masz jakieś poufne plik programu Excel, może podjąć się tego kawałek pamięci
na dysku komputera, a ja po prostu rysunek sam dowolnego 1s i 0s.
Po przeciągnięciu pliku podobnego do kosza lub kosza,
dosłownie nic nie dzieje się dlatego, że Apple i Microsoft po prostu postanowił
kosza, a kosz jest naprawdę tylko chwilowy zastępczy.
Może w końcu OS będzie opróżnić go dla Ciebie, ale zwykle, nie robi nic,
przynajmniej dopóki jesteś naprawdę mało miejsca.
>> Jednak, gdy idziesz do pustego kosza lub pustego kosza,
podobnie, nic się nie dzieje na tym zdjęciu.
Wszystko, co się dzieje, jest w innym miejscu na komputerze, nie jest jakimś stole.
To trochę jak mały arkusza ściągawki, które mówi, że, powiedzmy, resume.doc,
więc swoje CV w pliku Microsoft Word żyli w miejscu 123 na dysku twardym,
nie w pamięci, a nie w pamięci RAM, ale na dysku twardym,
a twoje życie sketchy JPEG w 456, a plik Excel mieszka w 789 lub gdziekolwiek.
Po usunięciu plików przez faktycznie opróżnianie kosza lub kosza,
ten obraz nie zmienia się. 0s i 1s na dysku twardym, nie idź nigdzie.
Ale ta tabela, ta mała baza danych z wszelkiego rodzaju, czy zmiany.
Gdy usuwasz swoje CV, to tak, jakby plik został usunięty w pewnym sensie,
ale komputer nie jest zapomnieć, gdzie to coś żyje na dysku twardym.
0s i 1s że komponować swoje CV lub jakichkolwiek innych plików są nienaruszone.
>> Więc jeśli zrobił to przypadkowo, nadal jest niezerowe prawdopodobieństwo
że można odzyskać dane za pomocą programu Norton Utilities lub niektóre komercyjnego oprogramowania
którego celem w życiu jest znalezienie 0s i 1s, które jakby zostały osierocone,
Zapomnieliście tutaj, ale tutaj w lewo, tak, że można uzyskać dane z powrotem.
Badacze z medycyny sądowej lub policji lub FBI rzeczywiście wziąć dysk
i rzeczywiście szukać wzorców 0s i 1s, które wyglądają jak JPEG, wyglądają jak pliki Excel,
i odzyskać je w ten sposób, nawet jeśli komputer zapomniał je tam.
Tak naprawdę jedynym sposobem, aby usunąć dane, jak omówimy w przyszłości,
jest do szorowania lub wytrzeć plik lub dysk twardy -
Naprawdę nie można się pozbyć 0s i 1s
bo inaczej chcesz zacząć gigabajtowym dysku twardym
i chcesz skończyć z megabajt dysku twardym, jeśli stale były usuwanie,
dosłownie 0s i 1s.
Więc co zrobić, jeśli naprawdę chce pokryć swoje utwory
i podstawowym problemem jest to, że jest jeszcze 0s i 1s na dysku?
Widzę kogoś gestykulując, że fizycznie złamać urządzenie. Że będzie działać.
[Śmiech] Ale jeśli to trochę drogie rozwiązanie, co byłoby bardziej rozsądne?
Tak. >> [Uczeń] Zastąp je. Zastąp je >> co? >> [Uczeń] Inne dane.
Inne dane. Można po prostu zastąpić dysk z 0s lub 1s lub wszystkich 0s, wszystkie 1s.
>> I to jest rzeczywiście to, co niektóre z oprogramowaniem.
Można kupić oprogramowanie lub nawet dostać wolnego oprogramowania,
a nawet wbudowane w Mac OS tych dni, mniej w systemie Windows,
jest możliwość, aby bezpiecznie usunąć.
Właściwie, jeśli chcesz wszystkich home run dzisiaj, jeśli masz komputer Mac i to zrobić,
jeśli masz trochę rzeczy w kosza, można zrobić Opróżnij Kosz bezpiecznie,
który robi dokładnie to.
A nie tylko pliki wymazywania tutaj, to nie kasuje 0s i 1s tutaj
raczej, po prostu zmienia je wszystkie, na przykład, do 0 i kropka, kropka, kropka.
Więc jednym z Twoich przyszłych psets rzeczywiście będzie celowo odzyskać dane -
fotografie, które podjęliśmy z ludzi, miejsc i rzeczy, na terenie kampusu
dla których zrobimy kryminalistycznych obraz cyfrowy na karcie pamięci aparatu,
który jest dokładnie taki sam pomysł - i musisz być kwestionowane rzeczywiście znaleźć
wzory, które reprezentują JPEG na twardym dysku,
tak jak tego byłego studenta, którego email Czytałem kilka tygodni temu zrobił
w celu odzyskania swojej siostry fotografie.
Dlaczego nie zrobić 5-minutową przerwę, tutaj, a my przegrupować z więcej pamięci.
Tak tu jest gdzie rzeczy trochę umysł gięcia, ale jest to bardzo potężny krok
kierunku zrozumienia tego wszystkiego więcej.
Tutaj jest program o nazwie pointers.c.
Jest wśród dzisiejszej przykładowego kodu.
Zauważ, że w pierwszych kilku liniach, 19 do 22, wszystko co robimy jest czymś getString
i zwracanie adresu, przechowywanie go w sekundach.
Odtąd dla Pset nawet 3 jeśli chcesz, ale pset 4 oraz
gdzie można zacząć przyjmować te kółka off siebie,
nie ma powodu, aby udawać, że struny istnieje.
Na pewno jest to w porządku, aby po prostu zacząć mówić char *.
>> Tak na marginesie, w internetowych referencje i w książkach można często zobaczyć gwiazdę obok zmiennej.
Można nawet zobaczyć miejsca w okolicy obu jej stronach.
Wszystkie te są funkcjonalnie poprawny.
Na razie jednak, będziemy standaryzacji na tym podejściu do super jasne
że char * to jak mówienie, wskaźnik znaków.
To jest typ danych.
I wtedy nazwa zmiennej jest s w tym przypadku.
Więc staliśmy ciąg i nazwał to my s.
A potem tu zauważyć, że robię właściwie trochę oszustwa.
To się nazywa arytmetyczne wskaźnika, który jest swego rodzaju super proste.
To oznacza tylko dodawać i odejmować liczby do wskaźników.
Ale to faktycznie działa.
Ten program podobno wypisuje łańcuch s 1 znak w każdym wierszu, takich, że końcowy wynik -
Tylko tak możemy zepsuć, gdzie to będzie, sprawdź wskaźniki, uruchomić wskazówki, niech powiększyć
Teraz niech mi typ w coś Witam i typ Enter
i drukuje 1 znak w wierszu.
Aż sekund temu, byśmy zrobili to z kwadratową notacji wspornika.
Mielibyśmy do pętli i zrobimy printf z s [i] i chcemy to zrobić ponownie i ponownie i ponownie
z n Backslashe na końcu każdej linii.
Ale ten program jest inny. Ten program jest za pomocą dosłownie arytmetyki.
Więc co tu się dzieje?
Przede wszystkim, zanim jeszcze ta pętla wykonuje, co, żeby było jasne, to jest faktycznie?
S? >> [Uczeń] adres. >> Adres.
>> A to adres, w przypadku komentarzy, pierwszy znak w tym słowie, które jest godz.
Tak więc jest to, w tym konkretnym przykładzie, adres godzin.
Więc co to znaczy zrobić s + i?
No, i zaczyna się od 0 w tym dla pętli. Zrobiliśmy, że wiele razy.
I ma zamiar iść do długości łańcucha, najwyraźniej.
Tak więc w pierwszym iteracji tej pętli, i to oczywiście 0.
Więc to wyrażenie mówi s + i -, a, s +0--to oczywiście tylko s.
Więc co to jest * s tutaj?
Teraz używamy gwiazdę w nieco inny sposób.
Pozwólcie mi iść do przodu i pozbyć t bo skończymy mówić o t i kopii tych.
Teraz chcemy tylko opowiedzieć historię z udziałem s.
I tak w tej chwili, po typu String, nasz świat wygląda zupełnie jak przedtem
z tylko s przechowywania adresu h i ogólnie wskazuje na ciąg hello.
Jeśli teraz zrobić linię * (s + i), spróbujmy to.
Tak * (S + i). Pozwól, że uproszczenie to, ponieważ jest to 0, więc jest to * (s +0).
Dobrze, chwileczkę. Dalsze uproszczenie. To * (S).
Cóż, teraz nawiasy są głupie, więc teraz niech po prostu zrobić * s.
Tak więc w pierwszej iteracji tej pętli, że linia, która jest podświetlona, ​​26,
jest prawie równoważna drukowania to.
Co to jest typ danych * s?
W związku z tym, ponieważ gwiazda bywa przy s samej
, ale bardziej szczegółowo, ponieważ są już stwierdzenie s,
nie jesteśmy już utworzenie zmiennej, nie ma wzmianki o char * w linii 26,
Nie ma wzmianki o ciąg słów kluczowych, są po prostu za pomocą zmiennej o nazwie s,
Okazuje się teraz gwiazda ma nieco inne i, trzeba przyznać, myląc znaczenie.
* S oznacza tu iść na adres w s i wydrukować cokolwiek tam jest.
Więc s jest tutaj, * s jest - coś jak Chutes i drabiny, śledzić strzałkę - tutaj.
Więc to jest * s.
>> Więc co zostanie wydrukowane na pierwszej iteracji pętli w linii 26?
Mogę wydrukować% C, która jest symbolem zastępczym charakterze,
następnie \ n dla nowej linii. * (S + i) gdzie i jest 0 jest właśnie to.
Więc co char mam umieścić w na% c? H.
W następnej iteracji pętli - prawdopodobnie można zobaczyć, gdzie to się dzieje -
Następna iteracji jest oczywiście 1, więc oznacza to, s +1,
a teraz trzeba nawiasów bo teraz gwiazda musi powiedzieć
przejdź do adresu pamięci s +1.
Co to jest s? Miejmy cofnąć się w czasie i powiedzieć, że to główna teraz nie jest rzeczywiście robi nam żadnych przysług.
Niech to dokładniej powiedzieć, że to jest przechowywanie 123 numer
, ponieważ na początku tego ciągu cześć, to adres 123 jest 124, i tak dalej.
Więc na drugiej iteracji, kiedy mówię, s. 1, to jak powiedzenie 123 1,
inaczej znany jako 124, więc co char zostanie wydrukowany na drugiej iteracji?
E na adres pamięci 124.
Potem znowu +, 125, 126, 127, i to na szczęście zatrzymuje się przed pętla tu dostaliśmy
ponieważ używam strlen, aby upewnić się, że nie liczy się zbyt wysoka.
Więc to też jest to.
Ponownie, to jest po prostu tak, jakbyśmy zrobili tydzień temu.
Pozwól, że piszę to na linii poniżej, mimo że nie chcę tego robić obie.
Obecnie jest identyczne z tym.
>> Więc nawet jeśli jest to ciąg, jak dzwonię to za tydzień, s jest naprawdę char *.
Więc jeśli chcemy być super anal, to naprawdę wypada napisać na specyficzny charakter
at-tego miejsca za pomocą tych adresów numerycznych i gwiazda tego operatora,
ale szczerze mówiąc, to jest po prostu tak dużo czystsze. Więc to nie jest złe.
Nie ma powodu, aby przestać robić linii 27 tutaj, ale 26 jest funkcjonalnie taka sama,
i jest funkcjonalnie takie same dokładnie powodów, że byliśmy omawianie tej pory.
I wreszcie, 29 jest po prostu dobra praktyka.
Telefonowanie bez s oznacza, że ​​teraz dajesz z powrotem pamięć GetString dał ci
bo znowu, jak już wspomniałem poniedziałek, za tydzień getString
został wprowadzenia błąd w kodzie.
Kod na tydzień miała przecieki pamięci
której zostałeś prosząc getString dla pamięci, ale nigdy nie zostały dając go z powrotem.
I że został celowo wybrany przez nas pedagogicznie
bo to jest po prostu zbyt wiele do myślenia na początku.
Ale teraz potrzebujemy więcej symetrię.
Jeśli spytasz komputer do pamięci, jak to jest w przypadku getString,
jak to ma najwyraźniej na malloc,
musisz teraz Pset 4 począwszy również bezpłatny takie pamięci.
Zawiadomienie to jest inne od powiedzenia int n.
Nie musisz uwolnić to, bo nie zadzwonił getString
a nie wywołać malloc.
>> I nawet jeśli nazywa getInt jak my w końcu zobaczyć,
GetInt nie przydzielić pamięci dla ciebie, bo rzeczywiście można przejść wokół liczb całkowitych
i pace i chars właśnie sposób robiliśmy przez kilka tygodni.
Struny są jednak wyjątkowy, bo naprawdę są połączeniem wielu znaków.
Więc oni są tylko różni się od znaków i pływaków oraz wskazówki i tym podobne.
Ale wrócimy do tego, przed długi.
Wszelkie pytania na owym początku wskaźniki? Tak.
[Niesłyszalne pytanie uczeń]
Ach, bardzo dobre pytanie.
Jedną z niewielu rzeczy, C faktycznie robi dla Ciebie, co jest wygodne,
są to dane dla ciebie co rozmiar jest typu danych
a następnie robi to rodzaj rozmnażania dla Ciebie.
To nie ma znaczenia w przypadku znaków, ponieważ prawie zawsze char jest 1 bajt,
tak to właśnie działa.
Ale dla dobra dyskusji, jeśli zostały rzeczywiście drukowania liczb całkowitych
i próbowano wydrukować niektóre wartości s, który wskazując na liczbę całkowitą,
Państwo również nie musiałby robić + 4 * i tylko dlatego, że int jest 4 bajty.
Arytmetyczna wskaźnika oznacza, że ​​kompilator C i zrobić wszystko, matematyki dla Ciebie.
Wszystko, co musisz się martwić o to liczenie w rodzaju ludzkim sensie. Tak.
[Uczeń] Jeśli zadeklarować ciąg wewnątrz pętli for, masz do uwolnienia go później?
Dobre pytanie.
>> Jeśli zgłoszone w środku ciąg dla pętli, jest potrzebna, aby zwolnić go później?
Wystarczy tylko wolnej pamięci, którą przydziela z getString lub malloc.
Więc jeśli tylko powiedzieć coś takiego - powiem nawiasy klamrowe, tak teraz cały kod jest powiązane.
Jeśli zrobił coś, aczkolwiek buggily, podobnie jak to, char * t = s,
nie trzeba do wolnych t bo t nie obejmowała żadnej wzmianki malloc lub getString.
Natomiast, jeśli to zrobił, GetString, to tak, trzeba byłoby wolnych t.
I rzeczywiście, twoja jedyna szansa na to, że jest teraz wewnątrz tej pętli, w tym samym numerze zakresu
że już omówione w przeszłości.
W przeciwnym razie możesz być przydzielania pamięci, przydział pamięci, przydział pamięci,
i na koniec, ponieważ jesteś programu poza pętli,
t nie istnieje, ale nigdy nie powiedział, system operacyjny
że nie trzeba, że ​​pamięć już.
I niebawem, dla 4 lub 5 PSET będziemy wyposażyć się program o nazwie Valgrind,
które jest podobne w duchu do GDB w tym, że ma nieco z tajemnej interfejsu
ale jego celem w życiu jest aby ci pomóc.
I Valgrind to program, który będzie w przyszłości szukać programów
poszukuje wycieków pamięci, czy z getString lub malloc,
którego zaczniemy przy tym bardziej jak zaprzestać używania CS50 bibliotekę tyle.
W końcu teraz rodzaj słownictwa i rodzaj mentalnego modelu w teorii
w którym, aby rozwiązać ten wadliwy program.
>> Więc w tym wadliwy program, swap działa wewnątrz swapu
ale nigdy tak naprawdę pracował w Głównym ponieważ główny przeszedł w xiy, wycofywania
a te były przekazywane przez wartości w, że tak powiem.
Ich kopie zostały przekazane swap.
Do końca konwersji, A i B zostały faktycznie wymianie
ale oczywiście x i y, jak rozmawialiśmy w poniedziałek, nie było.
Więc proponuję na zielono tutaj, że to jest rzeczywiście rozwiązaniem.
I faktycznie, pozwól mi przenieść moje gwiazdy po prostu być spójne
choć znowu, funkcjonalnie nie ma to znaczenia.
W przyszłości tydzień będziemy wyjaśnić, kiedy i dlaczego to ma znaczenie.
Więc na zielono to rozwiązanie.
Szczerze mówiąc, wygląda to dużo bałaganu, bo mam wszystkie z tych gwiazd.
Pozwól mi wskazać jedną rzecz.
Top line tutaj gdzie mówi int * i int * b
jest zasadniczo robi to samo, co zawsze.
Jest deklarując 2 argumenty lub parametry do wymiany,
z których pierwszy jest int wskaźnik nazywa,
z których drugi jest int wskaźnik zwany b.
Jedyne, co nowego jest w tym miejscu fakt, że nie jest gwiazdą tam.
>> Co to znaczy? Nie int, B nie jest int.
To adres int, a b jest adres innej int.
Tu, w tym miejscu przyznać, C dostaje mylące.
Teraz używamy gwiazdą, ale ma inne znaczenie w tym kontekście.
Ponieważ nie jesteśmy deklarowania wskaźników, jak jesteśmy tu,
tutaj jesteśmy dereferencji rzeczy.
Więc technicznie, gwiazda w tym kontekście pierwszej, drugiej i trzeciej linii wewnątrz swapu
jest operator dereference, co oznacza po prostu tam iść.
Tak, jak mój palec następnie strzałkę h,
* Środkiem przejść do tego adresu i znajdź mi int, który jest tam.
* Oznacza b Przejdź do adresu i przekazać mi, co tam jest.
Więc odświeżanie obrazu z poniedziałek teraz używając stos ramek
z których dolna będzie głównym,
z których górna będzie wymiany,
tak, że nasz świat wygląda tak jak poniedziałek, jak to.
Oto fragment pamięci, że główny będzie używać.
>> Przypomnijmy, od poniedziałku, że program po prostu mieliśmy 2 zmienne,
jeden o nazwie X i jeden o nazwie r, a włożyłem numerami 1 i 2 tam.
Teraz gdy zgłoszę zamienić jak ja w poniedziałek,
wcześniej, gdy użyłem czerwonej wersji tego programu, który wygląda tak,
Mam 2 parametry, A i B, i co piszemy tu i tu?
Tylko 1 i 2, dosłownie kopiuje xiy.
Dziś to zmienić.
Dziś zamiast przekazując wskazówki i b będziemy przechodzić w 2 adresy.
Te adresy stanie wskazać na wskazówki, ale te adresy nie są wskazówki siebie.
Są to adresy. To jak adres pocztowy zamiast.
Więc teraz musimy po prostu dać sobie trochę więcej szczegółów na ekranie.
To jest mój pamięci komputera jak to było przez cały dzień.
Teraz musimy trochę dowolny system numeracji.
Więc powiedzmy, po prostu przez przypadek, że jest to adres w pamięci 123, 124.
Powiedzmy, że jest to 125, to jest 126, i tak dalej, ale to jest całkowicie arbitralne.
Musimy tylko trochę schemat numerowania w mojej pamięci.
Więc teraz, kiedy faktycznie przechodzą w x i y, nie mam zamiaru przechodzić w xiy;
Zamierzam przekazać w adres pocztowy, by tak rzec, z x i y
tak, że to, co zostaje zapisane tu i tu nie jest 1 i 2,
ale jeśli można zobaczyć mój mały tekst, jaki zostanie przeniesiony tu i tu?
[Niesłyszalne reakcja studentów] >> Dokładnie. 123 dostaje umieścić tutaj i 124 pobiera umieścić tutaj.
>> Teraz, ponieważ użyłem gwiazdę w tej pierwszej linii sposób tu na górze,
mój program po prostu wie, że 123 i 124, choć są oczywiście liczbami całkowitymi
że każdy człowiek mógł zauważyć, powinny one być interpretowane jako adresy, adresy numeryczne.
Nie są one same w sobie wskazówki, są adresy,
a to dlatego, że wyraźnie umieścić gwiazdy tam.
Więc teraz w mojej pierwszej, drugiej i trzeciej linii rzeczywistego kodu, co dzieje się tutaj?
Narysujmy resztę obrazu.
Tmp jest tak jak to było w poniedziałek. Nic specjalnego tmp.
To jest zaledwie 32 bity lokalne zmienne, i wewnątrz, że jestem podobno przechowywania wartości *.
Teraz, jeśli tylko powiedział tmp =, co chciałbym umieścić tutaj? >> [Uczeń] 123.
123. Ale to nie jest to, co robię.
Mówię tmp = *. Oznacza gwiazdkowe tam.
Tak tu jest, 123. Jak mam tam iść? Udawaj, że jak nie ma strzałki.
Także, że jest on, 1. Więc co dostaje przechowywane w tmp, najwyraźniej? Tylko 1.
Tak więc inaczej mówiąc, TMP jest * a, * środkiem Do adres, który jest obecnie,
który jest podobno 123.
>> Dobra, jesteśmy na miejscu 123, widzę numer 1,
więc mam zamiar umieścić numer 1 tam.
Co mam teraz zrobić, w wierszu 2, * = * b?
Ten jest trochę bardziej zaangażowane, ponieważ teraz to, co jest? Jest 123.
Więc * jest gdzie? Tam, gdzie byłem wcześniej. Więc idź tam. Okay.
Teraz, wreszcie, w końcu to zacznie mieć sens, mam nadzieję,
* B oznacza, co jest w B? 124. Więc muszę tam iść, co jest 2.
Więc co mam umieścić gdzie?
2 przechodzi tu, bo * b przechodzi w *. Więc będę robić.
I widać już, być może, że jesteśmy o wiele bliżej
do rozwiązania tego głupiego, prostego problemu poprawnie po raz pierwszy
bo teraz mamy jeszcze pamięta co było x,
mamy 2 egzemplarze, co prawda, y,
ale linia 3 teraz mówi, * b.
Tak tu jest b. * Oznacza b tam. Więc gdzie jest miejsce 124?
To najwyraźniej tutaj. Więc co mogę umieścić tutaj? Oczywiście, tmp.
Więc teraz to zrobić. Więc mam 1 tu i 2 tutaj.
A teraz, co o tym wszystkim, 123, 124, a 1?
Jak tylko wraca swap, ta pamięć jest tak dobra, jak porażka
bo jak tylko zwrotów typu swap, system operacyjny
jest do wykorzystania tej pamięci ponownie w przyszłości.
Tylko w pamięci głównej, na dole stosu tzw wystaje wokół.
>> I tak w końcu mamy teraz wersję roboczą.
Pozwólcie mi iść do swap.c i zauważyć, co następuje.
Na początku programu Zmieniłem prototypu jest int a * b * int.
Jedyne więc zmieniłem przejść z czerwonym, który był zły, na zielony, co jest dobre,
jest dodałem te gwiazdy dziś.
Ale wtedy tutaj w zamienić się musiałem skopiować, wkleić to, co było po prostu na slajdzie.
Mam tu gwiazda, gwiazda tutaj - który pasuje do prototypu -
a wszystkie te rzeczy mają teraz gwiazdy oprócz tmp
ponieważ stosowanie zmiennej tymczasowej, nie ma nic nowego.
Muszę tylko tymczasowe magazynowanie dla int.
Więc nie musimy gwiazdę tam.
Musimy tylko gwiazdę tak, że możemy przekroczyć tego rodzaju arbitralnej granicy
między tymi 2 klatek w mojej pamięci komputera.
Ale jedna rzecz musi się zmienić, a może nie dostrzegł go już.
Co druga linia jest oczywiście teraz inaczej? >> [Uczeń] & x.
>> Tak, więc 25 jest ostatni wiersz kodu trzeba zmienić, aby to zadziałało.
Tydzień temu, a nawet w poniedziałek, linia 25 wygląda tak, swap xiy,
i to było po prostu zepsuty, bo jeśli powiesz swap (x, y)
dajesz kopie xiy do wymiany, to robi swoje,
ale nigdy nie rzeczywiście się zmienia xiy sama.
Tak więc, nawet jeśli nigdy wcześniej nie widziałem tego znaku przed z ampersand w kodzie,
tylko zgadywać. Co ampersand robić, najwyraźniej?
[Uczeń] Staje adres. >> Staje adres.
Więc ampersand mówi dać mi adres x.
Kto wie gdzie to jest? Zdarza się 123. Nie obchodzi mnie to. Daj mi adres x.
& Y oznacza dać mi adres y.
I w tym momencie historia jest całkowicie spójny z obrazem nakreśliliśmy chwilą.
>> Więc muszę przyznać wskaźniki, na pewno dla mnie, gdy po raz pierwszy rozpoczęła naukę tego,
była z pewnością jedną z najtrudniejszych rzeczy do zawijania zdanie wokół.
Ale uświadomić sobie, szczególnie, że nadal grać z tego typu rzeczy,
jeśli rozbicie go na te super proste rodzaju intelektualnie nieciekawe problemy
po prostu przenoszenie numerów wokół, odpowiedź na wiele nieporozumień ze wskaźnikami
rzeczywiście można otrzymać z tych podstawowych mechaniki bardzo.
Tu jest adres. Tam z gwiazdy.
Albo odwrotnie, tu ampersand. Dowiedzieć się, co adres jest w rzeczywistości.
Dobrze.
Więc gdzie jest wszystko to pochodzi z pamięci?
Musimy wyciągnąć ten obraz kilka razy, i zachować obiecujące wrócimy do niego,
ale tutaj jest reprezentacja pamięci komputera
To trochę więcej niż nasz tablicy oznaczony tu jest.
Fragment tekstu na górze reprezentuje to, co w odniesieniu do programu?
[Niesłyszalne reakcja studentów] >> Przepraszam? Powtórz.
[Uczeń] rzeczywisty program. >> Rzeczywisty program.
>> Więc 0s i 1s, które zostały opracowane po napisaniu kodu w C, a następnie uruchomić Clang
i generowania 0s i 1s kończy się uzyskiwanie schowany tam w pamięci
ponieważ po dwukrotnym kliknięciu ikony na komputerze Mac lub PC
lub uruchomić polecenie podobne do mario w znaku zachęty, Twój 0s i 1s z dysku
ładowane do pamięci, tak, że komputer może nimi manipulować
i wykonać je szybciej.
Więc założone dane i niezainicjowanych danych, nie będziemy mówić zbyt wiele o tych,
ale to są tylko zmienne globalne.
Zainicjowany oznacza zmienne globalne, które dały wartości;
niezainicjowanych oznacza zmienne globalne, które jeszcze nie dają wartości.
Potem jest zmienne te, które ja całkowicie kołysanie na rękę,
ale one tam są i że przechowuje takie rzeczy jak nazwy użytkownika
oraz z innych gatunków niższych szczegółów szczebla.
Ale najbardziej soczyste kawałki twojej pamięci w układzie jest ta rzecz zwana stosu i sterty.
Stos ponownie, aby było jasne, to pamięć, która jest stosowana przy każdym funkcje są uruchamiane,
gdy istnieją zmienne lokalne
i kiedy tam są parametry były przekazywane wokół.
Wszystko, co dzieje się w stos.
Kupa nie rozmawialiśmy na temat, ale Zgadnijcie kto używa sterty.
Tylko inny fragment pamięci.
Zdarza się wyciągnąć w górę, ale to jest arbitralne obrazowym umowy.
Kto najwyraźniej przy użyciu pamięci ze sterty za tydzień?
To technicznie jesteś, ale pośrednio. >> [Uczeń] GetString.
GetString i malloc. Tak tu jest zasadnicza różnica.
>> Wiesz, w ciągu ostatnich kilku tygodni, że jeśli potrzebujesz pamięci, wystarczy zadeklarować zmienną.
Jeśli potrzebujesz dużo pamięci, zadeklarować tablicę tuż wewnątrz swojej funkcji.
Ale problem mamy przechowywane skierowana jest jeśli deklarować zmienne lokalne wewnątrz funkcji,
tak szybko jak to funkcja zwróci wartość, co dzieje się z pamięcią i tych zmiennych?
Jakoś to już nie jest twoje, prawda? To po prostu znika, jakby koncepcyjnie.
To wciąż tam fizycznie, oczywiście, ale to już nie jest jego prawo do korzystania.
Jest to oczywiście problem, jeśli chcesz napisać funkcje w życiu
że rzeczywiście przydzielić pamięci i nie chce go oddać natychmiast.
Sprawa w punkcie: Celem getString się w życiu, to nie mam pojęcia z góry
jak duży ciąg mam zamiar napisać na klawiaturze,
ale to musi być w stanie przydzielić pamięci trzymać Dawida lub hello
lub cały esej, że użytkownik może mieć wpisane w.
Więc GetString używa malloc.
Malloc dlatego musi być używany, nie stos;
zamiast tego używa to coś o nazwie sterty.
Nie ma nic innego w pamięci. To nie szybciej lub wolniej lub coś w tym stylu.
To jest po prostu fizycznie w innym miejscu.
>> Ale regułą jest, że pamięć, która jest przeznaczona na stercie
nigdy nie będzie wam zabrane, aż zadzwonisz - Zgadnijcie - free.
Natomiast każda pamięć poprosić na stosie po prostu deklarując tablicę
lub zadeklarowanie zmiennej jak robiliśmy przez kilka tygodni,
domyślnie, że kończy się na stosie.
I że działa bardzo 90% czasu, ale w tych przypadkach rzadszych
której chcesz przydzielić pamięci i utrzymać ją wokół,
następnie trzeba użyć funkcji takich jak malloc.
Albo stosuje się funkcję jak GetString, które z kolei wykorzystuje malloc.
Zobaczmy, co może się załamać, a następnie rzucić okiem na Binky.
Wrócimy do tego w przyszłości.
Tutaj jest bardzo prosty program, który w pierwszych 2 liniach co robi?
W języku angielskim, co te pierwsze 2 linie kodu zrobić wewnątrz main?
[Niesłyszalne odpowiedź uczeń]
Ostrożnie. To nie daje mi adres x lub y.
[Uczeń] Daje wskazówki do wskazówki. >> Dobrze. Daj mi 2 wskaźniki do liczb całkowitych.
Innymi słowy, daj mi 2 kawałki pamięci trzymam dzisiaj, rysunek
choć usunięte to teraz, jako kwadraty.
Daj mi 2 kawałki pamięci, o nazwie x, jeden o nazwie Y -
wcześniej nazwałem je s i t - i co to jest typ tego kawałka pamięci?
To będzie przechowywać adres.
To z * typu int.
>> Więc adres int końcu żyć w X,
adres int końcu żyć w y,
ale na początku, co jest w środku x i y? Kto wie? Wartości śmieci.
To nie ma nic wspólnego z wskaźniki.
Jeśli nie mamy już coś tam, kto wie, co tak naprawdę tam jest?
Teraz, x. Co tu się dzieje? To jest legalne, ponieważ teraz x jest wskaźnikiem. To int *.
To znaczy, że mogę umieścić w x adres jakiegoś fragmentu pamięci.
Co malloc powrócić? Perfect, zwraca adresy,
adres pierwszego bajtu w całym fragmencie pamięci.
Ile bajtów jest to najwyraźniej podziału, na przykład, w urządzeniu?
Co jest rozmiar int? 4.
Jeśli uważasz, że powrót do tygodni 1, to nie jest bardzo ważne, aby zawsze pamiętać, że
, ale w tym przypadku jest to użyteczne informacje, 4 bajty.
Więc to przeznacza na stercie 4 bajtów
i to wraca adres pierwszego mnie arbitralnie.
Teraz, co jest x robisz?
* X = 42 robi co?
Jeśli w tym momencie w historii mamy x, która wygląda z pewnej wartości śmieci,
to jest teraz z pewnym y wartości śmieci, teraz w linii 3 Mam przyznane 4 bajty.
Ten obraz w istocie wygląda.
Lub bardziej konkretnie, czy jest to arbitralne adres 123, to właśnie nasza historia wygląda teraz.
* X = 42 oznacza teraz co? To oznacza, że ​​należy przejść do 123 adresów i umieścić numer 42 tam.
Nie muszę narysować te linie, ponieważ nie robimy sznurki.
>> Powinienem tylko napisane, podobnie jak to, i tylko do demonstracji boską,
42 jako int rodzaju zajmuje dużo miejsca, 4 bajty.
Więc to jest to, co się tam stało, ale jest teraz problem.
* Y = 13. Co wydarzy się tutaj?
Problem jest y * w naszym uproszczonym świecie po prostu oznacza, przejdź do adresu w y.
Co znajduje się w Y? To jest jakaś wartość śmieci.
Więc załóżmy, że wartość śmieci jest 5551212, coś szalonego tak.
* Oznacza r Idź do adresu 5551212.
To jest tak, jak tutaj. Nie istnieje na przykład.
Więc * y dostaje 13 oznacza Próbuję wyciągnąć 13 tutaj. To nie istnieje.
I już przekroczył segment tablicy. Co mogę dostać?
To tajemniczy błąd segmentacji wiadomość, ponieważ staram się umieścić w pamięci
wartość jak 13 w miejscu, które nie istnieje.
Pozostała część programu może działać dobrze, ale do tego momentu nie ma.
Więc spróbujmy opowiedzieć tę historię.
Wrócimy do tego po raz rozmawialiśmy o hex.
Wróćmy do tego i zawarcia z tym czymś zwanym Binky,
których odzyskanie jest profesorem Stanford siedzieć w domu grając z claymation,
opowiadać dokładnie tego samego programu.
To tylko około 3 minut. Tutaj mamy Binky.
[Mężczyzna głośnik na video] Hey Binky, obudź się. To jest czas na zabawę wskaźnika.
[Binky] Co to jest? Dowiedz się o wskaźniki? Oh, cukierek!
[Mężczyzna głośnik] Cóż, zacząć, myślę, że będziemy potrzebować wskazówek para.
>> [Binky] Dobra. Ten kod przydziela 2 wskaźniki, które można podpiąć do liczb całkowitych.
[Mężczyzna głośnik] Dobra. Cóż, widzę 2 wskaźniki, ale nie wydają się być skierowane do niczego.
[Binky] To prawda. Początkowo, wskaźniki nie wskazują na nic.
Rzeczy, które wskazują na nazywa pointees i ustawienie ich to oddzielny etap.
[Mężczyzna głośnik] Oh, racja, racja. Wiedziałem o tym. W pointees są oddzielne.
Er, więc jak można przydzielić pointee?
[Binky] Dobra. Ten kod alokuje nowy całkowitą pointee i ta część zawiera x zwrócić do niego.
[Mężczyzna głośnik] Hey, że wygląda lepiej.
Więc zrób to coś zrobić. >> [Binky] Dobra.
Będę dereference współrzędne x wskaźnik zapisać numer 42 w jego pointee.
Do tej sztuczki będziesz potrzebował mojej magicznej różdżki z dereferencji.
[Mężczyzna głośnik] Twoja magiczna różdżka z dereferencji? To świetnie.
[Binky] To jest to, co kod wygląda. Ja po prostu ustawić liczbę i ... [Popping dźwięk]
[Mężczyzna głośnik] Hey patrz, tam idzie.
Więc robi dereference na X następująco główna dostęp do swojego pointee,
w tym przypadku do przechowywania 42 w nie.
Hej, spróbuj go zapisać numer 13 przez innego wskaźnika, Y.
[Binky] Dobra. Pójdę tu do y i uzyskać numer 13 ustawić
a następnie podjąć Różdżka dereferencji i po prostu ... [Brzęczenie] Whoa!
[Mężczyzna głośnik] Oh hey, że nie działa.
>> Powiedz, Binky, nie sądzę dereferencji y to dobry pomysł
ponieważ konfigurowanie pointee jest oddzielny etap
i nie sądzę, że kiedykolwiek to zrobił.
[Binky] Hmm, dobry punkt.
[Mężczyzna głośnik] Tak. Mamy przyznane y wskaźnika, ale nigdy nie ustawić go wskazać na pointee.
[Binky] Hmm, bardzo spostrzegawczy.
[Mężczyzna głośnik] Hej, szukasz dobry tam, Binky.
Można go naprawić, więc Y wskazuje na ten sam pointee jak X? >> [Binky] Jasne.
Będę korzystać z magiczną różdżką cesji wskaźnika.
[Mężczyzna głośnik] Czy to będzie problem, jak wcześniej?
[Binky] Nie, to nie dotykaj pointees.
To zmienia tylko jeden wskaźnik, aby wskazywał to samo co innym. [Popping dźwięk]
[Mężczyzna głośnik] Oh, widzę. Teraz punkty r do tego samego miejsca co X.
Więc czekać. Teraz r jest stała. Ma pointee.
Więc można spróbować Różdżka dereferencji ponownie wysłać 13 ponad.
[Binky] Uh, okay. Tu idzie. [Popping dźwięk]
[Mężczyzna głośnik] Hej, popatrz na to. Teraz dereferencji prace na y.
A ponieważ wskaźniki dzielą ten jeden pointee, oboje zobaczyć 13.
[Binky] Tak, udostępniania. Cokolwiek.
>> Więc mamy zamiar zamienić się miejscami teraz?
[Mężczyzna głośnik] Oh look, jesteśmy poza czasem. >> [Binky] Ale -
[Mężczyzna głośnik] Wystarczy zapamiętać 3 zasady wskaźnika.
Numer 1, podstawowa struktura jest, że masz wskaźnik ten wskazuje na do pointee.
Ale wskaźnik i pointee są oddzielne, a powszechnym błędem jest ustawienie wskaźnika
ale zapomnij dać mu pointee.
Numer 2, dereferencji wskaźnik zaczyna się wskaźnika i stosuje swoje strzałki nad
dostęp do swojego pointee.
Jak wszyscy wiemy, to tylko wtedy, gdy istnieje pointee,
jaki rodzaj wróci do orzekania numer 1.
Numer 3, cesja wskaźnik przyjmuje jeden wskaźnik i zmienia go
wskazywać na ten sam pointee jak inny wskaźnik.
Więc po cesji, 2 wskaźniki będą wskazywać na ten sam pointee.
Czasami to się nazywa dzielenie.
>> I to wszystko, co jest do niej bardzo. Bye-bye teraz.
To Binky. To CS50. Do zobaczenia w przyszłym tygodniu. [Oklaski]
>> [CS50.TV]