- Писать функцию с типом результата, параметрами и
returnи вызывать её - Перегружать функции и использовать аргументы по умолчанию
- Объяснять разницу между передачей по значению и по ссылке
- Передавать большие объекты по
const-ссылке
Представь, что в игре ты в десяти местах считаешь расстояние между двумя персонажами и каждый раз копируешь одни и те же три строки. Найдёшь ошибку в формуле — придётся исправлять её в десяти местах! Эту проблему решают функции: код пишется один раз, получает имя и вызывается столько раз, сколько нужно. Одну функцию ты уже знаешь — это main.
Определение и вызов функции
Определение функции в C++ состоит из четырёх частей: тип возвращаемого значения, имя, параметры в скобках и тело в фигурных скобках. return возвращает результат в место вызова. У функции, которая ничего не возвращает, тип void.
#include <iostream>
#include <string>
int square(int x) {
return x * x;
}
void greet(std::string name) {
std::cout << "Hello, " << name << "!\n";
}
int main() {
greet("Leyla");
int s = square(7);
std::cout << "7 squared is " << s << '\n';
std::cout << square(3) + square(4) << '\n';
return 0;
}Hello, Leyla! 7 squared is 49 25
Параметр — переменная, указанная в определении функции (int x). Аргумент — конкретное значение, которое передаётся ей при вызове (7 в вызове square(7)).
Компилятор читает файл сверху вниз, поэтому функцию нужно хотя бы объявить до её вызова. Если хочешь написать функцию после main, укажи вверху её прототип — заголовок без тела:
#include <iostream>
int cube(int x); // declaration (prototype)
int main() {
std::cout << cube(3) << '\n';
return 0;
}
int cube(int x) { // definition
return x * x * x;
}27
Перегрузка функций
В C++ может быть несколько функций с одинаковым именем, если у них различается количество или типы параметров. Это называется перегрузкой. Компилятор сам выбирает подходящий вариант по аргументам вызова. Выражение a > b ? a : b в примере — тернарный оператор: «если условие истинно, то a, иначе b».
#include <iostream>
int maxOf(int a, int b) {
return a > b ? a : b;
}
double maxOf(double a, double b) {
return a > b ? a : b;
}
int maxOf(int a, int b, int c) {
return maxOf(maxOf(a, b), c);
}
int main() {
std::cout << maxOf(3, 8) << '\n';
std::cout << maxOf(2.5, 1.5) << '\n';
std::cout << maxOf(4, 9, 6) << '\n';
return 0;
}8 2.5 9
Аргументы по умолчанию
Параметру можно задать значение по умолчанию: если аргумент при вызове не указан, берётся оно. Правило такое: параметры со значениями по умолчанию должны стоять в конце списка.
#include <iostream>
#include <string>
void printPrice(std::string item, int price, std::string currency = "AZN") {
std::cout << item << ": " << price << ' ' << currency << '\n';
}
int main() {
printPrice("Book", 12);
printPrice("Headphones", 40, "USD");
return 0;
}Book: 12 AZN Headphones: 40 USD
Передача по значению и по ссылке
По умолчанию C++ передаёт копию аргумента: даже если функция изменит параметр, переменная у вызывающей стороны останется прежней. Если после типа параметра написать &, параметр станет ссылкой — другим именем исходной переменной. Тогда изменения внутри функции коснутся и оригинала.
#include <iostream>
void addBonusCopy(int points) {
points += 10;
}
void addBonus(int& points) {
points += 10;
}
int main() {
int score = 50;
addBonusCopy(score);
std::cout << "After copy: " << score << '\n';
addBonus(score);
std::cout << "After reference: " << score << '\n';
return 0;
}After copy: 50 After reference: 60
Ссылки особенно полезны в двух случаях: когда функция должна изменить несколько переменных (например, поменять два значения местами) и когда ей нужно прочитать большой объект без копирования. Во втором случае пишут const std::string&: копия не создаётся, а функция не может изменить текст.
#include <iostream>
#include <string>
void swapValues(int& a, int& b) {
int temp = a;
a = b;
b = temp;
}
void printBanner(const std::string& text) {
std::cout << "*** " << text << " ***\n";
}
int main() {
int x = 3;
int y = 8;
swapValues(x, y);
std::cout << "x = " << x << ", y = " << y << '\n';
printBanner("Game over");
return 0;
}x = 8, y = 3 *** Game over ***
| Способ | Запись | Меняется ли оригинал? | Когда использовать |
|---|---|---|---|
| по значению | int x | нет | маленькие типы: int, double, char |
| по ссылке | int& x | да | функция должна изменить переменную |
по const-ссылке | const std::string& s | нет | большие объекты, которые только читаются |
Главное
- Функция определяется как
тип имя(параметры) { ... };voidничего не возвращает. - Функцию нужно объявить до вызова — при необходимости напиши прототип.
- Перегрузка — функции с одинаковым именем, но разными параметрами; нужный вариант выбирает компилятор.
- Параметры со значениями по умолчанию стоят в конце списка.
- Передача по значению создаёт копию,
&работает с оригиналом, аconst &позволяет безопасно читать без копирования.
Проверь себя
Вопросов: 10. Каждый правильный ответ приносит XP.