Таким образом, указатели не являются целыми числами. Конечно, вы можете преобразовать их в целые числа, переведя их в целочисленный тип или добавив к ним целые числа, чтобы сместить их. Но они не целые.
Указатели как математические векторы над целыми числами, если вы сделали какую-либо линейную алгебру.
p1-p2
расстояние между p1
и p2
, целым числом, необходимым для добавления к p2
достичь p1
.
Когда вы добавляете целое число в указатель, вы должны обратить внимание на тип указателя. Если указатель относится к объекту размером 4, каждый раз, когда вы добавляете 1 к указателю, его числовой адрес увеличивается на 4, а не 1.
То же самое верно, если вы вычитаете два указателя.
Ключевая часть здесь заключается в том, что числовое значение адреса в памяти имеет значение, но тип имеет значение не менее, чтобы понять, что происходит.
Вторая странная вещь, происходящая здесь, заключается в том, что массивы распад в указатели к их первому элементу при капле шляпы. Они, однако, не указатели на их первый элемент, они просто конвертировать в них очень легко.
Так что, когда мы делаем это:
(&a)[1]
мы принимаем адрес a
. Адрес a
является указателем типа int(*)[7]
. Это указатель на массив, не указатель на первый элемент массива. Разница заключается в типе указателя. И это важно.
Затем мы используем []
на указателе. Если у вас есть указатель или массив p
и значение v
, p[v]
определено как *(p+v)
. Это приводит к юмору, если вы делаете v[p]
, но это не важно.
Сообщите, что pa
представляет (&a)
. Тогда pa[1]
будет *(pa + 1)
.
Теперь pa
является указателем на массив (не является указателем на первый элемент массива). Таким образом, +1 добавляет полный размер массива (sizeof (int) * 7) к числовому значению.
So pa+1
является указателем на один конец до конца a
и имеет тип pointer-to-array.
Затем мы разыскиваем и получаем несуществующий массив размера 7 сразу после окончания массива a
.
Затем мы вычитаем a
.
(&a)[1]-a
Это когда пинки распада указатель в. Там нет -
работы с массивами, но есть -
операции над указателями. Итак, C-язык помогает распадается каждый из этих массивов в указатели на их первый элемент.
Указатель на первый элемент a
- &a[0]
.
Указатель на первый элемент массива размера 7 сразу после окончания a
... &a[7]
.
Оба эти указателя имеют тип int*
. Когда вы вычитаете два int*
s, вы получаете их числовое значение указателя, деленное на sizeof(int)
. В этом случае это легко - 7.
Это может быть проще, если бы мы смотрели на это:
(&a)[1]-(&a)[0]
или
*(&a+1)-*(&a+0)
&a
является указателем на массив a
типа «указатель на массив размером 7». Мы добавляем 1 к нему, получая указатель на массив потом в одном случае, и ноль в другом случае.
Затем мы возвращаемся к тому, чтобы быть массивами и вычитаем. Триггеры вычитания распадаются на указатель на первый элемент, поэтому мы получаем указатель на элемент сразу после конца a и указатель на первый элемент a.
&a[7]-&a[0]
который
&*(a+7)-&*(a+0)
Теперь &*
ничего не делает, к вещам, которые уже указатели (которые они в этот момент), так:
(a+7)-(a+0)
Тогда возникает вопрос, как вам нужно добавить к a+0
, чтобы достичь a+7
. Ответ, не удивительно, что это 7
:
(a+7) = (a+0)+7
и это то, что отображается.
'(& a) [1] -a' - указатель разница. – haccks
включите предупреждения компилятора и обратите внимание, что у вас есть '% zu' для' size_t'. – sjsam
@hacce почему разница указателя 7 не что-то? – Mohan