Twoje pytanie jest interesujące na kilka sposobów, ponieważ wymaga starannego rozróżnienia dla kilku zagadnień. Ale twoja wizja wydaje mi się zasadniczo poprawna. Nie przeczytałem twojego odniesienia przed napisaniem większości tej odpowiedzi, aby uniknąć popychania mojej odpowiedzi.
Po pierwsze, twoje oświadczenie Variables are symbolic names for memory
addresses
jest prawie poprawne, ale myli koncepcję i jej zwykłą implementację. Zmienna jest tak naprawdę tylko kontenerem, który może zawierać wartość, którą można zmienić. Zazwyczaj ten kontener jest implementowany na komputerze jako blok pamięci, charakteryzowany przez adres i rozmiar, ponieważ zmienne mogą zawierać obiekt, który wymaga reprezentacji z większą lub mniejszą ilością informacji.
Ale rozważę głównie bardziej abstrakcyjny punkt widzenia semantyki języków, niezależnie od technik implementacyjnych.
Zatem zmienne są tylko kontenerami z abstrakcyjnego punktu widzenia. Taki pojemnik nie musi mieć nazwy. Jednak języki często mają zmienne, które są nazywane przez powiązanie z nim identyfikatora, więc użycie zmiennej może być wyrażone przez identyfikator. Zmienna może faktycznie mieć kilka identyfikatorów za pośrednictwem różnych mechanizmów aliasingu. Zmienna może być również częścią większej zmiennej: przykładem jest komórka zmiennej tablicowej, którą można nazwać określając zmienną tablicową i indeks komórki, ale równie dobrze można ją powiązać z identyfikatorami poprzez aliasing.
Celowo używam słowa „ kontener”, który jest nieco neutralny, aby uniknąć przywoływania innych słów, które mogą być technicznie ładowane semantycznie. W rzeczywistości jest on zbliżony do koncepcji odniesienia opisanej w wilipedia , która często jest mylona z adresem pamięci. Sam wskaźnik słowa jest często rozumiany jako adres pamięci, ale nie sądzę, aby miał on znaczenie przy rozważaniu większości języków wysokiego poziomu i prawdopodobnie nieodpowiedni w dokumencie do dyskusji, do którego się odwołujesz (chociaż adresów można używać), ponieważ jest niewłaściwy odnoszące się do konkretnego wdrożenia. Jest jednak odpowiedni dla języka takiego jak C, który ma być znacznie bliższy koncepcjom implementacji i architekturze maszyny.
W rzeczywistości, jeśli spojrzysz na zmienne lub wartości na poziomie implementacji, może istnieć kilka złożonych systemów pośrednich, „wskaźników na poziomie maszyny”, ale które są (i powinny być) niewidoczne dla użytkownika, tak że abstrakcyjny punkt widzenia Rozwijam się, może być ważny. W przypadku większości języków programowania użytkownik nie powinien się martwić, a nawet wiedzieć o implementacji, ponieważ implementacja może się znacznie różnić w zależności od języka. Może to nie być prawdą w przypadku niektórych języków, takich jak C, które są celowo zbliżone do architektury maszyny, jako zaawansowany zamiennik języków asemblerowych, które są prawie bezpośrednio związane z jawnym kodowaniem binarnym, ale zdecydowanie za niski poziom, aby można było z nich wygodnie korzystać w większości sytuacje.
To, co użytkownik języka powinien wiedzieć, a czasem powinien być jeszcze mniejszy, to jakie są wartości i powiązane operacje, gdzie można je zawrzeć, jak można je powiązać z nazwami, jak działa system nazewnictwa, jak nowe rodzaje wartości do zdefiniowania itp.
Kolejną ważną koncepcją są identyfikatory i nazewnictwo. Nazwanie bytu (wartości) można wykonać przez powiązanie identyfikatora z wartością (zwykle w deklaracji). Ale wartość można również uzyskać przez zastosowanie operacji do innych nazwanych wartości. Nazwy można ponownie wykorzystać, a istnieją reguły (reguły określania zakresu) w celu ustalenia, co jest powiązane z danym identyfikatorem, zgodnie z kontekstem użycia. Istnieją również specjalne nazwy, zwane literałami, w celu nazwania wartości niektórych domen, takich jak liczby całkowite (np612) lub boolean (np. true ).
Powiązanie niezmienionej wartości z identyfikatorem jest zwykle nazywane stałą. Litterals są stałymi w tym sensie.
„Pojemniki wartości” można również traktować jako wartości, a ich powiązanie z identyfikatorem jest zmienną w zwykłym „naiwnym” znaczeniu, którego używasz. Można więc powiedzieć, że zmienna jest „stałą kontenerową”.
Teraz możesz się zastanawiać, jaka jest różnica między powiązaniem identyfikatora z wartością (stała deklaracja) lub przypisaniem wartości do zmiennej, tj. Zapisaniem wartości w kontenerze zdefiniowanym jako stała kontenera. Zasadniczo deklaracja może być postrzegana jako operacja definiująca notację, która wiąże identyfikator, który jest bytem syntaktycznym, z pewną wartością, która jest bytem semantycznym. Przypisanie jest operacją czysto semantyczną, która modyfikuje stan, tj. Modyfikuje wartość kontenera. W pewnym sensie deklaracja jest meta pojęciem bez efektu semantycznego, innym niż dostarczenie mechanizmu nazewnictwa (tj. Składniowego) dla jednostek semantyki.
W rzeczywistości przypisania są operacjami semantycznymi, które pojawiają się dynamicznie podczas wykonywania programu, podczas gdy deklaracje mają bardziej składniowy charakter i zwykle należy je interpretować w tekście programu, niezależnie od wykonania. Właśnie dlatego ustalanie zakresu (tj. Określanie zakresu tekstu) jest zwykle naturalnym sposobem zrozumienia znaczenia identyfikatorów.
Po tym wszystkim mogę powiedzieć, że wartość wskaźnika to po prostu inna nazwa kontenera, a zmienna wskaźnika to zmienna kontenera, tzn. Kontener (stały), który może zawierać inny kontener (z możliwymi ograniczeniami narzuconej gry narzuconymi przez niektórych system typów).
Jeśli chodzi o kod, stwierdzasz [pointers] might indicate the entry point
to a section of code and can be used to call that code
. W rzeczywistości nie jest to do końca prawda. Część kodu jest często sama w sobie bez znaczenia (z wysokiego poziomu lub z punktu widzenia implementacji). Z punktu widzenia wysokiego poziomu kod zwykle zawiera identyfikatory i należy je interpretować w kontekście statycznym, w którym zostały zadeklarowane. Ale w rzeczywistości możliwe jest powielanie tego samego kontekstu statycznego, głównie z powodu rekurencji, która jest zjawiskiem dynamicznym (w czasie wykonywania), a kod można wykonać tylko w odpowiedniej dynamicznej instancji kontekstu statycznego. Jest to nieco skomplikowane, ale konsekwencją jest to, że właściwą koncepcją jest zamknięcie, które kojarzy kawałek kodu i środowisko, w którym identyfikatory mają być interpretowane. Zamknięcie jest właściwą koncepcją semantyczną, tj. Jest właściwie definiowaną wartością semantyczną. Następnie możesz mieć stałe zamknięcia, zmienne zamknięcia,
Funkcja jest zamknięciem, zwykle z pewnymi parametrami do zdefiniowania lub zainicjowania niektórych jej bytów (stałych i zmiennych).
Pomijam wiele wariantów wykorzystania tych mechanizmów.
Zamknięcia mogą służyć do definiowania struktur OO w imperatywnych lub funkcjonalnych językach. Właściwie wczesne prace nad stylem OO (prawdopodobnie przed nazwą) zostały wykonane w ten sposób.
Artykuł, do którego się odwołujesz, który szybko przejrzałem, wydaje się interesujący, napisany przez kompetentną osobę, ale być może nie jest łatwy do przeczytania, jeśli nie masz znaczącego doświadczenia z różnymi językami i leżącymi u ich podstaw modelami obliczeniowymi.
Pamiętaj jednak: wiele rzeczy znajduje się w oczach patrzącego, o ile zachowuje spójny pogląd. Punkty widzenia mogą się różnić.
Czy to odpowiada na twoje pytanie?
PS: To długa odpowiedź. Jeśli uważasz, że jakaś jej część jest nieodpowiednia, proszę wyraźnie powiedzieć, która to jest. Dziękuję Ci.