Итак:
sizeof(int) == 4
Следующее:
int ar[2][2];
- это двумерный массив.
Мы знаем, что a[b]
равно *(a + b)
,И &*
преобразуется в ничто.
Итак:
&ar[1]
равно
(ar + 1)
здесь ar
"распад" или "должны быть скорректированы"(читается как: магически преобразуется) в указатель.Указатель на массив из двух элементов int, т.е.int (*)[2]
.Так что это не указатель int *
или int[2][2]
, а int (*)[2]
.Мы знаем, что
sizeof(ar) == sizeof(int[2][2]) == sizeof(int[2]) * 2 == sizeof(int) * 2 * 2
sizeof(*ar) == sizeof(*(int(*)[2]) == sizeof(int[2]) == sizeof(int) * 2
sizeof(**ar) == sizeof(**(*(int(*)[2])) == sizeof(*(int[2])) == sizeof(*(int*)) == sizeof(int)
Итак
(ar + 1)
равно (значению):
(uintptr_t)ar + sizeof(*ar) * 1 ==
(uintptr_t)ar + sizeof(*(int(*)[2])) * 1) ==
(uintptr_t)ar + sizeof(int[2]) * 1) ==
(uintptr_t)ar + sizeof(int) * 2 * 1)
т.е.он увеличивает значение указателя ar
на 2 * sizeof(int)
.
Я не понимаю, почему разница между ar + 1 и ar составляет всего 8 байтов.
ar + 1
равно
(uintptr_t)ar + sizeof(*ar) + 1
Поскольку ar
равно int[2][2]
, тогда *ar
равно int[2]
, поэтому sizeof(*ar) = sizeof(int) * 2
.
Итак, ar + 1
равно
(uintptr_t)ar + sizeof(int) * 2 * 1
Итак, (ar + 1) - ar
равно
((uintptr_t)ar + sizeof(int[2]) * 1) - (uintrpt_t)ar ==
sizeof(int[2]) ==
sizeof(int) * 2
Разве ar + 1 и & ar + 1 не дают одинаковый результат?
В случае массивов, подобных int array[2];
Значение указателя array
равно значению указателя &array
.Это причуда C, что применение оператора address-of к массиву приводит к указателю массива на ту же память.Через array
имеет тип int[2][2]
, но &array
имеет тип int(*)[2][2]
, т.е.это указатель на двумерный массив.
Поскольку тип изменяется, арифметика указателя изменяется.typeof(ar)
распадается до typeof(int(*)[2])
, поэтому ar + 1
равно
`(uintptr_t)ar + sizeof(int[2]) * 1`.
Но поскольку typeof(&ar) == typeof(int(*)[2][2])
&ar + 1
равно
`(uintrpt_t)ar + sizeof(int[2][2]) * 1`.
, следовательно,разница в значении указателя при увеличении указателя, так как sizeof(int[2][2])
равно sizeof(int) * 2 * 2
.
Я думаю, вы не понимаете, что в случае 2d-массивов «первый» уровень - это 1d-массив из двух элементов, чем второй является int.Так что typeof(ar[0])
- это массив из двух элементов int.
Ваш код имеет UB, так как модификатор %p
должен использоваться только с указателями void*
.Лучше всего помнить (или, по крайней мере, знать, что вы должны), чтобы printf("%p", (void*)&ar[1][0] + 1);
разыграть ваши указатели.