Передача аргументов в функцию
В правильно организованной функции использование списка аргументов (параметров) и возвращаемого значения является единственным способом связи этой функции с остальными.
При вызове функции в стеке создаются локальные переменные соответствующие по типу формальным параметрам функции. Затем они инициализируются значениями фактических параметров, задаваемых при вызове функции в строгом соответствии с последовательностью формальных параметров. При необходимости производится допустимое преобразование типов. Соответствие фактических и формальных параметров устанавливается не по именам параметров, а по их местоположению в списках параметров.
Рассмотренный алгоритм вызова функции гарантирует сохранение значений фактических параметров независимо от того, что делала функция с соответствующими формальными параметрами. Рассмотрим функцию Sum(), вычисляющую значение суммы элементов массива:
#include <stdio.h>
double Sum(double A[], int nA)
{
double s = 0;
while(nA) s += A[--nA];
return s;
}
void main (void)
{
double B[] = { 1, 2, 3, 4, 5 };
int nB = sizeof(B)/sizeof(B[0]);
printf("Сумма = %lf\n", Sum(B,nB));
printf("nB = %d\n", nB);
}
Функция при своей работе изменяет значение формального параметра nA, в котором передается размер массива. Однако, если запустить программу, то можно увидеть, что значение соответствующего фактического параметра nB осталось неизменным, ввиду того, что функция работает с копиями параметров.
При фактическом параметре-массиве в функцию передается значение его имени, то есть адрес его первого элемента, для которого создается копия в стеке, которая уже не является адресом-константой и допускает изменение своего значения внутри функции. Поэтому функцию Sum можно реализовать и следующим образом:
double Sum(double A[], int nA)
{
double s = 0, *Aend = A + nA;
while( A < Aend ) s += *(A++);
return s;
}
Соответствующий фактический параметр - константный адрес массива B в вызывающей функции не меняет своего значения, то есть никаких противоречий в предыдущей функции нет.
Вообще говоря, для формальных параметров-массивов описания в виде A[] и *A совершенно идентичны и обозначают локальную копию адреса соответствующего типа. Какое из этих описаний использовать, зависит от смысла параметра. Если это массив, то более наглядно использовать описание вида A[].
Дата добавления: 2015-02-13; просмотров: 577;