>> [MUZYKI]
>> DOUG LLOYD: Wskaźniki, tutaj jesteśmy.
Jest to prawdopodobnie będzie najtrudniejszy temat
że mówimy w CS50.
A jeśli czytasz nic o wskaźniki
zanim można być trochę zastraszenia będzie w tym filmie.
To prawda, że ​​wskaźniki nie pozwalają Ci możliwość
być może zepsuć bardzo źle, gdy jesteś
pracy z zmiennych i danych, i powodując awarię program.
Ale są rzeczywiście bardzo przydatne i pozwalają nam naprawdę świetny sposób
do przekazywania danych z powrotem i się między funkcjami,
że jesteśmy w stanie zrobić w inny sposób.
>> A więc to, co naprawdę chcę zrobić tutaj jest pociąg
, aby mieć dobrą dyscyplinę wskaźnika, więc że można skutecznie wykorzystywać wskaźniki
aby programy, które znacznie lepiej.
Jak powiedziałem wskaźniki dają nam inny sposób przekazywania danych między funkcjami.
Teraz, jeśli przypomnieć od wcześniejszy film, kiedy
rozmawialiśmy o Zmienna Zakres wspominałem
że wszystkie dane, które mijamy między Funkcje w C jest przekazywane przez wartość.
I nie może być stosowany, że Termin, o co mi chodzi nie
było to, że mijamy kopii danych.
Kiedy przekazać zmienną do funkcji, nie jesteśmy właściwie przekazując zmienną
do funkcji, prawda?
Jesteśmy przekazując kopię że dane do funkcji.
Funkcja robi to, co będzie i wyznacza pewną wartość,
i być może użyć tej wartości gdy daje go z powrotem.
>> Był jeden wyjątek ta zasada przekazywania przez wartość,
i wrócimy do tego, co, że jest trochę później w tym filmie.
Jeśli używamy wskaźników zamiast używania zmiennych,
lub zamiast użycia zmiennych sami lub kopie zmiennych,
teraz możemy przekazać zmienne wokół pomiędzy funkcjonuje w odmienny sposób.
Oznacza to, że jeśli robimy zmiana w jednej funkcji,
że zmiany będą faktycznie efekt w innej funkcji.
Ponownie, jest to coś, co nie mogliśmy zrobić wcześniej,
i jeśli kiedykolwiek starał się zamienić wartość dwóch zmiennych w funkcji,
zauważyliście ten problem rodzaj skradanie się, prawda?
>> Jeśli chcemy zamienić X i Y, i przekazać je do funkcji o nazwie swap
Wewnątrz funkcji zamienić Zmienne zrobić wartości wymiany.
Człowiek staje się dwa, dwa staje się jeden, ale w rzeczywistości nie
nic zmieniać w oryginale Funkcja w rozmówcy.
Ponieważ nie możemy, jesteśmy tylko pracy z odpisów.
Ze wskaźnikami chociaż, możemy faktycznie przechodzą X i Y do funkcji.
Ta funkcja może zrobić coś z nimi.
I te wartości zmiennych może faktycznie zmienić.
Więc to jest dość zmiana nasza zdolność do pracy z danymi.
>> Zanim zagłębimy wskaźniki, myślę, że warto
biorąc kilka minut wrócić do podstaw tutaj.
I przyjrzeć się, jak Prace pamięci komputera
ponieważ te dwa obiekty będą aby rzeczywiście być bardzo ze sobą powiązane.
Jak zapewne wiecie, w systemie komputerowym
masz dysk twardy lub być może dysk SSD,
jakieś miejsca przechowywania plików.
Zazwyczaj gdzieś w Sąsiedztwo 250 GB
na moze kilka terabajtów teraz.
I to jest, gdy wszystkie swoje Pliki ostatecznie żyć,
nawet wtedy, gdy komputer jest wyłączony wyłączony, można włączyć ją ponownie
a znajdziesz pliki są tam ponownie po ponownym uruchomieniu systemu.
Ale dyski, jak na przykład dysk twardy, twardego dysku lub dysku SSD SSD,
to tylko przestrzeń do przechowywania.
>> Nie możemy nic zrobić w rzeczywistości dane, które jest w dysk twardy,
lub dysk SSD.
Aby właściwie zmianie danych lub przenieść go w inne,
musimy przenieść do RAM, pamięć o dostępie.
Teraz RAM, masz dużo mniej w komputerze.
Może masz gdzieś w Sąsiedztwo 512 megabajtów
jeśli masz starszy komputer, się może dwa, cztery, osiem, 16,
może nawet trochę więcej, gigabajty pamięci RAM.
Więc to jest o wiele mniejszy, ale to w którym wszystkie dane lotnych istnieje.
To miejsce, gdzie możemy coś zmienić.
Ale kiedy zwrócimy komputer wyłączony, wszystkie dane w pamięci RAM są niszczone.
>> Więc dlatego musimy mieć dysk twardy do bardziej stałego miejsca położenia tego,
tak, że exists- że będzie być naprawdę źle, jeśli za każdym razem,
Okazało nasz komputer wyłączyć, co Plik w naszym systemie zostało zatarte.
Więc pracujemy wewnątrz pamięci RAM.
I za każdym razem mówimy o Pamięć, dość dużo, w CS50,
mówimy o pamięci RAM, a nie na dysku twardym.
>> Kiedy więc przenieść rzeczy do pamięci, zajmuje pewną ilość miejsca.
Wszystkie rodzaje danych, które pracujemy z
zajmują różne ilości miejsca w pamięci RAM.
Dlatego za każdym razem tworzyć liczbę całkowitą Zmienna, czterech bajtów pamięci
uchylenie są w pamięci RAM, więc Ciebie Można pracować z tym całkowita.
Możesz zadeklarować liczbę całkowitą, zmienić go, przypisać go
do wartości 10 zwiększany o jeden, tak dalej, i tak dalej.
Wszystko, co musi się zdarzyć w RAM, a otrzymasz cztery bajty
pracować na każde Liczba całkowita tworzenia.
>> Każda postać ci tworzenie dostaje jeden bajt.
To jest po prostu jak dużo miejsca jest potrzebny do zapisywania znaku.
Każdy pływak, prawdziwy Numer, dostaje cztery bajty
chyba, że ​​jest to podwójna precyzja zmiennoprzecinkowa
Numer, który pozwala na mają bardziej precyzyjne lub więcej cyfr
po przecinku bez utraty precyzji,
które zajmują osiem bajtów pamięci.
Długie tęskni, bardzo duże liczby całkowite, również trwać osiem bajtów pamięci.
Ile bajtów pamięci czy ciągi trwać?
Cóż postawmy szpilkę w tym pytaniu na teraz, ale wrócimy do tego.
>> Więc z powrotem do tej idei pamięci jako duża tablica komórek bajtowych wielkości.
To naprawdę wszystko jest to, że to po prostu ogromny wachlarz komórek,
tak jak każdy inny tablicy, która znasz i zobaczyć,
chyba każdy element jest szeroki jeden bajt.
I podobnie jak tablica, każdy element ma adres.
Każdy element tablicy ma indeks, i
Można korzystać z tego indeksu, aby zrobić tzw o dostępie swobodnym na tablicy.
Nie musimy zacząć od początek tablicy
iterację każdego jego pojedynczy element,
aby znaleźć to, czego szukamy.
Możemy tylko powiedzieć, chcę dostać się do 15th Element lub element 100th.
A może po prostu przekazać w tej liczby i uzyskać wartość, którego szukasz.
>> Podobnie każda lokalizacja w pamięci ma adres.
Więc twoja pamięć może wyglądać tak.
Oto bardzo mały fragment Pamięć ta 20 bajtów pamięci.
Pierwsze 20 bajtów, ponieważ mój odnosi się tam na dnie
0, 1, 2, 3, a więc na całej drodze do 19.
A kiedy deklarować zmienne i kiedy zaczynam pracować z nimi,
System będzie ustawiona bok trochę miejsca dla mnie
w tej pamięci, do współpracy z moich zmiennych.
Więc mogę powiedzieć, char c równa kapitału H. I co się stanie?
Cóż system będzie uchylenie dla mnie jeden bajt.
W tym przypadku wybraliśmy numeru bajtu cztery, bajt pod adresem czterech,
i to będzie przechowywać litera H tam dla mnie.
Gdybym wtedy powiedzieć, int prędkości Limit wynosi 65, to
będzie uchylenie czterech bajtów pamięci dla mnie.
I to będzie traktować tych, cztery bajty jako pojedyncza jednostka
bo czym pracujemy z oznacza liczbę całkowitą o.
I to będzie przechowywać 65 tam.
>> Teraz już jestem trochę informacją, trochę kłamstwa,
Dobrze, bo wiemy, że komputery pracują w systemie binarnym.
Nie rozumieją koniecznie, co stolica H jest
lub co 65 jest, że tylko zrozumieć binarne zer i jedynek.
I tak rzeczywiście to, co jesteśmy przechowywania tam
nie jest litera H i numer 65, ale raczej reprezentacje binarne
tym, które wyglądają Trochę coś takiego.
A w szczególności w Kontekst zmiennej całkowitej,
to nie będzie po prostu wyrzuć to do, to nie będzie traktować go jako jeden cztery
bajt kawałek koniecznie, to faktycznie dzieje
traktować go jako cztery kawałki jeden bajt, co może wyglądać tak.
I nawet nie jest całkowicie prawdziwe albo,
z powodu czegoś, co nazywa kolejność bajtów, których nie jesteśmy
zamiar dostać się do teraz, ale jeśli jesteś ciekaw,
można przeczytać na trochę i duże kolejność bajtów.
Ale ze względu na ten argument, w trosce o tym filmie,
niech po prostu założyć, że jest w Fakt, jak numer 65 będzie
być reprezentowane Pamięć na każdym systemie,
choć nie jest to do końca prawda.
>> Ale spójrzmy prawdzie w rzeczywistości po prostu pozbyć się wszystkich binarnych w całości,
i tylko myśleć o jak H i 65, jest to o wiele łatwiejsze
myśleć o tym, jak że istota ludzka.
W porządku, więc wydaje się też być może trochę przypadkowe, że I've- mój system
nie dają mi bajty 5, 6, 7, i 8 przechowywać liczbę całkowitą.
Jest powód, dla tego też, co nie dostaniemy się już teraz, ale wystarczy
to znaczy, że to, co komputer robi tutaj
to chyba dobry ruch z jego strony.
Aby nie dać mi pamięć, która jest koniecznie z powrotem do tyłu.
Mimo, że to będzie zrobić to teraz jeśli chcę dostać inny ciąg,
nazywa nazwisko, a ja chcę umieścić Lloyd tam.
Będę musiał zmieścić jeden charakter, każda litera to
będzie wymagać jednego charakter, jeden bajt pamięci.
Więc jeśli mogę umieścić Lloyd w moim tablicy tak jestem całkiem dobrze iść, prawda?
Czego brakuje?
>> Pamiętaj, że każdy ciąg pracujemy zw C kończy backslashem zerowej,
i nie możemy pominąć, że tutaj, albo.
Musimy odłożyć na bok jeden bajt pamięci do przechowywania, że ​​dlatego
wiedzieć, kiedy nasz ciąg zakończył.
Więc jeszcze raz ten układ na sposób rzeczy
pojawiają się w potędze pamięci być trochę przypadkowa,
ale w rzeczywistości jest to, jak większość systemów są przeznaczone.
Aby je układać na wielokrotność czterech względów ponownie
że nie trzeba dostać się do teraz.
Ale to, więc wystarczy powiedzieć, że po tych trzech linii kodu,
Pamięć to właśnie może wyglądać.
Jeśli muszę komórek pamięci 4, 8 i 12 do przechowywania moich danych,
to co moja pamięć może wyglądać.
>> I tak być szczególnie pedantyczny tutaj, kiedy
mówimy o pamięci Adresy zwykle
zrobić za pomocą zapisów w systemie szesnastkowym.
Więc dlaczego nie możemy przekształcić wszystkie te z przecinku do zapisie szesnastkowym
tylko dlatego, że na ogół w jaki odnosimy się do pamięci.
Więc zamiast być od 0 do 19, co mamy jest zero
x od zera do zera x1 trzy.
Są to 20 bajtów pamięci, że zostały lub patrzymy na tym zdjęciu
dokładnie tutaj.
>> Więc wszystko, co mówi, niech krok od pamięci na sekundę
i powrót do wskaźników.
Oto najważniejsze rzeczą do zapamiętania
jak rozpocząć pracę ze wskaźnikami.
Wskaźnik ma nic więcej niż adresem.
Powiem to jeszcze raz, ponieważ to takie ważne,
wskaźnik ma nic więcej niż adresem.
Wskaźniki są adresy do lokalizacji Zmienne w pamięci, gdzie mieszkają.
Wiedząc, że staje się miejmy nadzieję, trochę łatwiej z nimi pracować.
Inną rzeczą lubię zrobić, to mieć sortowania
schematów wizualnie reprezentujący co dzieje się z różnych linii kodu.
A my to kilka zrobić razy w wskaźników,
a kiedy mówimy o dynamicznym alokacji pamięci, jak również.
Bo myślę, że te schematy może być szczególnie pomocne.
>> Więc jeśli powiem, na przykład, int k w moim kodu, co się dzieje?
Cóż, co się w zasadzie dzieje się Dostaję pamięć przeznaczoną dla mnie,
ale ja nawet nie lubię myśleć o tym w ten sposób, że
lubię myśleć o tym jak pudełko.
Mam pole i to kolorowe zielona bo
może umieścić całkowite w zielone pola.
Jeśli był to znak, że może mieć niebieskie pole.
Ale ja zawsze powtarzam, jeśli tworzę pole, które może pomieścić liczb całkowitych
że skrzynka jest w kolorze zielonym.
I biorę markerem i piszę k na stronie.
Więc mam pole o nazwie K, w którym można umieścić liczby całkowite.
Więc kiedy mówię, int k, to co dzieje się w mojej głowie.
Jeśli powiem, k równa się pięć, co ja robię?
Cóż, Kładę pięć w polu, tuż.
To jest bardzo proste, jeśli Mówię int k, utworzyć pole o nazwie k.
Jeśli powiem, k równa się 5, umieścić pięć w polu.
Mam nadzieję, że to nie jest zbyt wielkim skokiem.
Oto, gdzie rzeczy pójść mało interesujące choć.
Jeśli powiem, int * pk, a nawet jeśli nie mam wiem co to niekoniecznie oznacza,
to wyraźnie coś do czynienia z liczbą całkowitą.
Więc idę do koloru to pole Zielona-owski,
Wiem, że to ma coś do czynienia z liczbą całkowitą,
ale to nie jest samo w sobie całkowitą, bo to int gwiazdą.
Jest coś, co nieco różni się o tym.
Tak zaangażowany liczbą całkowitą użytkownika, ale poza tym to
niezbyt różni się od co nam chodzi.
Jest to pole, jego dostał etykietę, to sobie pk etykiety,
i jest w stanie utrzymać int gwiazdy, co to są.
Mają coś do zrobienia z liczb całkowitych, wyraźnie.
Oto ostatnia linia chociaż.
Jeśli powiem, pk = & k, zaraz, co się stało, prawda?
Więc to liczba losowa, pozornie przypadkowe liczba, zostaje wrzucony w pudełku.
Wszystko to jest pk dostaje adres k.
Więc mam trzymać gdzie k mieszka w pamięci, adres, adres jego bajtów.
Wszystko robię to mówię że wartość jest co zamierzam
umieścić wewnątrz mojej skrzynki zwanej pk.
A ponieważ te rzeczy są wskaźniki, a ponieważ patrząc
na sznurku, jak zero, X osiem zera c siedem cztery osiem
dwa zera jest chyba nie bardzo znaczące.
Kiedy ogół wizualizować wskaźniki, faktycznie zrobić jako wskaźniki.
Pk daje nam informacje musimy znaleźć k w pamięci.
Więc w zasadzie pk ma strzałkę w nim.
A jeśli idziemy długość tej strzałki, wyobraź sobie,
to jest coś, co można chodzić, jeśli będziemy spacer wzdłuż strzałki,
na samym czubku tej strzałki, mamy będzie znaleźć miejsce w pamięci
gdzie k żyje.
I to jest bardzo ważne bo kiedy wiemy, gdzie k mieszka,
możemy przystąpić do pracy z danymi Wnętrze tego miejsca pamięci.
Choć jesteśmy coraz malusieńki bit przed siebie teraz.
>> Więc co to jest wskaźnik?
Wskaźnik jest element danych, którego wartość jest adres pamięci.
To było to, że zera x ośmiu zera stuff dzieje, że był to adres pamięci.
To było miejsce w pamięci.
I typ wskaźnika opisuje rodzaj
danych znajdziesz w że adres pamięci.
Więc jest częścią prawo int gwiazdą.
Jeśli śledzę tę strzałkę, to będzie prowadzić mnie do lokalizacji.
I to miejsce, co ja znajdzie tam w moim przykładzie,
jest w kolorze zielonym polu.
Jest liczbą całkowitą, to co ja znajdzie, jeśli pójdę na ten adres.
Typ danych wskaźnik opisuje co
znajdziesz pod tym adresem pamięci.
Więc tutaj jest naprawdę fajne rzeczy jednak.
Wskaźniki pozwalają nam przejść zmienne pomiędzy funkcjami.
I rzeczywiście przekazać zmienne i nie przekazać ich kopie.
Bo jeśli wiemy dokładnie, gdzie w pamięci, aby znaleźć zmienną,
nie musimy zrobić kopię to możemy po prostu udać się do tego miejsca
i pracy z tej zmiennej.
Tak w istocie rodzaj wskaźników od dokonania środowisko komputera
o wiele bardziej jak w rzeczywistym świecie, w prawo.
>> Tak tu jest analogia.
Powiedzmy, że mam notebooka w prawo, i to jest pełne notatek.
I chciałbym, aby go zaktualizować.
Jesteś funkcją aktualizacje notatki, prawda.
W drodze byliśmy działa tak daleko, co
dzieje się weźmiesz mój zeszyt, pójdziesz do sklepu, kopiowania,
będziesz się kserokopię każda strona notebooka.
Musisz opuścić mój notatnik na moim biurku, kiedy skończysz,
pójdziesz i przejechać się rzeczy w moim notebook, które są nieaktualne lub błędne,
a następnie będziesz przechodzić z powrotem do mi stos stron Xerox
która jest repliką moim notebooku z zmiany, które zostały wprowadzone do niego.
I w tym momencie, to do mnie, funkcja powołaniem jako rozmówcy,
zdecydować, aby zabrać swoje notatki i zintegrować je z powrotem na moim notebooku.
Więc jest dużo schodów chodzi tu, w prawo.
Jak nie będzie lepiej gdybym tylko powiedzieć, hej, można
zaktualizować notebook dla ja, wręczyć ci mój zeszyt,
i zabrać rzeczy i dosłownie przekroczyć je
i aktualizować swoje notatki w zeszycie.
A potem dał mi mój notatnik.
To coś, co wskaźniki pozwalają nam robić,
robią to środowisko o wiele raczej jak działamy w rzeczywistości.
>> Dobrze więc, że to, co wskaźnik jest, porozmawiajmy
o tym, jak działają wskaźniki w C, a jak możemy rozpocząć pracę z nimi.
Więc jest to bardzo prosty wskaźnik w C zwany pustego wskaźnika.
Null wskaźnik pokazywał nic.
Wydaje się to zapewne jak to Właściwie nie bardzo przydatna rzecz,
ale jak zobaczymy Nieco później, fakt,
że ten wskaźnik NULL istnieje rzeczywiście bardzo może się przydać.
I podczas tworzenia wskaźnika, a nie ustawić jej wartość immediately-
Przykład ustawiania jego wartość natychmiast
będzie kilka slajdów z powrotem gdzie powiedziałem pk równa & K,
pk dostaje adres k, tak jak Zobaczymy, co to znaczy,
zobaczymy jak kod, który shortly- jeśli nie ustawić jej wartość na coś
natychmiast sens, powinieneś zawsze
ustawić kursor do punktu na null.
Należy ustawić go wskazują na nic.
>> To jest zupełnie inny niż pozostawiając tylko wartość, jak to jest
a następnie uznającej wskaźnik i tylko przy założeniu,
jest pusty, bo to rzadko prawdziwe.
Więc zawsze należy ustawić wartość wskaźnika
null, jeśli nie ustawić jej wartość do czegoś sensownego natychmiast.
Można sprawdzić, czy wartość wskaźnika w jest null za pomocą operatora równości
(==), Tak jak porównać dowolną liczbę całkowitą wartości lub wartości postaciach używając (==)
równie dobrze.
To szczególny rodzaj stałej wartości, które można używać do testowania.
Tak, że był to bardzo proste wskaźnik, null pointer.
Innym sposobem tworzenia wskaźnik jest wydobycie
adres zmiennej już stworzone,
i można to zrobić za pomocą & Ekstrakcja adres operatora.
Które widzieliśmy już wcześniej w pierwszym przykładzie schematu pokazałem.
Tak więc, jeśli x jest zmienna mamy już utworzony typu INTEGER,
następnie & x jest wskaźnikiem do liczby całkowitej.
& x jest-pamiętam, i zamierza wyodrębnić adres rzeczy po prawej stronie.
A ponieważ wskaźnik jest tylko adres, niż & x jest wskaźnikiem do liczby całkowitej
których wartość jest, gdy w pamięci x życiu.
Jest to adres X..
Więc i x jest adres x.
Weźmy ten jeden krok dalej i połączyć się z czymś
Wspomniałem w poprzednim filmie.
Jeśli arr jest tablicą deblu, a następnie & arr nawias kwadratowy i jest wskaźnikiem
na podwójne.
OK.
arr nawias kwadratowy i, jeśli to arr jest tablicą deblu
następnie arr nawias kwadratowy i jest element i-tego tablicy
i & arr nawias kwadratowy i jest gdzie w element i-ty z arr istnieje pamięci.
>> Więc co jest implikacją tutaj?
Tablice nazwa, implikacja w całej tej sprawie,
jest to, że nazwa tablicy jest właściwie sam wskaźnik.
Pracowaliście ze wskaźnikami wszystkim wzdłuż
za każdym razem, że użyłeś tablicę.
Pamiętaj, na przykładzie na zmiennej zakresie,
pod koniec filmu przedstawiam przykład, w którym mamy funkcję
zwany zestaw int i Funkcja o nazwie zestaw tablica.
A twój wyzwaniem, aby określić czy też nie, lub co
Wartości, które drukowane na Koniec funkcji
pod koniec głównego programu.
>> Jeśli pamiętacie z tego przykładu lub jeśli nie oglądałem film,
wiesz, że jeśli wam-wezwanie do Zestaw int skutecznie nic nie robi.
Ale rozmowa ustawić tablicę robi.
I coś w rodzaju tabu, dlaczego tak było w tym czasie.
Powiedziałem tylko, jak to jest tablicą, to Specjalny, wiesz, że jest powód.
Powodem jest to, że tablica na Nazwa jest naprawdę tylko wskaźnik,
i jest to specjalne Składnia kwadratowy nawias, że
dokonać rzeczy o wiele ładniejszy pracować.
A oni ideę wyżeł dużo mniej zastraszające,
i dlatego są one rodzaju zaprezentowanych w ten sposób.
Ale tak naprawdę to tylko tablice Wskaźniki.
I dlatego, kiedy wprowadzeniu zmian do tablicy,
kiedy minęliśmy tablicę jako parametr do funkcji lub argument
do funkcji, zawartość tablicy rzeczywiście zmieniona w wywoływany
a rozmówcą.
Które dla każdego innego rodzaju Zmienna widzieliśmy nie był przypadek.
Tak, że po prostu coś do utrzymania w przeszkadza podczas pracy ze wskaźnikami,
jest to, że nazwą Tablica rzeczywiście wskaźnik
pierwszego elementu tablicy.
>> OK, więc teraz mamy wszystko fakty, będziemy mówili, w prawo.
Dlaczego dbamy o gdzie coś żyje.
Cóż, jak powiedziałem, to jest całkiem warto wiedzieć, gdzie coś mieszka
więc można tam pojechać i go zmienić.
Praca z nim i rzeczywiście mieć coś, co Cię
chcesz zrobić z tym zmiennym skutkiem podjęcia, i nie ma wpływu na jakimś kopię.
To się nazywa wyłuskania.
Idziemy do odniesienia i my tam zmienić wartość.
Więc jeśli mamy wskaźnik i to się nazywa pc, a to wskazuje na charakter,
wtedy możemy powiedzieć, * * pc i pc jest nazwa, co znajdziemy jeśli pójdziemy
na pc adresu.
Co my tam znaleźć to charakter i * pc jest, jak odnosimy się do danych na które
Lokalizacja.
Więc można powiedzieć coś takiego * pc = D lub coś w tym stylu,
a to oznacza, że ​​bez względu na był pod adresem pamięci komputera,
bez względu na charakter był wcześniej tam, jest D, jeśli powiemy * pc = D.
>> Więc zaczynamy ponownie niektóre dziwne C rzeczy, prawda.
Tak więc widzieliśmy * wcześniej jako w jakiś sposób częścią tego typu danych,
i obecnie jest używany w nieco inny kontekst
Aby uzyskać dostęp do danych na miejscu.
Wiem, że to trochę mylące i to jest rzeczywiście częścią tej całości
jak, dlaczego wskaźniki mają tę mitologię wokół nich jako tak skomplikowane,
to rodzaj problemu składni, szczerze.
A * jest używany zarówno w kontekstach zarówno jako część nazwy typu,
i zobaczymy trochę później coś jeszcze.
A teraz jest operator wyłuskiwania.
Więc to idzie do odniesienia, że dostęp do danych
w miejscu kursora, oraz pozwala manipulować do woli.
>> Teraz to jest bardzo podobne do zwiedzanie bliźniego, prawo.
Jeśli wiesz, co sąsiad mieszka, jesteś
Nie wychodzić z sąsiadem.
Wiesz, że zdarzy się wiedzieć, gdzie mieszkają,
ale to nie znaczy, że Cnota mając tę ​​wiedzę
jesteś interakcji z nimi.
Jeśli chcesz interakcji z nimi, musisz udać się do ich domu,
musisz udać się do miejsca, gdzie żyją.
A kiedy to zrobisz, wtedy można oddziaływać
z nimi tak jak wy chcą.
I podobnie ze zmiennymi, trzeba iść na ich adres
jeśli chcesz ich interakcji, nie można po prostu znać adres.
I tak, jak przejść do adresu jest używać *, operator wyłuskiwania.
Co sądzisz dzieje jeśli spróbujemy i dereference
wskaźnik, którego wartość jest null?
Przypomnijmy, że null Wskaźnik wskazuje na nic.
Więc jeśli spróbujesz i dereference nic lub udać się do niczego adresu
co sądzisz dzieje?
Cóż, jeśli zgadłeś segmentacja winy, to masz rację.
Jeśli spróbujesz i dereference wskaźnikiem NULL,
cierpisz segmentacji przyczepić. Ale poczekaj,
ja nie powiedziałem ci, że jeśli nie będziemy
ustawić wartość swoich wskaźnik do czegoś sensownego,
należy ustawić na wartość null?
Zrobiłem i faktycznie segmentacja Błędem jest rodzajem dobrego zachowania.
>> Czy kiedykolwiek zadeklarowaniu zmiennej i nie od razu przypisać jej wartość?
Więc po prostu powiedzieć, int x; ty nie faktycznie przypisać go do niczego
a następnie później w kodzie, wydrukować wartość x,
nadal nie mając przypisane go do niczego.
Najczęściej dostaniesz zero, ale czasami
Może trochę liczb losowych, a nie masz pojęcia, skąd się to wzięło.
Podobnie można rzeczy stało ze wskaźnikami.
Kiedy zadeklarować wskaźnik int * pk np
i nie przypisać go do wartości, masz cztery bajty w pamięci.
Niezależnie cztery bajty Pamięć system może
okaże się, że jakieś sensowne wartości.
I nie mogło być coś, co już istnieje, że
nie są już potrzebne innym Funkcja, więc po prostu trzeba
niezależnie od danych nie było.
>> Co zrobić, jeśli próbował zrobić dereference Adres, że niektóre don't- było
już bajtów i informacji w nie, to jest teraz w Twoim wskaźnikiem.
Jeśli spróbujesz i wyłuskanie tego wskaźnika, może być brudząc z jakiegoś pamięci
że nie zamierza zadzierać z tym wszystkim.
A w rzeczywistości można zrobić coś naprawdę katastrofalne,
jak złamać inny program, lub złamać kolejną funkcję,
lub zrobić coś szkodliwego, że nie miał zamiaru robić w ogóle.
I tak właśnie dlatego, że to rzeczywiście dobry pomysł
aby ustawić wskazówki na null, jeśli Ciebie nie ustawić je na coś sensownego.
To chyba lepiej u Koniec dnia dla programu
do katastrofy to na to, aby zrobić Coś, śruby górę
inny program lub innej funkcji.
To zachowanie jest chyba nawet mniej idealna niż tylko upaść.
I tak właśnie dlatego, że to rzeczywiście dobry zwyczaj
aby dostać się na ustawienie wskazówek null, jeśli nie je ustawić
do znaczącej wartości natychmiast, to wartość, która wiesz,
i że można bezpiecznie dereference.
>> Więc niech się teraz do tyłu i spojrzeć w całkowitej składni sytuacji.
Jeśli powiem, int * p ;, co ja po prostu zrobić?
Co zrobiłem jest to.
Wiem, wartość p jest adres ponieważ wszystkie wskaźniki są po prostu
adresy.
Mogę dereference p za pomocą operatora *.
W związku z tym tutaj, na samym top przypomnieć * jest częścią typu.
Int * jest typem danych.
Ale mogę dereference s za pomocą operatora *,
a jeśli mam zrobić, jeśli pójdę na ten adres, co znajdę pod tym adresem?
Znajdę liczbę całkowitą.
Tak int * p jest w zasadzie mówiąc, p jest adres.
Mogę dereference p, a jeśli Ja, znajdę liczbę całkowitą
w tym miejscu pamięci.
>> OK, więc powiedziałem, nie było innego irytujące z gwiazdami
I tu, że irytujące z gwiazdami jest.
Czy kiedykolwiek próbowałeś do ogłoszenia wiele zmiennych tego samego typu
na tej samej linii kodu?
Więc na chwilę, udawać, że linia, kod I rzeczywiście jest w kolorze zielonym
tam nie ma i po prostu mówi, int x, y, z ;.
Co, że zrobi to rzeczywiście stworzyć trzy zmienne całkowite dla Ciebie,
jeden o nazwie x, jeden o nazwie y, jeden zwany z.
Jest to sposób, aby to zrobić bez konieczności podzielić na trzy linie.
>> Oto, gdzie gwiazdek uzyskać ponownie denerwujące choć,
ponieważ * jest rzeczywiście częścią zarówno nazwą typu i częściowo
nazwy zmiennych.
I tak, jeśli powiem, int * px, py, pz, co ja rzeczywiście się jest wskaźnikiem do liczby całkowitej
nazywa px i dwie liczby całkowite, py i pz.
A to nie to, co prawdopodobnie chcemy, to nie jest dobre.
>> Więc jeśli chcę utworzyć wiele wskaźników na tej samej linii z tego samego typu,
i gwiazdy, co faktycznie potrzebne zrobić, to powiedzieć, int * pa, * pb, * szt.
Teraz po prostu powiedział, że a teraz ci tego mówić,
prawdopodobnie nigdy nie będzie tego robił.
I to chyba dobrze, szczerze mówiąc, ponieważ może nieumyślnie
pominąć gwiazda, coś takiego.
To chyba najlepiej może zadeklarować Wskaźniki na poszczególnych liniach,
ale to tylko jeszcze jeden z tych irytujących składni
rzeczy, które sprawiają, że z gwiazd Wskaźniki tak trudno pracować.
Bo to jest właśnie to składniowym bałagan trzeba pracować przez.
Z praktyki robi naprawdę się drugą naturą.
I nadal popełniają błędy z nim jeszcze po zaprogramowaniu przez 10 lat,
więc nie denerwuj się, jeśli coś się dzieje do ciebie, to dość powszechne szczerze.
To naprawdę rodzaj to błąd składni.
>> OK, więc rodzaj obiecał że będziemy ponownie
pojęcie, jak duże jest łańcuchem.
Cóż, gdybym powiedział, że Łańcuch, mamy naprawdę rodzaj
leżał na ciebie cały czas.
Nie ma typ danych o nazwie łańcuch, aw rzeczywistości
Wspomniałem o tym w jednym z naszych Pierwsze filmy w typów danych,
że łańcuch był to typ danych, które został stworzony dla Ciebie w CS50.h.
Musisz #include CS50.h w celu wykorzystania go.
>> Cóż łańcuch jest tak naprawdę aliasem na coś
nazywany char *, a wskaźnik do znaku.
Cóż wskaźniki, przypomnijmy, są tylko adresy.
Więc co jest rozmiar w bajtach ciąg?
No to cztery lub osiem.
A powód mówię cztery lub osiem, bo to jest naprawdę
zależy od systemu, Jeśli używasz CS50 ide, char * jest wielkość char
* Jest osiem, jest to system 64-bitowy.
Każdy adres w pamięci jest długa 64 bity.
Jeśli używasz CS50 urządzenia lub przy użyciu dowolnego komputera 32-bitowego,
i słyszałem, że termin 32-bit Maszyna, co to maszyna 32-bit?
No to po prostu oznacza, że ​​każdy adres w pamięci jest długa 32 bity.
I tak 32 bity to cztery bajty.
Więc char * jest cztery lub osiem bajtów w zależności od systemu.
I rzeczywiście wszelkie typy danych, i wskaźnik do wszelkich danych
wpisać, ponieważ wszystkie wskaźniki są po prostu adresy, cztery lub osiem bajtów.
Więc ponownie tego diagram i niech to stwierdzić
Ten film z odrobiną wysiłku tutaj.
Więc oto schemat skończyliśmy z na samym początku filmu.
Więc co się dzieje teraz, jeśli powiem, * PK = 35?
Więc co to znaczy, gdy mówię, * pk = 35?
Weź drugi.
* pk.
W kontekście tutaj, * jest operator wyłuskiwania.
Więc kiedy dereference operator jest używany
idziemy na adres wskazany przez pk, i zmienić to, co możemy znaleźć.
Tak * pk = 35 skutecznie robi to na zdjęciu.
Więc jest to w zasadzie składniowo identyczny z powiedział, k = 35.
>> Jeszcze jeden.
Jeśli powiem, int m, tworzę nową zmienną o nazwie m.
Nowy pojemnik, to zielone pole, ponieważ to będzie trzymać liczbę całkowitą,
i jest oznaczony m.
Jeśli powiem, m = 4, to umieścić całkowita w tym polu.
Jeśli powiedzmy pk = & m, w jaki sposób ta zmiana schemat?
Pk = & m, zrobić sobie przypomnieć, co się & Operator robi i nazywa?
Pamiętaj, że & jakąś nazwę zmiennej jest adres nazwy zmiennej.
Więc to, co mówisz, jest pk dostaje adres m.
I tak skutecznie, co się stanie, Schemat jest to, że pk nie wskazuje już
k, ale punkty do m.
>> Ponownie wskaźniki są bardzo trudne do pracy z
i biorą dużo praktyka, ale dlatego,
ich zdolności, aby umożliwić do przekazywania danych pomiędzy funkcjami
i rzeczywiście mają te Zmiany zaczną obowiązywać,
się wokół twojej głowie jest naprawdę ważne.
To chyba jest najbardziej skomplikowane temat omówimy CS50,
ale wartość, że cię uzyskać z wykorzystaniem wskaźników
znacznie przewyższają powikłań które pochodzą z ich nauki.
Więc życzę ci najlepiej Powodzenia nauki o wskazówki.
Jestem Doug Lloyd, to CS50.