Локальные переменные
Внутри функции можно создавать переменные, как и в main. Но такая переменная существует только внутри функции: она создаётся, когда функция выполняется, и исчезает, когда функция заканчивается. За пределами функции C++ о ней не знает:
#include <iostream>
#include <string>
void sayHello() {
std::string greeting = "Привет!";
std::cout << greeting << std::endl;
}
int main() {
sayHello();
std::cout << greeting << std::endl;
return 0;
}Программа не компилируется:
main.cpp:11:18: error: use of undeclared identifier 'greeting'
11 | std::cout << greeting << std::endl;
| ^~~~~~~~
1 error generated.В строке 11 main пытается вывести переменную greeting, которая существует только внутри функции sayHello. С параметрами то же самое: они существуют только внутри своей функции.
Часть программы, где существует переменная, называется её областью видимости. Переменная, созданная внутри функции, локальная: она принадлежит только этой функции. Это относится и к main, потому что она тоже функция. Поэтому другие функции не видят переменных main:
#include <iostream>
#include <string>
void printLabel(std::string product) {
std::cout << shopName << ": " << product << std::endl;
}
int main() {
std::string shopName = "Четыре лапы";
printLabel("корм для собак");
return 0;
}Эта программа не компилируется. Ошибка use of undeclared identifier 'shopName' находится в строке 5, внутри функции, которая не знает переменную из main. Когда функции нужно значение из main, передайте его как аргумент: добавьте функции параметр std::string shop и вызовите её как printLabel(shopName, "корм для собак"). (Переменные, созданные вне всех функций, были бы видны всем функциям, но на этом курсе мы их не используем. В длинной программе трудно уследить, какая функция их изменила.)
У каждого блока в фигурных скобках своя область видимости. Переменная, созданная внутри if или цикла, существует только до своей }, а переменная i из for (int i = 0; ...) существует только в цикле.
Чем полезно, что локальные переменные остаются внутри своих функций?
- Функции не мешают друг другу. В двух функциях может быть по переменной
total, и это две разные переменные: изменение одной не меняет другую. - Чтобы пользоваться функцией, достаточно знать, что ей дать (аргументы) и что она отдаёт (возвращаемое значение). Как она устроена внутри — её дело.
- Каждый вызов начинается с чистого листа: переменные функции создаются заново, и от предыдущего вызова ничего не остаётся.
Параметр — тоже локальная переменная. Когда функцию вызывают, параметр получает копию аргумента. Если функция меняет параметр, переменная в main остаётся прежней:
#include <iostream>
void resetScore(int score) {
score = 0;
}
int main() {
int score = 10;
resetScore(score);
std::cout << score << std::endl;
return 0;
}Эта программа выводит:
10Функция присвоила своему параметру score значение 0. Но переменная score в main — другая переменная, у которой лишь то же имя, и она осталась равной 10.
Правило простое: значения попадают в функцию через параметры, а выходят через return. Когда вам нужно значение из функции, не пытайтесь добраться до её переменной. Верните значение и сохраните его там, где вызываете функцию.
Задание
- 1
Программа не компилируется, потому что
totalсуществует только внутри функции. Исправьте это: измените тип возвращаемого значения функции наintи верните из неёtotal. Вmainсохраните результат вызоваtotalPrice(25, 4)в переменнуюbillи выведитеbillвместоtotal. Программа выведет100. - 2
К каждому заказу добавляется доставка. Её цена лежит в переменной
deliveryвmain. Функция её не видит, потому что она локальна дляmain. Добавьте функции третий параметр,deliveryтипаint, прибавьте его к итогу внутри функции и передайте ему переменнуюdeliveryв вызове:totalPrice(25, 4, delivery). Тогда программа выведет105.