Чтобы понять этот хак, сначала нужно понять разницу в указателях, т. Е. Что происходит, когда два указателя указывают на элементы одного массива вычитаются ?
Когда один указатель вычитается из другого, результатом является расстояние (измеренное в элементах массива) между указателями. Итак, если pуказывает на a[i]и qуказывает на a[j], тоp - q равноi - j .
C11: 6.5.6 Аддитивные операторы (p9):
Когда вычтены два указателя , оба должны указывать на элементы одного и того же объекта массива или один после последнего элемента объекта массива; Результатом является разница индексов двух элементов массива . [...].
Другими словами, если выражения Pи Qуказывают, соответственно, на i-й и j-й элементы объекта массива, выражение (P)-(Q)имеет значениеi−j при условии, что это значение соответствует объекту типа ptrdiff_t.
Теперь я ожидаю, что вы знаете о преобразовании имени массива в указатель, aпреобразует указатель на первый элемент массива a. &aэто адрес всего блока памяти, т.е. это адрес массива a. Рисунок ниже поможет вам понять ( прочитайте этот ответ для подробного объяснения ):

Это поможет вам понять , что , почему aи &aимеет тот же адрес , и как (&a)[i]это адрес I - го массива (такого же размера, как уa ).
Итак, утверждение
return (&a)[n] - a;
эквивалентно
return (&a)[n] - (&a)[0];
и эта разница будет давать количество элементов между указателями (&a)[n]и (&a)[0], которые являются nмассивами каждого из n intэлементов. Следовательно, все элементы массива равны n*n= n2 .
НОТА:
C11: 6.5.6 Аддитивные операторы (p9):
Когда вычтены два указателя, оба должны указывать на элементы одного и того же объекта массива или один после последнего элемента объекта массива ; Результатом является разница индексов двух элементов массива. Размер результата определяется реализацией , а его тип (целочисленный тип со знаком) ptrdiff_tопределяется в <stddef.h>заголовке. Если результат не может быть представлен в объекте этого типа, поведение не определено.
Поскольку (&a)[n]ни указатель на элементы одного и того же объекта массива, ни на один элемент после последнего элемента объекта массива (&a)[n] - aне вызовет неопределенное поведение .
Также отметим , что, лучше изменить тип возвращаемого значения функции pв ptrdiff_t.