Определение и описание функций
Если переменные и константы хранят состояние программы, то функции определяют ее действия.
Формальное определение функции выглядит следующим образом:
1
2
3
4
тип имя_функции(параметры)
{
выполняемые_выражения
}
Первая строка представляет заголовок или сигнатуру функции. Вначале указывается возвращаемый тип функции. Если функция не возвращает никакого значения, то используется тип void.
Затем идет имя функции, которое представляет произвольный идентификатор, к которому применяются те же правила, что и к именованию переменных.
После имени функции в скобках идет перечисление параметров. Функция может не иметь параметров, в этом случае указываются пустые скобки.
После заголовка функции в фигурных скобках идет тело функции, которое содержит выполняемые выражения.
Для возвращения результата функция применяет оператор return, которые имеет следующие способы использования:
1
2
return;
return выражение;
Первая форма может использоваться в тех функциях, которые не возвращают никакого значения, то есть имеют в качестве возвращаемого типа void.
Вторая форма применяется, если функция имеет в качестве возвращаемого типа любой тип, кроме void. Выражение после оператора return представляет возвращаемое значение.
Для выполнения функции ее необходимо вызвать. Вызов функции осуществляется в форме:
1
имя_функции(аргументы);
После имени функции указываются скобки, в которых перечисляются аргументы - значения для параметров функции.
Определим простейшую функцию:
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
void hello()
{
printf("Hello!\n");
}
int main(void)
{
hello();
hello();
return 0;
}
Здесь определена функция hello, которая просто выводит на консоль строку "Hello!". Эта функция имеет тип void, то есть фактически она ничего не возвращает.
В любой программе должна быть как минимум одна функция, которая имеет фиксированное имя main(). Именно с функции main начинается выполнение. Поэтому если мы хотим выполнить функцию hello, то нам надо ее вызвать в функции main.
Также стоит отметить, что функция main в качестве возвращаемого типа имеет тип int, поэтому она в обязательном порядке должна возвратить какое-либо значение типа int с помощью оператора return. Поэтому в конце тела функции стоит вызов return 0;. Согласно условностям в качестве индикатора успешного выполнения функция main возвращает число 0.
В данном случае функция hello вызывается два раза. В этом и состоит прелесть функция: мы можем вынести некоторое общее действие, которое может состоять из нескольких строк, в отдельную функцию и затем вызывать многократно в различных местах программы. В итоге программа два раза выведет строку "Hello".
Прототип или описание функции
Здесь стоит учесть важный момент - компилятор должен знать о функции до ее вызова. Поэтому вызов функции должен происходить после ее определения, как в случае выше. В некоторых языках это не имеет значение, но в языке Си это играет большую роль. И если, к примеру, мы сначала вызовем, а потом определим функцию, то мы получим ошибку на этапе компиляции, как в следующем случае:
1
2
3
4
5
6
7
8
9
10
11
int main(void)
{
hello();
hello();
return 0;
}
void hello()
{
printf("Hello!\n");
}
Но есть и другой способ, который заключается в использовании описания функции. Описание функции еще называют прототипом. Формальное определение прототипа выглядит следующим образом:
1
тип имя_функции(параметры);
Фактически это заголовок функции. То есть для функции hello прототип будет выглядеть следующим образом:
1
void hello();
Применим прототип функции:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
// описание
void hello();
int main(void)
{
hello();
hello();
return 0;
}
// определение
void hello()
{
printf("Hello!\n");
}
В данном случае несмотря на то, что определение функции идет после ее вызова, но так как ее описание идет до вызова, то компилятор уже будет знать о функции hello, и никаких проблем в работе программы не возникнет.