Aby zrozumieć ten hack, najpierw musisz zrozumieć różnicę wskaźników, tj. Co się stanie, gdy odejmie się dwa wskaźniki wskazujące na elementy tej samej tablicy ?
Kiedy jeden wskaźnik jest odejmowany od drugiego, wynikiem jest odległość (mierzona w elementach tablicy) między wskaźnikami. Tak więc, jeśli p
wskazuje a[i]
i q
wskazuje na a[j]
, to p - q
jest równei - j
.
C11: 6.5.6 Operatory addytywne (p9):
Gdy odejmowane są dwa wskaźniki , oba wskazują elementy tego samego obiektu tablicy lub jeden za ostatnim elementem obiektu tablicy; wynik jest różnicą między indeksami dwóch elementów tablicy . […].
Innymi słowy, jeśli wyrażenia P
i Q
wskazują, odpowiednio, i
-ty i j
-ty element obiektu tablicy, wyrażenie (P)-(Q)
ma wartośći−j
pod warunkiem, że wartość pasuje do obiektu typu ptrdiff_t
.
Teraz oczekuję, że jesteś świadomy konwersji nazwy tablicy na wskaźnik, a
konwertuje na wskaźnik do pierwszego elementu tablicy a
. &a
to adres całego bloku pamięci, czyli adres tablicy a
. Poniższy rysunek pomoże ci zrozumieć ( przeczytaj tę odpowiedź, aby uzyskać szczegółowe wyjaśnienie ):
Pomoże ci to zrozumieć, dlaczego a
i &a
ma ten sam adres i jaki (&a)[i]
jest adres i- tej tablicy (tego samego rozmiaru co adres a
).
A więc oświadczenie
return (&a)[n] - a;
jest równa
return (&a)[n] - (&a)[0];
a ta różnica da liczbę elementów między wskaźnikami (&a)[n]
i (&a)[0]
, które są n
tablicami każdego z n
int
elementów. Dlatego łączna liczba elementów tablicy wynosi n*n
= n
2 .
UWAGA:
C11: 6.5.6 Operatory addytywne (p9):
Gdy odejmowane są dwa wskaźniki, oba wskazują elementy tego samego obiektu tablicy lub jeden za ostatnim elementem obiektu tablicy ; wynik jest różnicą między indeksami dwóch elementów tablicy. Rozmiar wyniku jest zdefiniowany w implementacji , a jego typ (typ liczby całkowitej ze znakiem) jest ptrdiff_t
zdefiniowany w <stddef.h>
nagłówku. Jeśli wynik nie jest reprezentowalny w obiekcie tego typu, zachowanie jest niezdefiniowane.
Ponieważ (&a)[n]
żaden z elementów tego samego obiektu tablicy ani jeden za ostatnim elementem obiektu tablicy nie (&a)[n] - a
wywoła niezdefiniowanego zachowania .
Zauważ też, że lepiej zmienić zwracany typ funkcji p
na ptrdiff_t
.