A wystarczy poznać matematyczny wzór stojący za tym i wszystko staje się jasne, a także można wyciągnąć różne ciekawe permutacje.
Kiedyś już to na forum tłumaczyłem, ale nie znajdę tego więc napiszę ponownie.
Adresowanie odbywa się wzorem matematycznym, x + y
, adres + offset, teoretycznie adres + adres jest możliwe, ale kompilatory tego nie uznają więc pominę(oczywiście w assemblerze można), gdzie kompilator jeśli będziemy mieli typ danych wskaźnika char* to traktuje offset jako liczbę o wielkość typu elementu wskaźnika, na który wskazuje.
offset * sizeof(char)
, dla tablicy intów będzie razy offset * sizeof(int)
itp.
adresowanie tablic wygląda tak alphabet[0]
czyli alphabet jest wskaźnikiem char* czyli jest traktowany jak adres, a 0 jest int czyli jest traktowane jak offset, a więc offset musi być pomnożony razy wielkość elementu char to 1 bajt, offset * sizeof(char)
.
We wzorze występuje przemienność, bo dodawanie jest przemienne, czyli możemy zapisać to tak 0[alphabet]
,
wzór wyjdzie offset * sizeof(char) + adres
, lub analogicznie dla alphabet[0]
adres + offset * sizeof(char)
.
A rozwinięcie tego to *(0 * 1 + alphabet)
tyle, że to robi automatycznie kompilator, w assemblerze to jest poprawne, kompilator dedukuje, że int trzeba przemnożyć przez wielkość elementu, czyli w C będzie to *(alphabet + 0)
char alphabet[] = "asdfsds";
to jest to samo co:
char *alphabet = "asdfsds";
String w pamięci to zwykła tablica, czyli tablica to adres gdzie to jest, a jej elementy to offset * wielkość elementu.
Dodając do adresu offset, otrzymujemy nowy adres tak jakby to była nowa tablica, tylko po prostu wskazuje na inne miejsce w tablicy.
A *alphabet
to po prostu skrót do alphabet[0]
,
Jak tego nie zrozumiesz to zostaje tylko skorzystać z jakichś rysunków, może animacji.