Указатели как формальные параметры
В Си предусмотрен единый способ передачи параметров в функцию -так называемая ПЕРЕДАЧА ПО ЗНАЧЕНИЮ. Формальные параметры представляют собой аналог собственных локальных переменных функции, которым присваиваются значения фактических параметров. Формальные параметры, представляя собой копии, могут как угодно изменяться -это не затрагивает соответствующих фактических параметров. Если же требуется обратное, то формальный и фактический параметр должны быть явно переданы в виде указателей на ту переменную, изменения которой должны производиться в функции:
void inc(int *p)
{ (*pi)++; } // аналог вызова:
// pi = &a
void main()
{ int a;
inc(&a); } // *(pi)++ эквивалентно a++
В данном примере формальный параметр является явным указателем, а фактический - явным адресом переменной. В Си++ аналогичный способ передачи параметров поддерживается транслятором с помощью неявных, скрытых от программиста указателей, и называется передачей параметров по ссылке (см.7.2). В Си тоже имеется одно такое исключение: формальный параметр - массив передается в виде указателя на его начало. Посмотрим, как в этом случае поступает транслятор:
int sum(int A[],int n) // Исходная программа
{ int s,i;
for (i=s=0; i<n; i++) s+= A[i];
return s; }
int sum(int *p, int n) // Эквивалент с указателем
{ int s,i;
for (i=s=0; i<n; i++) s+= p[i];
return s; }
int x,B[10]={1,4,3,6,3,7,2,5,23,6};
void main()
{ x = sum(B,10); } // аналог вызова: p = B, n = 10
Заметим, что в вызове фигурирует идентификатор массива. Он интерпретируется как начальный адрес массива (указатель на его нулевой элемент). Поэтому типы формального и фактического параметров совпадают. Совпадают также оба варианта функций вплоть до генерируемого кода.
Рассмотрим третий вариант той же функции:
int sum(int *p, int n)
{ int s;
for (s=0; n >=0; n--) s += *p++;
return s; }
В нем операции p[i] и i++ над элементами массива заменены эквивалентной операцией *p++. Это значит, что при просмотре массива операция индексирования с линейно изменяющимся индексом может быть замена аналогичным линейным перемещением указателя.