Подпрограмма – независимая часть программы, выполняющая логически завершенное действие. При структурном программировании задача разбивается на отдельные этапы решения, каждый из которых оформляется в виде отдельной подпрограммы. Порядок выполнения подпрограмм указывается в программном коде основной программы.
В языке С++ все подпрограммы называются функциями и представляют собой совокупность объявлений и операторов, предназначенных для реализации определенного этапа решения задачи. При этом функция может возвращать значение, а может быть предназначена для выполнения действий.
В С++ выделяют следующие виды функций:
● стандартные (библиотечные) – их объявление содержится в файлах формата *.h (например, для математических функций – math.h), а описание реализации – в файлах формата *.lib (для математических функций – math.lib);
● пользовательские – не входят в стандартные библиотеки и разрабатываются при решении конкретных задач.
В любой программе на С++ должна быть функция с именем main (главная функция), с которой начинается выполнение этой программы.
С использованием пользовательских функций связано три понятия: определение, объявление и вызов функции.
Определение функциивключает задание следующих ее характеристик:
● тип возвращаемого значения или указание на отсутствие значения (void);
● имя (идентификатор);
● список формальных параметров и их типов – переменных, используемых в качестве аргументов;
● тело функции – объявления переменных и операторов, определяющих действие функции.
Переменные, которые используются внутри данной функции, называются локальными. Память для них выделяется в стеке, поэтому после окончания работы функции они удаляются из памяти.
Глобальные переменные – это переменные, описанные вне функций. Они видны во всех функциях, где нет локальных переменных с такими именами. Правилами хорошего стиля программирования не рекомендуется давать одинаковые имена локальным и глобальным переменным. Однако, если локальная и глобальная переменные объявлены с одинаковыми именами, то внутри функции будет обращение к локальной переменной.
спецификатор_класса_памяти – необязательный параметр, который задает класс памяти функции (static или extern), а также дополнительный модификатор. По умолчанию класс определяется как extern (внешний).
спецификатор_типа – необязательный параметр, который задает тип возвращаемого функцией значения и может быть любым типом. По умолчанию спецификатор типа определяется как int. Для функций, не возвращающих значение, должен использоваться тип void, указывающий на отсутствие возвращаемого значения.
имя_функции – идентификатор, указывающий на область памяти, в которую будет возвращено значение функции (для типа void значение не определяется). Главной функции должно соответствовать имя main.
список_формальных_параметров – последовательность объявлений формальных параметров, разделенная запятыми. Формальные параметры – это переменные, используемые внутри тела функции и получающие значение при вызове функции путем копирования в них значений соответствующих фактических параметров. Список формальных параметров может заканчиваться запятой (,) или запятой с многоточием (,...) – это означает, что число аргументов функции переменно. Предполагается, что функция имеет по крайней мере столько обязательных аргументов, сколько формальных параметров задано перед последней запятой в списке параметров. Такой функции может быть передано большее число аргументов, но над дополнительными аргументами не проводится контроль типов.
Тело_функции – это составной оператор, содержащий операторы, определяющие действие функции. Тело функции может содержать необязательный оператор return – оператор возврата в вызывающую функцию. В теле пользовательской функции не может содержаться описаний других пользовательских функций.
Примеры определения функции:
//Функция вычисления логарифма от числа а по основанию b
float logab(float a, float b) // заголовок функции:
{ // начало тела функции
return log(a)/log(b);
} // окончание тела функции
Пояснение к примеру
Заголовок функции содержит:
float – тип значения функции;
logab – имя функции;
float a, float b – тип и имя формальных параметров.
Тело функции содержит:
return log(a)/log(b) – оператор возвращения значения выражения в качестве значения функции.
//Функция определения количества делителей натурального n
int numdel(int n) // заголовок функции:
{ // начало тела функции
int i, k=1;
for (i=1; i<=n/2; i++)
if (n%i==0) k++;
return k;
} // окончание тела функции
Пояснение к примеру
Заголовок функции содержит:
int – тип значения функции;
numdel – имя функции;
int n – тип и имя формального параметра.
Тело функции содержит:
· реализацию алгоритма подсчета количества делителей натурального числа n;
· return k – оператор возвращения значения переменной k в качестве значения функции.
Объявление функции (прототип, заголовок) – предшествует определению функции и задается именем функции, типом возвращаемого значения и списком передаваемых параметров. Функция объявляется после раздела глобальных объявлений. Использование прототипов функций предусмотрено хорошим стилем программирования, а также реализует возможность включения функций пользователя в отдельный файл.
Синтаксис объявления функции (прототипа):
[спецификатор_типа] имя_функции
([список_формальных_параметров]);
Вызов функциипроисходит следующим образом:
· в точке вызова функции происходит обращение вида
имя_функции ([список_выражений])
· вычисляются значения из списка выражений, которые называются фактическими значениями параметров,
· фактические значения параметров передаются в качестве значений формальных параметров в порядке их следования в описании, поэтому должно соблюдаться соответствие типов и числа параметров,
· управление передается на первый оператор тела функции,
· после выполнения тела функции происходит возвращение в точку вызова функции; при этом или возвращается значение определенного типа (при наличии return), или функция не передает никаких значений.
Пример 1. На отрезке [a,b] с натуральными границами найдите все простые числа (a < b).
/*Программа вывода всех простых чисел на данном отрезке [a,b]*/