The subscript expression a[i]
is defined as *(a + i)
- given an address a
1, offset i
elements (not bytes! - more on that below ) с этого адреса и разыменовать результат. ary[0]
эквивалентно выражению *(ary + 0)
, которое эквивалентно *ary
, ary[1]
эквивалентно *(ary + 1)
и т. д.
Выражение p[-2]
эквивалентно *(p - 2)
; начиная с p == ary + 3
, затем p - 2 == ary + 3 - 2 == ary + 1
, который является адресом второго элемента ary
. Таким образом, p[-2] == ary[1] == 2
.
Арифметика указателя основана на размере типа, на который указывает указатель. Если p
содержит адрес объекта типа T
, то p + 1
дает адрес следующего объекта того типа. Например, задано
char *cp = (char *) 0x1000;
short *sp = (short *) 0x1000;
long *lp = (long *) 0x1000;
тогда имеем следующее:
Address char short long
------- +---+ +---+ +---+
0x1000 | | cp | | sp | | lp
+---+ + - + + - +
0x1001 | | cp + 1 | | | |
+---+ +---+ + - +
0x1002 | | cp + 2 | | sp + 1 | |
+---+ + - + + - +
0x1003 | | cp + 3 | | | |
+---+ +---+ +---+
0x1004 | | cp + 4 | | sp + 2 | | lp + 1
+---+ + - + + - +
... ... ...
- Массивы не являются указателями, однако если они не являются операндами операторов
sizeof
или унарных &
или строковым литералом, используемым для инициализации массива символов в объявлении, выражение типа "N-элементный массив из T
" будет преобразовано или "затухать" в выражение типа "указатель на T
", а значением выражения будет адрес первый элемент массива.
Арифметика указателя работает аналогично индексации массива. Массив распадается на указатель, поэтому
ary + 3
имеет то же значение, что и&ary[3]
.я попытался увидеть другой результат, изменив index. p[0] дает «4», а p[1],p[2] дает «0», как это видно?
p[1]
иp[2]
индексируются за пределами последнего элемента исходного массива, что является неопределенным поведением, и найденные значения не имеют значения.https://www.geeksforgeeks.org/pointer-array-array-pointer/ размещен очень плохой код.
sizeof(p) = %lu
имеет неопределенное поведение и абсолютно неправильно в 64-разрядных системах Windows, гдеsize_t
— 64-битное, а <long
s> — 64-битное.