2.5 – Почему функции полезны, и как эффективно их использовать

Добавлено 10 апреля 2021 в 14:40

Теперь, когда мы рассмотрели, что такое функции и некоторые из их основных возможностей, давайте подробнее рассмотрим, почему они полезны.

Зачем использовать функции?

Программисты-новички часто спрашивают: «А нельзя ли просто поместить весь код в функцию main?» Для простых программ это возможно. Однако функции предоставляют ряд преимуществ, которые делают их чрезвычайно полезными в программах нетривиальной длины или сложности.

  • Организация. По мере того, как программы становятся всё сложнее, размещение всего кода внутри функции main() становится всё более сложным. Функция почти похожа на мини-программу, которую мы можем написать отдельно от основной программы, не думая об остальной части, пока ее пишем. Это позволяет нам разбивать сложную программу на более мелкие, более управляемые фрагменты, что снижает общую сложность нашей программы.
  • Возможность повторного использования – после того, как функция написана, ее можно вызывать в программе несколько раз. Это позволяет избежать дублирования кода (принцип DRY, «не повторяйтесь») и минимизирует вероятность ошибок копирования/вставки. Функции также могут использоваться в других программах, что сокращает объем кода, который приходится каждый раз писать с нуля (и повторно тестировать).
  • Тестирование. Поскольку функции уменьшают избыточность кода, то, в первую очередь, меньше кода нужно тестировать. Кроме того, поскольку функции являются самодостаточными, после того, как мы проверили функцию, чтобы убедиться, что она работает, нам не нужно тестировать ее снова, пока мы ее не изменим. Это уменьшает объем кода, который мы должны тестировать за один раз, что значительно упрощает поиск ошибок (или, в первую очередь, их предотвращение).
  • Расширяемость. Когда нам нужно расширить нашу программу для обработки случая, который она не обрабатывала раньше, функции позволяют нам вносить изменения в одном месте, и это изменение вступает в силу каждый раз при вызове функции.
  • Абстракция. Чтобы использовать функцию, вам нужно знать только ее имя, входные и выходные данные, и где она находится. Вам не нужно знать, как она работает, или от какого еще кода зависит ее использование. Это снижает объем знаний, необходимых для использования чужого кода (включая всё, что есть в стандартной библиотеке).

Хотя это так не выглядит, но каждый раз, когда вы используете operator<< или operator>> для ввода или вывода, вы используете функцию, предоставляемую стандартной библиотекой, которая соответствует всем вышеперечисленным критериям.

Эффективное использование функций

Одна из самых больших проблем, с которыми сталкиваются программисты-новички (помимо изучения языка), – это понимание того, когда и как эффективно использовать функции. Вот несколько основных рекомендаций по написанию функций:

  • Инструкции, которые появляются в программе более одного раза, обычно должны быть преобразованы в функцию. Например, если мы читаем пользовательские входные данные несколько раз одним и тем же способом, это отличный кандидат на роль функции. Если мы выводим что-то одним и тем же способом несколько раз, это тоже отличный кандидат на роль функции.
  • Код с четко определенным набором входных и выходных данных является хорошим кандидатом на роль функции, особенно если он сложен. Например, если у нас есть список элементов, которые мы хотим отсортировать, код для сортировки будет отличной функцией, даже если это будет сделано только один раз. Входными данными является несортированный список, а выходными данными – отсортированный список.
  • Функция обычно должна выполнять одну (и только одну) задачу.
  • Когда функция становится слишком длинной, сложной или трудной для понимания, ее можно разделить на несколько подфункций. Это называется рефакторингом. Мы подробнее поговорим о рефакторинге в уроке «3.10 – Поиск проблем до того, как они станут проблемами».

Обычно при изучении C++ вы пишете множество программ, которые включают 3 подзадачи:

  1. чтение входных данных от пользователя;
  2. расчет значения на основе входных данных;
  3. печать рассчитанного значения.

Для тривиальных программ (например, менее 20 строк кода) часть или всё это можно сделать в функции main. Однако для более длинных программ (или просто для практики) каждая из этих подзадач является хорошим кандидатом для реализации отдельной функции.

Программисты-новички часто объединяют вычисление значения и печать вычисленного значения в одной функции. Однако это нарушает эмпирическое правило «одной задачи» для функций. Функция, которая вычисляет значение, должна возвращать значение вызывающей стороне и позволять вызывающей стороне решать, что делать с вычисленным значением (например, вызывать другую функцию для печати значения).

Теги

C++ / CppLearnCppДля начинающихОбучениеПрограммирование

На сайте работает сервис комментирования DISQUS, который позволяет вам оставлять комментарии на множестве сайтов, имея лишь один аккаунт на Disqus.com.

В случае комментирования в качестве гостя (без регистрации на disqus.com) для публикации комментария требуется время на премодерацию.