logo search
Подбельский Фомин_Программирование на языке СИ_

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

Вызов функции. Для обращения к функции используется выражение с операцией "круглые скобки":

обозначение_функции (список_фактических_параметров)

Операндами операции '( )' служат обозначение_функции и список_фактических_параметров. Наиболее естественное и понятное обозначение _функции - это ее имя. Кроме того, функцию можно обозначить, разыменовав указатель на нее. Так как указатели на функции мы еще не ввели (см. следующие параграфы этой главы), то ограничимся пока для обозначения функций их именами.

Список фактических параметров, называемых аргументами, - это список выражений, количество которых равно числу формальных параметров функции (исключение составляют функции с переменным количеством параметров). Соответствие между формальными и фактическими параметрами устанавливается по их взаимному расположению в списках. Порядок вычисления значений фактических параметров (слева направо или справа налево) стандарт языка Си не определяет.

Между формальными и фактическими параметрами должно быть соответствие по типам. Лучше всего, когда тип фактического параметра совпадает с типом формального параметра. В противном случае компилятор автоматически добавляет команды преобразования типов, что возможно только в том случае, если такое приведение типов допустимо. Например, пусть определена функция с прототипом:

Далее в программе использован вызов:

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

Так как вызов функции является выражением, то после выполнения операторов тела функции в точку вызова возвращается некоторое значение, тип которого строго соответствует типу, указанному перед именем функции в ее определении (и прототипе). Например, функция

всегда возвращает значение типа float. В выражения, помещенные в операторы return, компилятор автоматически добавит средства для приведения типов, т.е. получим (невидимые программисту) операторы:

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

Передача параметров по значению предусматривает следующие шаги:

1. При компиляции функции (точнее, при подготовке к ее выполнению) выделяются участки памяти для формальных параметров, т.е. формальные параметры оказываются внутренними объектами функции. При этом для параметров типа float формируются объекты типа double, а для параметров типов char и short int создаются объекты типа int. Если параметром является массив, то формируется указатель на начало этого массива и он служит представлением массива-параметра в теле функции.

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

3. Значения выражений - фактических параметров заносятся в участки памяти, выделенные для формальных параметров функции. При этом float преобразуется в double, a char и short int - в тип int (см. п. 1).

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

5. Никакого влияния на фактические параметры (на их значения) функция не оказывает.

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

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

имя_фукции (список_фактических_параметров);

Например, следующая функция возвращает значение типа void:

Обращение к ней

приведет к такому выводу на экран:

Может оказаться полезной и функция, которая не только не возвращает никакого значения (имеет возвращаемое значение типа void), но и не имеет параметров. Например, такая:

При обращении

в результате выполнения функции будет выведено на экран дисплея сообщение: