Формальные и фактические параметры
Параметры, записанные в скобках прототипа (заголовка) функции или ее описания, называют формальными параметрами (Len, y и ch). Параметры, записанные при вызове функции, называются фактическими параметрами (LEN, Y, C). Между ними должно быть соответствие:
* по типу, с учётом их совместимости. Например, вместо параметра типа char можно передать не только символ, но и его код типа int. Вместо формального вещественного параметра можно передать целый, но не наоборот;
* по порядку следования. Нарушение этого требования приведёт либо к ошибке компиляции, либо повлияет на результат. Если в нашем примере вызвать функцию LINE2(“*”, 5, 20), то компилятор сообщает о невозможности преобразования char в int. Если же вызвать LINE2 (Y, LEN, ‘-‘), то в строке LEN будет выведено Y символов “-“;
* по количеству параметров. Это требование справедливо, если не используются параметры по умолчанию.
Замечание. Имена формальных и фактических параметров могут отличаться, показывая тем самым, что для них выделяются разные ячейки памяти. Если имена формальных и фактических параметров совпадают, то все равно это разные переменные.
Формальные параметры, которые используются при описании заголовка функции, могут быть двух видов: параметры-значения и параметры-переменные. Использование параметров-значений или параметров-переменных влияет на тип передачи данных из программы в функцию и наоборот.
1) Параметры-значения используются в тех случаях, когда функция получает некоторые параметры, но после действия функции, их не возвращает. Такие параметры имеют след. особенности:
* для фактического и формального параметров компилятор отводит разные ячейки памяти;
* при выполнении программы содержимое фактического параметра копируется в формальный параметр, то есть при первом вызове LINE2 (20, 5, '*'); Len=20, y=5 и ch=’*’, хотя это явно нигде не записывается;
* из первой особенности следует, что если в функции изменить формальный параметр, то это не повлияет на значение переменной, используемой при вызове, то есть фактического параметра. Если бы в функции изменили y (например, там было бы записано y++), то значение соответствующей переменной Y в головной функции после второго вызова осталось бы без изменения, т. е. тем, что ввели;
* в качестве фактического параметра, соответствующего параметру-значению может быть выражение соответствующего или совместимого типа. Например, функцию можно вызвать так: LINE2 (LEN*2, Y+1, ‘*’). Как частный случай можно передавать константу: LINE2 (20, 5, '*'); или переменную LINE2(LEN, Y, C); При этом её имя, используемое при вызове, не обязательно должно отличаться, как в нашем примере, от имени формального параметра. В головной программе переменную для фактической длины символов можно было бы тоже назвать Len. Но и в этом случае это разные ячейки памяти.
2) Формальные параметры-переменные используются в тех случаях, когда функция получает некоторые параметры, но после действия функции, эти параметры необходимо вернуть в вызывающую функцию, например main().
Передачу данных из пользовательской функции в программу можно двумя способами: через ссылочный тип или через указатели.
Рассмотрим ссылочный тип. Ссылочный тип используется следующим образом:
* в заголовке функции параметры записываются как параметры-переменные ссылочного типа, то есть с символом &, например, void SINCOS(float x, float eps, float &y, float &z);
* в теле функции никакие дополнительные символы для этих переменных не используются, то есть работают, как с обычными переменными;
* при вызове функции в качестве фактических параметров, указывают простые переменные соответствующего типа объявленные обычным образом, например, SINCOS(Х, Е, Y, Z);
* входные параметры как параметры-значения (х, eps) используются по тем же правилам;
Замечание. С помощью ссылочного типа для формального (y) и фактического (Y) параметров отводится одна и та же ячейка памяти, которая в пользовательской функции называется y, а при вызове в вызывающей функции main() - Y. Поэтому все изменения параметра y сказываются на изменении параметра Y. Таким образом, происходит передача значения параметра из пользовательской функции в основную (вызывающую) функцию.
Например. Для x=-0.8, -0.6, -0.4, …, 0.8 найти и вывести на экран значения функций:
в виде следующих пяти столбцов: x, y, cos(x), z, sin(x), в которых показать значения указанных тригонометрических функций, вычисленные как сумма бесконечного ряда с заданной точностью, так и с помощью встроенных функций.
Для решения задачи составим функцию SINCOS, которая вычисляет обе бесконечные суммы с произвольной одинаковой точностью. Поэтому она имеет два входных параметра: аргумент функций (x) и одинаковую точность вычисления бесконечных сумм (eps) и два выходных (y и z), которые в заголовке функции объявляются с помощью ссылочного типа.
void SINCOS(float x, float eps, float &y, float &z);
void main()
{
float x, sn, cs;
cout<<" x y=cos(x) Cos(Standart) z=sin(x) Sin(Standart)";
cout<<”\n\n”;
for (x=-0.8; x<0.805; x+=0.2)
{ SINCOS(x,1E-10, cs, sn);
printf("%5.1f %10.6f %12.6f %10.6f %12.6f\n", x, cs, cos(x), sn, sin(x));
}
getch();
}
//пользовательская функция
void SINCOS(float x, float eps, float &y, float &z)
{ float k=1, s1=1; y=1;
do
{s1=s1*(-1)*x*x/(k*(k+1));
y+=s1;
k+=2;
}
while (fabs(v1)>eps);
k=2; s1=x; z=x;
do
{ s1=s1*(-1)*x*x/(k*(k+1));
z+=s1;
k+=2;
}
while (fabs(v1)>eps);
}
Функции с одним результатом. Оператор return.
Если функция возвращает один результат, то в прототипе функции вместо void указывается тип результата функции (char, int, long, float, double и др.), а в теле функции обязательно указывается
return <значение>,
где <значение> должно быть того же или совместимого типа, что и в заголовке (прототипе) функции.Оператор return<значение> осуществляет выход из функции, передаёт управление в вызвавшую её функцию и возвращает в неё значение указанного выражения.
Например. Написать функцию SUMDIG(int), которая вычисляет сумму цифр полученного целого числа.
int SUMDIG(int);
void main()
{
int X=1;
cout<< "Введите целое число:\n";
while (X)
{ cin>>X;
cout<<”Сумма цифр=”<<SUMDIG(X)<<”\n”;
cout<< "Для выхода введите 0\n\n";
}
getch();
}
int SUMDIG (int num)
{ int s=0, dig;
while (num)
{ dig=num%10; // выделение последней цифры
s+=dig; //сумма цифр
num/=10; //выделение целой части
}
return s; //возврат суммы
}
Замечание. Некоторые варианты применения return:
1) return 5; //возвращает константу
2) return s; //возвращает значение переменной
3) return a+b; //возвращает значение выражения
4) float MyFun (float x, float y)
{ if (x>y) return x+y;
else return x*y;
} // используется несколько раз, и не обязательно в конце функции
5) return используется для выхода из функции типа void.