Руководство полного чайника по программированию на языке Си


МАССИВЫ


Язык Си работает с именами массивов специальным образом. Имя массива "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].

Это обратное следствие из схожести массивов и указателей.




- Начало -  - Назад -  - Вперед -