
|
|
|
|
|
|
|
|
|
|
|
é Функция - это именованная часть программы, к которой можно
обращаться из других частей программы столько раз, сколько потребуется
éФункция - это именованная последовательность описаний и операторов, выполняющая какое-либо законченное действие. Функция может принимать параметры и возвращать значение.
Программа
выполняется по строкам в порядке их расположения в исходном тексте до тех пор,
пока не встретится вызов какой-нибудь функции. Затем управление передается
строкам этой функции. После выполнения функции управление возвращается той
строке программы, которая следует сразу за вызовом функции.
Есть
прекрасная аналогия для работы программы с функцией. Например, если во время
рисования у вас ломается карандаш, вы прекращаете рисовать и затачиваете его.
После этого вы возвращаетесь к тому месту рисунка, где сломался карандаш. Когда
программа нуждается в выполнении некоторой сервисной операции, вызывается
функция, ответственная за выполнение этой операции, после чего программа
продолжает свою работу с того места, где была вызвана функция. Эта идея
демонстрируется в листинге 1.
Листинг
1 Пример вызова функции listing.cpp


В строках 5—8 определяется функция DemonstrationFunction(). Она выводит на экран сообщение и возвращает управление программе.
Функция 1ла1п() начинается в строке 13, и в строке 15 выводится на экран сообщение, уведомляющее о том, что сейчас управление программой находится в функции main(). После вывода этого сообщения в строке 16 вызывается функция DemonstrationFunction(). В результате этого вызова выполняются команды, содержащиеся в функции DemonstrationFunction(). В данном случае вся функция состоит из одной команды, содержащейся в строке 7, которая выводит другое сообщение. По завершении выполнения функции DemonstrationFunction() (строка 8) управление программой возвращается туда, откуда эта функция была вызвана. В данном случае выполнение программы продолжается со строки 17, в которой функция main() выводит на экран заключительное сообщение.
Функции возвращают либо некоторое реальное значение, либо значение типа void, т.е. ничего не возвращают. Функцию, которая складывает два целых числа и возвращает значение суммы, следует определить как возвращающую целочисленное значение. Функции, которая только выводит сообщение, возвращать нечего, поэтому для нее задается тип возврата void.
Функции состоят из заголовка и тела. Заголовок содержит установки типа возвращаемого значения, имени и параметров функции. Параметры позволяют передавать в функцию значения. Следовательно, если функция предназначена для сложения двух чисел, то эти числа необходимо передать в функцию как параметры. Вот как будет выглядеть заголовок такой функции:
int Suin(int
a, int b)
Параметр — это объявление типа данных значения, передаваемого в функцию. Реальное значение, передаваемое при вызове функции, называется аргументом. Многие программисты используют эти два понятия как синонимы. Другие считают смешение этих терминов признаком непрофессионализма. Возможно, это и так, но в данной книге эти термины взаимозаменяемы.
Тело функции начинается открывающей фигурной скобкой и содержит ряд строк (хотя тело функции может быть даже нулевым), за которыми следует закрывающая фигурная скобка. Назначение функции определяется содержащимися в ней строками программного кода. Функция может возвращать значение в программу с помощью оператора возврата (return). Этот оператор также означает выход из функции. Если не поместить в функцию оператор возврата, то по завершении функции автоматически возвращается значение типа void. Значение, возвращаемое функцией, должно иметь тип, объявленный в заголовке функции.
В листинге 2 демонстрируется функция, которая принимает два целочисленных параметра и возвращает целочисленное значение. Не беспокойтесь пока насчет синтаксиса или особенностей работы с целыми значениями (например, int x).
Листинг
2 Пример использования
простои функции func .
срр


Функция Add() определена в строке 2. Она принимает два целочисленных параметра и возвращает целочисленное значение. Сама же программа начинается в строке 9, выводя на экран первое сообщение. Затем пользователю предлагается ввести два числа (строки 13—15). Пользователь вводит числа, разделяя их пробелом, а затем нажимает клавишу <Enter>. В строке 17 функция main() передает функции Add () в качестве аргументов два числа, введенные пользователем.
Управление программой переходит к функции Add(), которая начинается в строке 2. Параметры а и b выводятся на экран, а затем складываются. Результат функции возвращается в строке 6, и на этом функция завершает свою работу.
Функцию можно вызвать через указатель на нее. Для этого объявляется указатель соответствующего типа и ему с помощью операции взятия адреса присваивается адрес функции:
void f(int a ){ /* j */ } // определение функции
void (*pf)(int); // указатель на функцию
pf =&f ; // указателю присваивается адрес
функции
//
(можно написать pf = f;)
pf(10); // функция f
вызывается через указатель pf
// (можно написать (*pf(10) )
Для того чтобы сделать программу легко читаемой, при описании указателей на функции используют переименование типов (typedef). Можно объявлять массивы указателей на функции (это может быть полезно, например,при реализации меню):
// Описание
типа PF как указателя
// на
функцию с одним параметром типа int :
typedef void (*PF)(int);
// Описание и инициализация массива указателей:
PF menu[]= {&new. &open.
&save}:
menu[l](10); // Вызов функции open
Здесь new, open и save — имена функций, которые должны быть объявлены ранее.
Указатели на функции передаются в подпрограмму таким же образом, как и параметры других типов:


Тип указателя и тип функции, которая вызывается посредством этого указателя, должны совпадать в точности.
Чтобы упростить вызов функции, в ее заголовке можно указать значения параметров по умолчанию. Эти параметры должны быть последними в списке и могут опускаться при вызове функции. Если при вызове параметр опущен, должны быть опущены и все параметры, стоящие за ним. В качестве значений параметров по умолчанию могут использоваться константы, глобальные переменные и выражения:
int f(int a. int b= 0);
void f1(int. int = 100. char* =0); /* обратите внимание на пробел между * и
= (без него получилась бы операция сложного присваивания *=) */
void err(int errValue = еrrnо); // ermo - глобальная переменная
f(100):
f(a. 1); // варианты вызова функции f
f1(a); f1(a. 10); f1(a. 10. "Vasia"); // варианты вызова функции f1
f1(a.."Vasia")
//неверно!