Чтобы понять этот прием, сначала вам нужно понять разницу в указателях, т. е. что происходит, когда вычитаются два указателя, указывающие на элементы одного и того же массива?
Когда один указатель вычитается из другого, результатом является расстояние (измеряемое в элементах массива) между указателями. Итак, если p
указывает на a[i]
, а q
указывает на a[j]
, то p - q
равно i - j
.
C11: 6.5.6 Аддитивные операторы (p9):
При вычитании двух указателей оба должны указывать на элементы одного и того же объекта массива или один после последнего элемента объекта массива; результатом является разница индексов двух элементов массива. [...].
Другими словами, если выражения P
и Q
указывают соответственно на i
-й и j
-й элементы массива, выражение (P)-(Q)
имеет значение i−j
strong> при условии, что значение соответствует объекту типа ptrdiff_t
.
Теперь я ожидаю, что вы знаете о преобразовании имени массива в указатель, a
преобразуется в указатель на первый элемент массива a
. &a
- это адрес всего блока памяти, т.е. это адрес массива a
. Рисунок ниже поможет вам понять (прочитайте этот ответ для подробного объяснения):
![введите здесь описание изображения](https://i.stack.imgur.com/rjnjc.png)
Это поможет вам понять, почему a
и &a
имеют одинаковый адрес и почему (&a)[i]
является адресом iго массива (того же размера, что и a
).
Итак, заявление
return (&a)[n] - a;
эквивалентно
return (&a)[n] - (&a)[0];
и эта разница даст количество элементов между указателями (&a)[n]
и (&a)[0]
, которые представляют собой n
массивов каждый из n
int
элементов. Таким образом, общее количество элементов массива равно n*n
= n
2.
ПРИМЕЧАНИЕ:
C11: 6.5.6 Аддитивные операторы (p9):
При вычитании двух указателей оба должны указывать на элементы одного и того же объекта массива или один после последнего элемента объекта массива; результатом является разница индексов двух элементов массива. Размер результата определяется реализацией, а его тип (целочисленный тип со знаком) определяется ptrdiff_t
в заголовке <stddef.h>
. Если результат не может быть представлен в объекте этого типа, поведение не определено.
Поскольку (&a)[n]
не указывает ни на элементы одного и того же объекта массива, ни на элемент, следующий за последним элементом объекта массива, (&a)[n] - a
вызовет неопределенное поведение.
Также обратите внимание, что лучше изменить тип возвращаемого значения функции p
на ptrdiff_t
.
person
haccks
schedule
07.01.2015
int p(n)
? Это даже компилируется? - person barak manos   schedule 08.01.2015gcc
. - person lurker   schedule 08.01.2015int q(int n) { return sizeof (char [n][n]); }
- person ouah   schedule 08.01.2015sizeof
для сохранения символов. Все остальные: это намеренно неясный код, это неопределенное поведение, ответ @ouah правильный. - person ecatmur   schedule 08.01.2015O(n^2)
для расчетаn^2
- person Khaled.K   schedule 14.01.2015