main(void)
{
int а = 0, b = 1;
float х = 2.0, у = 3.0;
double realadd (double, double);
a = intadd(a, b);
x = realadd(x, y);
}
intadd(int a, int b)
{
return (a + b);
}
double realadd(double x, double y)
{
return (x + y);
}
В примере функция intadd объявлена неявно с типом возвращаемого значения int, так как она вызнана до своего определения. Компилятор не проверит типы аргументов при вызове функции intadd, поскольку список типов аргументов для нее не задан.
Функция realadd возвращает значение типа double. В функции main имеется предварительное объявление функции realadd. Тип возвращаемого значения (double), заданный в определении, соответствует типу возвращаемого значения, заданному в предварительном объявлении. В предварительном объявлении также определены типы двух параметров функции realadd. Типы фактических аргументов соответствуют типам, заданным в предварительном объявлении, и также соответствуют типам формальных параметров в определении функции realadd.
Вызов функции
Вызов функции передает управление и фактические аргументы (если они есть) заданной функции. Синтаксически вызов функции имеет следующий вид:
<
<
<
При выполнении вызова функции происходит присвоение значений фактических аргументов формальным параметрам. Перед этим каждый фактический аргумент вычисляется, над ним выполняются необходимые преобразования, и он копируется в стек. Первый фактический аргумент соответствует первому формальному параметру, второй — второму и т. д. Все аргументы передаются по значению, только массивы — по ссылке.
Вызванная функция работает с копией фактических аргументов, поэтому никакое изменение значений формальных параметров не отразится на значениях аргументов, с которых была сделана копия.
Передача управления осуществляется на первый оператор тела функции. Выполнение оператора return в теле функции возвращает в точку вызова управление и, возможно, значение. В отсутствие оператора return управление возвращается по достижении завершающей фигурной скобки тела функции. В этом случае возвращаемое значение не определено.
Примечание
<
Вызов функции синтаксически напоминает ее объявление. При объявлении функции сначала записывается ее имя, а затем список типов аргументов в скобках. При вызове также записывается имя функции, а за ним следует список выражений в скобках.
Аналогичным образом функция вызывается через указатель. Предположим, что указатель на функцию объявлен следующим образом:
int (*fpointer)(int, int);
Идентификатор fpointer именует указатель на функцию с двумя аргументами типа int и возвращаемым значением типа int. Вызов функции в этом случае будет выглядеть так:
extern int f (int, int);
fpointer = &f; /*знак & необязателен */
(*fpointer)(3,4); /* можно и просто fpointer(3,4); */
Примеры:
/* пример 1 */
double *realcomp(double, double);
double a, b, *rp;
rp = realcomp(a, b);
/* пример 2 */
main()
{
long lift(int), slep(int), drop(int);
void work(int, long (*)(int));
int select, count;
.
.
.
switch(select) {
case 1: work(count, lift); break;
case 2: work(count, step); break;
case 3: work(count, drop); break;
default: break;
}
void work(int n, long (*func)(int))
{
int i;
long j;
for(i = j = 0; i < n; i++)
j += (*func)(i); /* можно просто j += func(i); */