Вызов функции

Выполнение вызова функции происходит следующим образом:

1. Вычисляются выражения в списке выражений, и подвергаются обычным арифметическим преобразованиям. Затем, если известен прототип функции, тип полученного фактического аргумента сравнивается с типом соответствующего формального параметра. Если они не совпадают, то либо производится преобразование типов, либо формируется сообщение об ошибке. Число выражений в списке выражений должно совпадать с числом формальных параметров, если только функция не имеет переменного числа параметров. В последнем случае проверке подлежат только обязательные параметры. Если в прототипе функции указано, что ей не требуются параметры, а при вызове они указаны, формируется сообщение об ошибке.

2. Происходит присваивание значений фактических параметров соответствующим формальным параметрам.

3. Управление передается на первый оператор функции.

4. Выполнение оператора return в теле функции возвращает управление и возможно, значение в вызывающую функцию. При отсутствии оператора return управление возвращается после выполнения последнего оператора тела функции, а возвращаемое значение не определено.

Вызов функции имеет следующий формат:

АдресноеВыражение ([СписокВыражений])

Поскольку синтаксически имя функции является адресом начала тела функции, в качестве обращения к функции может быть использовано АдресноеВыражение (в том числе и имя функции или разадресация указателя на функцию), имеющее значение адреса функции.

СписокВыражений представляет собой список фактических параметров, передаваемых в функцию. Этот список может быть и пустым, но наличие круглых скобок обязательно.

Фактический параметр может быть величиной любого основного типа, структурой, объединением, перечислением или указателем на объект любого типа. Массив и функция не могут быть использованы в качестве фактических параметров, но можно использовать указатели на эти объекты.

Пример:

#include<iostream.h>void change (int &x, int &y); void main() {int a=1,b=4; cout<<a<<" "<<b<<endl; change (a,b); cout<<a<<" "<<b; }void change (int &x, int &y) { int k=x; x=y; y=k; } Результат:1 44 1

Пример:

#include<iostream.h>void change (int *x, int *y); void main() {int a=1,b=4; cout<<a<<" "<<b<<endl; change (&a,&b); cout<<a<<" "<<b; }void change (int *x, int *y) { int k=*x; *x=*y; *y=k; }Результат:1 44 1

Т.к. АдресноеВыражение, стоящее перед скобками определяет адрес вызываемой функции, то функция может быть вызвана через указатель на функцию.

Пример:

int (*fun)(int x, int *y);

Здесь объявлена переменная fun как указатель на функцию с двумя параметрами: типа int и указателем на int. Сама функция должна возвращать значение типа int. Круглые скобки, содержащие имя указателя fun и признак указателя *, обязательны, иначе запись

int *fun (intx,int *y);

будет интерпретироваться как объявление функции fun возвращающей указатель на int.

Вызов функции возможен только после инициализации значения указателя fun и имеет вид:

(*fun)(i,&j);

В этом выражении для получения адреса функции, на которую ссылается указатель fun, используется операция разадресации *.

Указатель на функцию может быть передан в качестве параметра функции. При этом разадресация происходит во время вызова функции, на которую ссылается указатель на функцию. Присвоить значение указателю на функцию можно в операторе присваивания, употребив имя функции без списка параметров.

Пример:

double (*fun1)(int x, int y); double fun2(int k, int l); fun1=fun2; /* инициализация указателя на функцию */ (*fun1)(2,7); /* обращение к функции */

В рассмотренном примере указатель на функцию fun1 описан как указатель на функцию с двумя параметрами, возвращающую значение типа double, и также описана функция fun2. В противном случае, т.е. когда указателю на функцию присваивается функция описанная иначе чем указатель, произойдет ошибка.

Рассмотрим пример использования указателя на функцию в качестве параметра функции вычисляющей производную от функции cos(x).

Пример:

double proiz(double x, double dx, double (*f)(double x)); double fun(double z); int main() { double x; /* точка вычисления производной */ double dx; /* приращение */ double z; /* значение производной */ scanf("%f,%f",&x,&dx); /* ввод значений x и dx */ z=proiz(x,dx,fun); /* вызов функции */ printf("%f",z); /* печать значения производной */ return 0; } double proiz(double x,double dx, double (*f)(double z)) { /* функция вычисляющая производную */ double xk,xk1,pr; xk=fun(x); xk1=fun(x+dx); pr=(xk1/xk-1e0)*xk/dx; return pr; } double fun(double z) { /* функция от которой вычисляется производная */ return (cos(z)); }

Для вычисления производной от какой-либо другой функции можно изменить тело функции fun или использовать при вызове функции proiz имя другой функции. В частности, для вычисления производной от функции cos(x) можно вызвать функцию proiz в форме

z=proiz(x,dx,cos);

а для вычисления производной от функции sin(x) в форме

z=proiz(x,dx,sin);


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: