Язык Си работает с именами массивов специальным образом. Имя массива "a" для
int a[5];
является на самом деле указателем на его нулевой элемент.
То есть у нас есть переменные (ящики) с именами
a[0] a[1] ... a[4].
При этом само имя a при его использовании в программе означает &a[0]
a | | | V a[0] a[1] a[2] a[3] a[4] _________________________________________ | | | | | | | | | | | | | | | | | | -----------------------------------------
Поэтому
int a[5];
/* Передаётся не КОПИЯ самого массива, а копия УКАЗАТЕЛЯ на его начало */
void f(int *a){ /* или f(int a[]), что есть равноценная запись */ printf("%d\n", a[1]); a[2] = 7; }
main (){ a[1] = 777; f(a); /* аргумент - массив */ printf("%d\n", a[2]); }
Вызов f(a); сделает именно ожидаемые вещи. В этом примере мы видим два правила:
ПРАВИЛО_1: При передаче в функцию имени массива в аргумент функции копируется не весь массив (жирновато будет), а указатель на его 0-ой элемент.
ПРАВИЛО_2: Указатель на начало массива МОЖНО индексировать как сам массив. Это вторая операция, помимо *pointer, применимая к указателям: pointer[n].
Второе правило влечет за собой ряд следствий.
int a[5]; /* массив */ int *ptr; /* указательная переменная */
ptr = a; /* законно, означает ptr = &a[0]; */
Теперь
ptr[0] = 3; /* означает a[0] = 3; */ ptr[1] = 5; /* означает a[1] = 5; */
Более того. Возьмем теперь
ptr = &a[2];
a[0] a[1] a[2] a[3] a[4] _________________________________________ | | | | | | a: | | | | | | | | | | | | ---------------------------------------------- | | | | ... ptr: | | | | ----------------------------- -2 -1 ptr[0] ptr[1] ptr[2]
Мы как бы "приложили" к массиву a[] массив ptr[].
В котором
ptr[0] есть a[2] ptr[1] есть a[3] ptr[2] есть a[4] ptr[3] находится за концом массива a[], МУСОР
Более того, допустимы отрицательные индексы!
ptr[-1] есть a[1] ptr[-2] есть a[0] ptr[-3] находится перед началом массива a[], МУСОР
Итак: индексировать можно И массивы И указатели.
Кстати, для имени массива a[] *a означает то же самое, что и a[0].
Это обратное следствие из схожести массивов и указателей.