Объявление функции
Определение функции max(…) (см. пример 1) расположено до функции main(), которая в данной случае является вызывающей функцией, т.е. к моменту вызова функция max() уже определена. В С нет строгих требований к местоположению определения функции, оно может располагаться:
перед функцией main(),
после функции main(),
в другом модуле (файле) программы.
Вызов и определение функции могут находиться в разных частях программы, но есть простое правило, относящееся к использованию функций, - к моменту вызова функция должна быть либо определена, либо объявлена.
Если вызов функции предшествует ее определению, то перед вызовом необходимо поместить объявление функции, которое чаще называют ее прототипом. Это связано с тем, что компилятору необходимо осуществить проверку соответствия количества и типов передаваемых фактических параметров количеству и типам формальных параметров.
Прототип функции обладает следующими свойствами:
прототип имеет такой же вид, что и заголовок определения функции,
тело функции отсутствует,
имена формальных параметров могут быть опущены (типы параметров опускать нельзя).
Рассмотрим пример решения предыдущей задачи с использованием прототипа функции max().
В теле функции вместо оператора if будем использовать оператор ?, что позволит записать алгоритм короче.
Пример 1.1
…
int max (int a, int b); //прототип функции max
// основная программа
void main()
{int x, y, big;
printf(“\n x=”); scanf(“%d”, &x);
printf(“\n y=”); scanf(“%d”, &y);
big = max(x, y); //вызов функции max
printf(“big = %d \n”, big);
}
int max (int a, int b) // определение функции max
{
return (a>=b)? a : b; // возврат результата
}
Прототип функции max() может быть задан двумя способами:
int max (int a, int b); или int max (int , int );
Как видно, во втором случае опущены имена параметров функции, что не помешает транслятору проверить правильность ее вызова.
Зачастую прототипы всех используемых функций задают в начале программного модуля вне зависимости от местоположения определения конкретной функции. Такой подход дает возможность охватить единым взглядом все используемые функции и их параметры, что весьма удобно при разработке и отладке больших программ.
Операторов return в функции может быть несколько, и тогда они фиксируют несколько точек выхода.
Пример 1.2 Найти максимальное значение из двух целых чисел a и b, отразить его на экране и вернуть в точку вызова.
…
int max (int, int); //прототип функции max
// основная программа
void main()
{int x, y, big;
printf(“\n x=”); scanf(“%d”, &x);
printf(“\n y=”); scanf(“%d”, &y);
big = max(x, y); //вызов функции max
}
int max (int a, int b) // определение функции max
{ if (a>b)
{ printf (“max = %d \n”, a);
return a; }
else
{ printf (“max = %d \n”, b);
return b; }
}
Предыдущий вариант данного примера, когда печать выполняется в вызывающей программе, более компактный, но в данном случае демонстрируется возможность наличия нескольких выходов из одной функции.
Тип возвращаемого значения и типы параметров совместно определяют тип функции.
Для вызова функции в простейшем случае нужно указать ее имя, за которым в ( ) через запятую перечисляются имена передаваемых аргументов. Вызов функции может находиться в любом месте программы, где по синтаксису допустимо выражение того типа, который формирует функция. Если тип возвращаемого функцией значения не void, она может входить в состав выражений или, в частном случае, располагаться в правой части оператора присваивания (см. пример 1, 1.1).
Пример 2. Функция, возвращающая сумму двух целых величин.
#include <iostream.h>
int sum (int a, int b); //объявление функции
int main ()
{int a=2, b=3, c, d;
c = sum (a, b); //вызов функции
cin >> d;
cout << sum (c, d); //вызов функции
return 0;
}
int sum (int a, int b) //определение функции
{return (a+b);
}