Функция — это именованный фрагмент программы, который выполняет некоторую задачу.
Функции позволяют:
В C++ функция должна быть объявлена (или определена) до места своего первого вызова.
На практике это означает, что все пользовательские функции обычно пишут до функции int main().
Простейший пример функции:
#include <iostream>
using namespace std;
int sum(int a, int b) {
return a + b;
}
int main() {
int x = sum(3, 5);
cout << x;
}
Здесь:
sum объявлена до main;main она вызывается как обычная команда: sum(3, 5).При вызове функции:
return управление возвращается в место вызова.Сигнатура функции — это набор характеристик, по которым компилятор отличает одну функцию от другой.
В сигнатуру входят:
Тип возвращаемого значения не входит в сигнатуру.
Если функция ничего не должна возвращать, в качестве типа возвращаемого значения указывается void.
void print_sum(int a, int b) {
cout << a + b;
}
Если же функция объявлена, например, с типом int, но из неё ничего не возвращается, это является ошибкой.
int f() {
int x = 5;
// return отсутствует — ошибка
}
В C++ можно иметь несколько функций с одинаковым именем, если их сигнатуры различаются.
Пример:
int min(int a, int b) {
if (a < b) {
return a;
} else {
return b;
}
}
int min(int a, int b, int c) {
return min(min(a, b), c);
}
Здесь:
min(int, int) — минимум из двух чисел;min(int, int, int) — минимум из трёх чисел;Так написать нельзя:
long long min(int a, int b) {
if (a < b) {
return a;
} else {
return b;
}
}
Почему?
Потому что сигнатура у неё такая же, как у int min(int, int) — имя и аргументы совпадают, а возвращаемый тип не учитывается.
Если аргумент передаётся по значению, то в функцию попадает копия переменной.
void abs_value(int x) {
if (x < 0) {
x = -x;
}
}
int main() {
int a = -5;
abs_value(a);
cout << a; // выведет -5
}
Здесь:
x — копия a;x не влияют на a.Если аргумент передаётся по ссылке, функция работает с исходной переменной.
void abs_value(int& x) {
if (x < 0) {
x = -x;
}
}
int main() {
int a = -5;
abs_value(a);
cout << a; // выведет 5
}
Здесь:
x — это другое имя для a;main.Передача по ссылке используется, когда:
Локальные переменные объявляются внутри функции и:
void f() {
int x = 10; // локальная переменная
}
Каждая функция имеет свои собственные локальные переменные.
Функции не делят локальные переменные между собой.
Глобальные переменные объявляются вне всех функций и доступны везде.
int N = 100;
void f() {
cout << N;
}
Использование глобальных переменных считается плохой практикой, потому что:
Допустимое и рекомендуемое применение — глобальные константы:
const int MAXN = 100000;
Рекурсия — это ситуация, когда функция вызывает саму себя.
Любая рекурсивная функция должна иметь:
void print_up(int n) {
if (n == 0) {
return;
}
print_up(n - 1);
cout << n << " ";
}
Работа функции:
print_up(n - 1);n.Результат: 1 2 3 ... n
void print_down(int n) {
if (n == 0) {
return;
}
cout << n << " ";
print_down(n - 1);
}
Результат: n n-1 ... 1
Поэтому рекурсию важно знать и понимать, даже если не всегда использовать.