Wprowadzenie do wskaźników dla programistów

  • Harry James
  • 0
  • 3469
  • 714
Reklama

Niezależnie od tego, czy zdajesz sobie z tego sprawę, czy też nie, ogromna większość używanych programów wykorzystuje wskaźniki w pewien sposób. Może doświadczyłeś NullPointerException w pewnym momencie. Jako programista kod, który piszesz, z dużym prawdopodobieństwem użyje wskaźników, nawet jeśli sam ich nie zaimplementowałeś.

Dzisiaj pokażę ci, jak działają wskaźniki, więc możesz sprawdzić, jak działają tablice i listy Jak działają tablice i listy w Pythonie Jak działają tablice i listy w Pythonie Tablice i listy są jednymi z najbardziej przydatnych struktur danych w programowaniu - - chociaż niewiele osób wykorzystuje je w pełni. dla podkładu programującego. Ten artykuł będzie bardziej oparty na teorii niż zwykle, ale trzymaj się go, wskaźniki są bardzo złożone!

Kod kompilacji

Przed zagłębieniem się w wskaźniki musisz zrozumieć, w jaki sposób budowany i wykonywany jest kod - być może już o tym wiesz. Ta sekcja będzie miała dość ogólne stwierdzenia - rzeczy, które dotyczą większość języków, ale niekoniecznie wszystkich.

Wróćmy do rzeczy. Każdy komputer używa pliku binarnego Co to jest binarny? [Wyjaśniona technologia] Co to jest binarny? [Wyjaśnienie technologii] Biorąc pod uwagę, że binarność jest tak absolutnie fundamentalna dla istnienia komputerów, wydaje się dziwne, że nigdy wcześniej nie zajmowaliśmy się tym tematem - więc dzisiaj pomyślałem, że dam krótki przegląd tego, co binarne…, seria zer i jedynek, które tworzą nowoczesną technologię, jaką znamy. Niezwykle trudno jest napisać cokolwiek w formacie binarnym (pliki byłyby bardzo mylące), ponieważ są to surowe instrukcje, których potrzebujesz jednostka centralna lub procesor do działania Czym jest procesor i do czego służy? Co to jest procesor i co robi? Akronimy komputerowe są mylące. Co to właściwie jest procesor? Czy potrzebuję procesora czterordzeniowego lub dwurdzeniowego? Co powiesz na AMD lub Intel? Jesteśmy tutaj, aby pomóc wyjaśnić różnicę! . Jest to znane jako Kod maszynowy.

Kolejny krok od kodu maszynowego to montaż. Jest to format czytelny dla człowieka. Chociaż programowanie jest wciąż skomplikowane, jest możliwe. Zestaw składa się z szeregu prostych poleceń służących do wykonywania zadań i jest znany jako niski poziom język programowania. Możliwe jest pisanie skomplikowanych programów, ale trudno jest wyrazić abstrakcyjne pojęcia i wymaga dużo uwagi.

Wiele gier wideo i aplikacji o wysokiej wydajności ma pewną logikę zapisaną w asemblerze, ponieważ pewne rzeczywiste zwiększenie prędkości można znaleźć, jeśli wiesz, co robisz. Jednak w zdecydowanej większości projektów programistycznych wcale nie musisz znać żadnego zestawu.

Więc jeśli kod maszynowy jest zbyt trudny do napisania, a montaż jest zbyt trudny do zaprogramowania, czym piszesz kod? Oto gdzie wysoki poziom języki. Języki wysokiego poziomu ułatwiają pisanie programów. Możesz programować w czymś, co przypomina twój język ojczysty, i łatwo jest wyrazić złożone algorytmy. Być może słyszałeś o wielu językach wysokiego poziomu (i na pewno skorzystałeś z napisanego w nich programu):

  • PODSTAWOWY
  • do++
  • Seplenienie

Te języki są teraz bardzo stare i wiele z nich zostało opracowanych na początku lat 50. XX wieku! Niemal każdy współczesny język programowania jest językiem wysokiego poziomu, w tym PHP i Python. Każdego dnia wymyślanych jest więcej języków (choć prawdopodobnie jest ich teraz wystarczająco dużo), ale jak dokładnie działa twój kod, jeśli komputery wymagają kodu maszynowego?

Tutaj pojawia się kompilacja. Kompilator to program, który konwertuje kod wysokiego poziomu do postaci, którą można wykonać. Może to być kolejny język wysokiego poziomu, ale zwykle jest to asembler. Niektóre języki (takie jak Python lub Java) konwertują kod na etap pośredni o nazwie kod bajtowy. Będzie to wymagało ponownej kompilacji w późniejszym terminie, co zwykle odbywa się na żądanie, na przykład podczas uruchamiania programu. Jest to znane jako w samą porę kompilacja i jest dość popularna.

Zarządzanie pamięcią

Teraz, gdy wiesz, jak działają języki programowania, spójrzmy na zarządzanie pamięcią w językach wysokiego poziomu. W tych przykładach użyję pseudo kodu - kodu napisanego nie w żadnym konkretnym języku, ale używanego do pokazywania pojęć, a nie dokładnej składni. Dzisiaj będzie to bardziej przypominać C ++, ponieważ jest to najlepszy język wysokiego poziomu (moim zdaniem).

W tym rozdziale pomoże Ci zrozumieć, jak działa pamięć RAM Szybki i brudny przewodnik po pamięci RAM: Co musisz wiedzieć Szybki i brudny przewodnik po pamięci RAM: Co musisz wiedzieć Pamięć RAM jest kluczowym elementem każdego komputera , ale może to być mylące. Rozbijamy to na łatwe do zrozumienia warunki, które zrozumiesz. .

Większość języków ma zmienne - kontenery, które przechowują niektóre dane. Musisz jawnie zdefiniować typ danych. Niektóre dynamicznie pisane języki, takie jak Python lub PHP, obsługują to za Ciebie, ale nadal muszą to robić.

Powiedz, że masz zmienną:

int myNumber;

Ten kod deklaruje zmienną o nazwie mój numer, i nadaje mu typ danych liczba całkowita. Po skompilowaniu komputer interpretuje to polecenie jako:

“Znajdź trochę pustej pamięci i zarezerwuj miejsce wystarczająco duże, aby zapisać liczbę całkowitą”

Po wykonaniu tego polecenia ten bit pamięci nie może być używany przez inny program. Nie zawiera jeszcze żadnych danych, ale jest zarezerwowany dla zmiennej myNumber.

Teraz przypisz wartość do swojej zmiennej:

myNumber = 10;

Aby wykonać to zadanie, komputer uzyskuje dostęp do zarezerwowanej lokalizacji pamięci i zmienia dowolną przechowywaną tam wartość na tę nową wartość.

Teraz wszystko jest dobrze i dobrze, ale w jaki sposób lokalizacje pamięci stają się niezarezerwowane? Jeśli programy zarezerwują całą pamięć, którą lubią, pamięć RAM zapełni się natychmiast - to by było bardzo wolny system.

Aby uniknąć tego potencjalnego problemu, wiele języków implementuje śmieciarz, służy do niszczenia zmiennych (i dlatego zwalnia zarezerwowane lokalizacje pamięci), które zniknęły poza zakresem.

Być może zastanawiasz się, co to jest zakres i dlaczego jest tak ważny. Zakres określa limity i żywotność zmiennych lub dowolnej pamięci używanej przez program. Zmienna to “poza zakresem” kiedy żaden kod nie może już uzyskać do niego dostępu (wtedy wkracza śmieciarz). Oto przykład:

function maths () int firstNumber = 1;  int secondNumber = 2; print (firstNumber + secondNumber); // nie będzie działać

Ten przykład nie zostanie skompilowany. Zmienna firstNumber jest w obrębie matematyka funkcja, więc to jest jej zakres. Nie można uzyskać do niego dostępu spoza funkcji, w której został zadeklarowany. To ważna koncepcja programowania, i zrozumienie, że jest to kluczowe dla pracy ze wskaźnikami.

Ten sposób obsługi pamięci nazywa się stos. Tak działa ogromna większość programów. Nie musisz rozumieć wskaźników, aby z niego korzystać, i jest dość dobrze skonstruowany. Wadą stosu jest szybkość. Ponieważ komputer musi przypisać pamięć, śledzić zmienne i uruchomić wyrzucanie elementów bezużytecznych, istnieje niewielki narzut. Jest to dobre w przypadku mniejszych programów, ale co z wysokowydajnymi zadaniami lub aplikacjami obciążającymi dane?

Wpisz: wskaźniki.

Wskaźniki

Na powierzchni wskaźniki wydają się proste. Odnoszą się (wskaż na) miejsce w pamięci. To może się nie różnić “regularny” zmienne na stosie, ale wierzcie mi, jest ogromna różnica. Wskaźniki są przechowywane w sterta. Jest to przeciwieństwo stosu - jest mniej zorganizowany, ale jest znacznie szybszy.

Spójrzmy, jak zmienne są przypisywane na stosie:

liczba całkowita Jeden = 1; int numberTwo = numberOne;

To prosta składnia; Zmienna numer dwa zawiera numer jeden. Jego wartość jest kopiowana podczas przypisania z numer jeden zmienna.

Jeśli chcesz zdobyć adres pamięci zmiennej, zamiast jej wartości, musisz użyć znaku handlowego i (&). To się nazywa adres operatora i jest niezbędną częścią zestawu narzędzi wskaźnika.

liczba całkowita Jeden = 1; int numberTwo = & numberOne;

Teraz numer dwa zmienna zwrotnica do miejsca w pamięci, zamiast kopiować numer jeden do własnej, nowej lokalizacji w pamięci. Jeśli miałbyś wypisać tę zmienną, nie byłby to numer jeden (nawet jeśli jest przechowywany w miejscu pamięci). Wypisuje swoją lokalizację pamięci (prawdopodobnie coś w rodzaju 2167, chociaż różni się w zależności od systemu i dostępnej pamięci RAM). Aby uzyskać dostęp do wartości zapisanej we wskaźniku, zamiast miejsca w pamięci, musisz dereferencja wskaźnik. Umożliwia to bezpośredni dostęp do wartości, która w tym przypadku byłaby numerem jeden. Oto jak wyreżyserujesz wskaźnik:

int numberTwo = * numberOne;

The operator dereferencji jest gwiazdką (*).

Może to być trudna do zrozumienia koncepcja, więc przejrzyjmy ją jeszcze raz:

  • The adres operator (&) przechowuje adres pamięci.
  • The operator dereferencji (*) uzyskuje dostęp do wartości.

Składnia zmienia się nieznacznie podczas deklarowania wskaźników:

int * myPointer;

Typ danych int tutaj odnosi się do typu danych wskaźnika zwrotnica do, a nie typ samego wskaźnika.

Teraz, gdy wiesz, jakie są wskaźniki, możesz z nimi zrobić naprawdę fajne sztuczki! Gdy używana jest pamięć, uruchamia się system operacyjny sekwencyjnie. Możesz myśleć o RAM jako o dziurawych gołębiach. Wiele otworów do przechowywania czegoś, tylko jeden może być używany jednocześnie. Różnica polega na tym, że wszystkie gołębie są ponumerowane. Podczas przypisywania pamięci system operacyjny zaczyna się od najniższego numeru i działa. Nigdy nie przeskakuje między liczbami losowymi.

Podczas pracy ze wskaźnikami, jeśli przypisałeś tablicę, możesz łatwo przejść do następnego elementu, po prostu zwiększając wskaźnik.

Oto, gdzie robi się ciekawie. Gdy przekazujesz wartości do funkcji (używając zmiennych przechowywanych na stosie), wartości te są kopiowane do twojej funkcji. Jeśli są to duże zmienne, program przechowuje je teraz dwukrotnie. Po zakończeniu funkcji konieczne może być zwrócenie tych wartości. Funkcje mogą generalnie zwrócić tylko jedną rzecz - co z tego, jeśli chcesz zwrócić dwie, trzy lub cztery rzeczy?

Jeśli przekażesz wskaźnik do funkcji, tylko adres pamięci zostanie skopiowany (co jest małe). To oszczędza procesorowi dużo pracy! Być może twój wskaźnik wskazuje na ogromną tablicę obrazów - nie tylko twoja funkcja może działać na dokładnie tych samych danych przechowywanych w dokładnie tej samej lokalizacji w pamięci, ale kiedy to zrobisz, nie musisz nic zwracać. Schludny!

Musisz jednak być bardzo ostrożny. Wskaźniki mogą nadal wykraczać poza zakres i być zbierane przez moduł wyrzucający elementy bezużyteczne. Wartości przechowywane w pamięci nie są jednak gromadzone. Nazywa się to wyciekiem pamięci. Nie możesz już uzyskać dostępu do danych (ponieważ wskaźniki zostały zniszczone), ale wciąż zużywa pamięć. Jest to częsty powód awarii wielu programów i może się spektakularnie zawieść, jeśli istnieje duża ilość danych. W większości przypadków system operacyjny zabija program, jeśli masz duży wyciek (zużywa więcej pamięci RAM niż system), ale nie jest to pożądane.

Wskaźniki debugowania mogą być koszmarem, szczególnie jeśli pracujesz z dużą ilością danych lub pracujesz w pętli. Ich wady i trudność w zrozumieniu są naprawdę warte kompromisów, które zyskujesz na wydajności. Pamiętaj jednak, że nie zawsze mogą być wymagane.

To tyle na dzisiaj. Mam nadzieję, że nauczyłeś się czegoś użytecznego na temat złożonego tematu. Oczywiście nie omówiliśmy wszystkiego, co trzeba wiedzieć - to bardzo złożony temat. Jeśli chcesz dowiedzieć się więcej, bardzo polecam C ++ w ciągu 24 godzin.

Jeśli było to trochę skomplikowane, zapoznaj się z naszym przewodnikiem po najłatwiejszych językach programowania. 6 najłatwiejszych języków programowania dla początkujących. 6 najłatwiejszych języków programowania dla początkujących. Nauka programowania polega na znalezieniu odpowiedniego języka, tak samo jak na proces edycji. Oto sześć najpopularniejszych języków programowania dla początkujących. .

Czy nauczyłeś się dzisiaj, jak działają wskaźniki? Czy masz jakieś wskazówki i porady, którymi chcesz się podzielić z innymi programistami? Wskocz do komentarzy i podziel się swoimi przemyśleniami poniżej!




Jeszcze bez komentarzy

O nowoczesnej technologii, prostej i niedrogiej.
Twój przewodnik w świecie nowoczesnych technologii. Dowiedz się, jak korzystać z technologii i gadżetów, które nas otaczają każdego dnia i dowiedz się, jak odkrywać ciekawe rzeczy w Internecie.