0 added
0 removed
Original
2026-01-01
Modified
2026-02-21
1
<p><a>#Руководства</a></p>
1
<p><a>#Руководства</a></p>
2
<ul><li>5 июн 2020</li>
2
<ul><li>5 июн 2020</li>
3
<li>0</li>
3
<li>0</li>
4
</ul><p>Разбираемся, как функции помогают сократить код и сделать программу полезнее.</p>
4
</ul><p>Разбираемся, как функции помогают сократить код и сделать программу полезнее.</p>
5
<p> vlada_maestro / shutterstock</p>
5
<p> vlada_maestro / shutterstock</p>
6
<p>Пишет о программировании, в свободное время создаёт игры. Мечтает открыть свою студию и выпускать ламповые RPG.</p>
6
<p>Пишет о программировании, в свободное время создаёт игры. Мечтает открыть свою студию и выпускать ламповые RPG.</p>
7
<p>Это пятая часть из серии статей<strong>"Глубокое погружение в C++"</strong>. В <a>прошлый раз</a>мы узнали, как правильно использовать ввод данных и обрабатывать исключения. Сегодня займёмся функциями и процедурами.</p>
7
<p>Это пятая часть из серии статей<strong>"Глубокое погружение в C++"</strong>. В <a>прошлый раз</a>мы узнали, как правильно использовать ввод данных и обрабатывать исключения. Сегодня займёмся функциями и процедурами.</p>
8
<p>Если код нужно использовать несколько раз, то лучше всего его вывести в подпрограмму - функцию или процедуру. Это позволит значительно сократить объём кода. Давайте рассмотрим вот такую программу:</p>
8
<p>Если код нужно использовать несколько раз, то лучше всего его вывести в подпрограмму - функцию или процедуру. Это позволит значительно сократить объём кода. Давайте рассмотрим вот такую программу:</p>
9
int name1 = "John"; int name2 = "James"; int name3 = "Jack"; int name4 = "Ivan"; int name5 = "Igor"; int name6 = "Boris"; std::cout << "Hello, " << name1 << "!\n"; std::cout << "Hello, " << name2 << "!\n"; std::cout << "Hello, " << name3 << "!\n"; std::cout << "Hello, " << name4 << "!\n"; std::cout << "Hello, " << name5 << "!\n"; std::cout << "Hello, " << name6 << "!\n";<p>Программа по очереди приветствует шесть человек. Это относительно небольшой код, но что, если понадобится заменить фразу "Hello, %name%!" на "Hello, %name%! How are you?"? Тогда придётся поменять код в шести местах. А такие сообщения могут выводиться сто или даже тысячу раз.</p>
9
int name1 = "John"; int name2 = "James"; int name3 = "Jack"; int name4 = "Ivan"; int name5 = "Igor"; int name6 = "Boris"; std::cout << "Hello, " << name1 << "!\n"; std::cout << "Hello, " << name2 << "!\n"; std::cout << "Hello, " << name3 << "!\n"; std::cout << "Hello, " << name4 << "!\n"; std::cout << "Hello, " << name5 << "!\n"; std::cout << "Hello, " << name6 << "!\n";<p>Программа по очереди приветствует шесть человек. Это относительно небольшой код, но что, если понадобится заменить фразу "Hello, %name%!" на "Hello, %name%! How are you?"? Тогда придётся поменять код в шести местах. А такие сообщения могут выводиться сто или даже тысячу раз.</p>
10
<p>Подпрограммы как раз и нужны, чтобы избежать таких проблем.</p>
10
<p>Подпрограммы как раз и нужны, чтобы избежать таких проблем.</p>
11
<p>Для удобства любые подпрограммы, в том числе и процедуры, называют функциями.</p>
11
<p>Для удобства любые подпрограммы, в том числе и процедуры, называют функциями.</p>
12
<p>Одну функцию мы с вами уже создавали -<em>main ()</em>. Она работает как точка входа в каждую программу. Другие функции создаются аналогичным образом:</p>
12
<p>Одну функцию мы с вами уже создавали -<em>main ()</em>. Она работает как точка входа в каждую программу. Другие функции создаются аналогичным образом:</p>
13
<p>Вот так это выглядит в коде:</p>
13
<p>Вот так это выглядит в коде:</p>
14
#include <iostream> //Новые функции и процедуры должны создаваться выше функции main() //В круглых скобках указываются аргументы, которые будет принимать функция int sum(int a, int b) { //Используем переданные аргументы, чтобы провести вычисления int result = a + b; //Оператор возврата говорит программе, что функция завершила работу return result; //Всё, что записано после return, не будет выполнено } int main() { //Вызываем функцию с аргументами int result = sum(5, 6); }<p>Функции могут принимать или не принимать аргументы. Но если вы указали, что аргументы всё же нужны, то попытка вызвать функцию без них приведёт к ошибке.</p>
14
#include <iostream> //Новые функции и процедуры должны создаваться выше функции main() //В круглых скобках указываются аргументы, которые будет принимать функция int sum(int a, int b) { //Используем переданные аргументы, чтобы провести вычисления int result = a + b; //Оператор возврата говорит программе, что функция завершила работу return result; //Всё, что записано после return, не будет выполнено } int main() { //Вызываем функцию с аргументами int result = sum(5, 6); }<p>Функции могут принимать или не принимать аргументы. Но если вы указали, что аргументы всё же нужны, то попытка вызвать функцию без них приведёт к ошибке.</p>
15
<p>Если вы указываете какой-либо тип возвращаемых данных, то обязательно должен присутствовать оператор<em>return</em>. Если возвращать значение не нужно, создайте процедуру - укажите тип<em>void</em>.</p>
15
<p>Если вы указываете какой-либо тип возвращаемых данных, то обязательно должен присутствовать оператор<em>return</em>. Если возвращать значение не нужно, создайте процедуру - укажите тип<em>void</em>.</p>
16
#include <iostream> void printHello(std::string name) { std::cout << "Hello, " << name << "!\n"; } int main() { printHello("Igor"); printHello("Boris"); }<p>Вот что выведет такая программа:</p>
16
#include <iostream> void printHello(std::string name) { std::cout << "Hello, " << name << "!\n"; } int main() { printHello("Igor"); printHello("Boris"); }<p>Вот что выведет такая программа:</p>
17
<p>Функция<em>main ()</em>автоматически возвращает значение, поэтому отдельно прописывать<em>return</em>не обязательно. Программа вернёт 0, если она выполнилась успешно, или другое число в зависимости от ошибки.</p>
17
<p>Функция<em>main ()</em>автоматически возвращает значение, поэтому отдельно прописывать<em>return</em>не обязательно. Программа вернёт 0, если она выполнилась успешно, или другое число в зависимости от ошибки.</p>
18
<p>Всё, что происходит в функции, в ней же и остаётся. То есть функции могут работать только с теми значениями, которые в них передали:</p>
18
<p>Всё, что происходит в функции, в ней же и остаётся. То есть функции могут работать только с теми значениями, которые в них передали:</p>
19
#include <iostream> void printHello() { //Переменная name объявлена в другой функции, поэтому у printHello() нет к ней доступа //Запуск такого кода приведёт к ошибке std::cout << "Hello, " << name << "!\n"; } int main() { std::string name = "Igor"; printHello(); }<p>Если переменная создаётся внутри какого-либо блока {}, то она будет доступна только в этом и во всех вложенных блоках; такие переменные называются<strong>локальными.</strong></p>
19
#include <iostream> void printHello() { //Переменная name объявлена в другой функции, поэтому у printHello() нет к ней доступа //Запуск такого кода приведёт к ошибке std::cout << "Hello, " << name << "!\n"; } int main() { std::string name = "Igor"; printHello(); }<p>Если переменная создаётся внутри какого-либо блока {}, то она будет доступна только в этом и во всех вложенных блоках; такие переменные называются<strong>локальными.</strong></p>
20
<p>Если вы хотите, чтобы какая-нибудь переменная была доступна везде, то её нужно объявить за пределами каких-либо блоков; такие переменные называются<strong>глобальными:</strong></p>
20
<p>Если вы хотите, чтобы какая-нибудь переменная была доступна везде, то её нужно объявить за пределами каких-либо блоков; такие переменные называются<strong>глобальными:</strong></p>
21
#include <iostream> //Глобальные переменные создаются вне функций std::string name; void printHello() { std::cout << "Hello, " << name << "!\n"; } int main() { name = "Igor"; printHello(); }<p>Однако использовать глобальные переменные не рекомендуется, потому что вам будет сложно отслеживать изменения и влиять на результат работы программы. Единственное исключение - это константы, которые нужно делать глобальными, потому что они не меняются.</p>
21
#include <iostream> //Глобальные переменные создаются вне функций std::string name; void printHello() { std::cout << "Hello, " << name << "!\n"; } int main() { name = "Igor"; printHello(); }<p>Однако использовать глобальные переменные не рекомендуется, потому что вам будет сложно отслеживать изменения и влиять на результат работы программы. Единственное исключение - это константы, которые нужно делать глобальными, потому что они не меняются.</p>
22
<p>Рассмотрим, что происходит, когда вы передаёте аргумент в функцию. Допустим, есть вот такой код:</p>
22
<p>Рассмотрим, что происходит, когда вы передаёте аргумент в функцию. Допустим, есть вот такой код:</p>
23
#include <iostream> void sum(int a) { a = a + 500; } int main() { int a = 5; sum(a); std::cout << a << "\n"; }<p>Можно подумать, что в результате программы мы увидим число 505, но это неверно. Дело в том, что функции в качестве аргументов принимают не сами переменные, а их значения. То есть в <em>sum ()</em>попала не ячейка памяти, а число 5, которое находилось в этой ячейке. Учитывайте это, когда пишете программы.</p>
23
#include <iostream> void sum(int a) { a = a + 500; } int main() { int a = 5; sum(a); std::cout << a << "\n"; }<p>Можно подумать, что в результате программы мы увидим число 505, но это неверно. Дело в том, что функции в качестве аргументов принимают не сами переменные, а их значения. То есть в <em>sum ()</em>попала не ячейка памяти, а число 5, которое находилось в этой ячейке. Учитывайте это, когда пишете программы.</p>
24
<p>Это касается только примитивных типов данных. Ссылочные типы ведут себя иначе.</p>
24
<p>Это касается только примитивных типов данных. Ссылочные типы ведут себя иначе.</p>
25
<p><a>Рекурсия</a> - это ситуация, когда объект является частью самого себя<em>(не путать с <a>фракталом</a>)</em>. В программировании это проявляется в одной интересной особенности функций - они могут вызывать сами себя.</p>
25
<p><a>Рекурсия</a> - это ситуация, когда объект является частью самого себя<em>(не путать с <a>фракталом</a>)</em>. В программировании это проявляется в одной интересной особенности функций - они могут вызывать сами себя.</p>
26
<p><em>Чтобы понять, что такое рекурсия, нужно понять, что такое рекурсия</em></p>
26
<p><em>Чтобы понять, что такое рекурсия, нужно понять, что такое рекурсия</em></p>
27
<p>Чаще всего рекурсия объясняется на примере<a>факториалов</a><em>(не путать с фракталами):</em></p>
27
<p>Чаще всего рекурсия объясняется на примере<a>факториалов</a><em>(не путать с фракталами):</em></p>
28
#include <iostream> int f(int n) { if(n < 0) { return 0; } else if (n == 0) { return 1; } else { return n * f(n - 1); } } void printFactorial(int n) { int a = f(n); std::cout << n << "! = " << a << "\n"; } int main() { printFactorial(1); printFactorial(2); printFactorial(3); printFactorial(4); printFactorial(5); printFactorial(6); printFactorial(7); printFactorial(8); printFactorial(9); printFactorial(10); }<p>Вот факториалы чисел от 1 до 10:</p>
28
#include <iostream> int f(int n) { if(n < 0) { return 0; } else if (n == 0) { return 1; } else { return n * f(n - 1); } } void printFactorial(int n) { int a = f(n); std::cout << n << "! = " << a << "\n"; } int main() { printFactorial(1); printFactorial(2); printFactorial(3); printFactorial(4); printFactorial(5); printFactorial(6); printFactorial(7); printFactorial(8); printFactorial(9); printFactorial(10); }<p>Вот факториалы чисел от 1 до 10:</p>
29
<p>Важно! Прописывайте условия выхода из рекурсии, иначе программа попадёт в бесконечный цикл и сильно нагрузит компьютер.</p>
29
<p>Важно! Прописывайте условия выхода из рекурсии, иначе программа попадёт в бесконечный цикл и сильно нагрузит компьютер.</p>
30
<p>На практике применение этой особенности можно увидеть при рекурсивном удалении папок. Функция удаления должна работать так:</p>
30
<p>На практике применение этой особенности можно увидеть при рекурсивном удалении папок. Функция удаления должна работать так:</p>
31
<ol><li>Сканирует указанную папку.</li>
31
<ol><li>Сканирует указанную папку.</li>
32
<li>Удаляет все файлы из этой папки.</li>
32
<li>Удаляет все файлы из этой папки.</li>
33
<li>Сканирует папки внутри этой папки и выполняет предыдущие шаги для каждой из них.</li>
33
<li>Сканирует папки внутри этой папки и выполняет предыдущие шаги для каждой из них.</li>
34
</ol><p>Разрабатывая программы, вы постоянно будете работать с функциями, поэтому важно научиться делать их максимально полезными. Вот несколько рекомендаций:</p>
34
</ol><p>Разрабатывая программы, вы постоянно будете работать с функциями, поэтому важно научиться делать их максимально полезными. Вот несколько рекомендаций:</p>
35
<ol><li>Называйте их так, чтобы было сразу понятно, что они делают. При этом лучше использовать повелительное наклонение, то есть<em>напечатайФакториал ()</em>, а не <em>печатьФакториала ()</em>.</li>
35
<ol><li>Называйте их так, чтобы было сразу понятно, что они делают. При этом лучше использовать повелительное наклонение, то есть<em>напечатайФакториал ()</em>, а не <em>печатьФакториала ()</em>.</li>
36
<li>Делайте функции как можно меньше и универсальнее.</li>
36
<li>Делайте функции как можно меньше и универсальнее.</li>
37
<li>Если есть вероятность, что часть кода может повториться несколько раз, то сразу выносите её в отдельную функцию.</li>
37
<li>Если есть вероятность, что часть кода может повториться несколько раз, то сразу выносите её в отдельную функцию.</li>
38
</ol><p>И старайтесь как можно больше практиковаться, чтобы закрепить новые знания. В этой серии статей описываются базовые возможности программирования, которые пригодятся вам на протяжении всей карьеры. В следующем материале мы разберёмся, как упростить повторяющийся код с помощью циклов.</p>
38
</ol><p>И старайтесь как можно больше практиковаться, чтобы закрепить новые знания. В этой серии статей описываются базовые возможности программирования, которые пригодятся вам на протяжении всей карьеры. В следующем материале мы разберёмся, как упростить повторяющийся код с помощью циклов.</p>
39
<a><b>Бесплатный курс по Python ➞</b>Мини-курс для новичков и для опытных кодеров. 4 крутых проекта в портфолио, живое общение со спикером. Кликните и узнайте, чему можно научиться на курсе. Смотреть программу</a>
39
<a><b>Бесплатный курс по Python ➞</b>Мини-курс для новичков и для опытных кодеров. 4 крутых проекта в портфолио, живое общение со спикером. Кликните и узнайте, чему можно научиться на курсе. Смотреть программу</a>