С какой целью и как в программах используются функции

В практике программирования часто складываются ситуации, когда одну и ту же группу операторов, реализующих определенную цель, требуется повторить без изменений в нескольких местах программы. Для избавления от столь нерациональной траты времени была предложена концепция подпрограммы. Подпрограмма – именованная, логически законченная группа операторов языка, которую можно вызвать для выполнения любое количество раз из различных мест программы. В языке С++ подпрограммы реализованы в виде функций .

4.1 Общие сведения о функциях. Локальные и глобальные переменные

Алексеев Е.Р., Чеснокова О.В. Самоучитель по программированию на C/C++. 101

. тип имя_n(список_переменных) < тело_функции_n; >int main(список_переменных) < //Тело функции может содержать операторы вызова //функций имя_1, имя_2, . имя_n тело_основной_функции; >Однако допустима и другая форма записи программного кода : директивы компилятора тип имя_1(список_переменных); тип имя_2(список_переменных); . тип имя_n(список_переменных); int main(Список_переменных) < //Тело функции может содержать операторы вызова //функций имя_1, имя_2, . имя_n тело__основной_функции; >тип имя_1(список_переменных) < тело_функции_1; >тип имя_2(список_переменных) < тело_функции_2; >. тип имя_n(список_переменных) < тело_функции_n; >Здесь функции описаны после функции main() , однако до нее перечислены заголовки всех функций. Такого рода опережающие заголовки называют прототипами функций . Прототип указывает компилятору тип данных, возвращаемых функцией, тип переменных, выступающих в роли аргументов и порядок их следования.

Язык Си для начинающих / #6 — Функции в Си

Прототипы используются для проверки правильности вызова функций в основной программе. Имена переменных, указанные в прототипе функции, компилятор игнорирует: //Записи равносильны. int funс(int a,int b); int funс(int ,int); Вызвать функцию можно в любом месте программы. Для вызова функции необходимо указать ее имя и в круглых скобках, через запятую перечислить имена или зна- чения аргументов , если таковые имеются: имя_функции(список_переменных); Рассмотрим пример. Создадим функцию f() , которая не имеет входных значений и не формирует результат. При вызове этой функции на экран выводится строка симво-

Алексеев Е.Р., Чеснокова О.В. Самоучитель по программированию на C/C++. 102
лов «Happy new year, » .
#include
using namespace std;
void f() //Описание функции.
cout
>
int main()
//Вызов функции.
f();
cout
f(); //Вызов функции.
cout
f(); //Вызов функции.
cout
>

Результатом работы программы будут три строки: Happy new year, Students! Happy new year, Teachers! Happy new year, People! Далее приведен пример программы, которая пять раз выводит на экран фразу «Hello World!» . Операция вывода строки символов оформлена в виде функции fun() . Эта функция так же не имеет входных значений и не формирует результат. Вы- зов функции осуществляется в цикле: #include using namespace std; void fun() < cout int main() < for(int i=1;i<=5;fun(),i++); >Если тип возвращаемого значения не void , то функция может входить в состав выражений. Типы и порядок следования переменных в определении и при вызове функции должны совпадать . Для того чтобы функция вернула какое-либо значение, в ней должен быть оператор: return (выражение); Далее приведен пример программы, которая проверяет значение выражения sin 2 ( α )+ cos 2 ( α )= 1 при заданном значении α . Здесь функция radian выполняет перевод градусной меры угла в радианную 26 . #include #include 26 Чтобы найти радианную меру какого-нибудь угла по заданной градусной мере, нужно помножить

23 Функция ЕСЛИ в Excel (IF)

число градусов на , число минут на , число секунд на и
180 180 60 180 60 60

найденные произведения сложить.

Алексеев Е.Р., Чеснокова О.В. Самоучитель по программированию на C/C++. 103

#define PI 3.14159 using namespace std; double radian(int deg, int min, int sec) < return (deg*PI/180+min*PI/180/60+sec*PI/180/60/60);

>
int main()
int DEG,MIN,SEC; double RAD;
//Ввод данных. //Величина угла:
cout
cout //градусы,
cout //минуты,
cout //секунды.
//Величина угла в радианах. //Вызов функции.
RAD=radian(DEG,MIN,SEC);

cout cout Переменные, описанные внутри функции, а так же переменные из списка аргументов, являются локальными . Например, если программа содержит пять разных функций, в каждой из которых описана переменная N, то для С++ это пять различных переменных. Область действия локальной переменной не выходит за рамки функции.

Значения локальных переменных между вызовами одной и той же функции не сохраняются. Переменные, определенные до объявления всех функций и доступные всем функциям, называют глобальными . В функции глобальную переменную можно отличить, если не описана локальная переменная с теми же именем. Глобальные переменные применяют для передачи данных между функциями, но это затрудняет отладку программы. Для обмена данными между функциями используют параметры функций и значения, возвращаемые функциями.

Читайте также:
Что за китайская программа на компьютере и как ее удалить

4.2 Передача параметров в функцию

Обмен информацией между вызываемой и вызывающей функциями осуществляется с помощью механизма передачи параметров . Список_переменных , ука- занный в заголовке функции называется формальными параметрами или просто параметрами функции. Список_переменных в операторе вызова функции это фактиче- ские параметры или аргументы . Механизм передачи параметров обеспечивает замену формальных параметров фактическими параметрами , и позволяет выполнять функцию с различными данными.

Между фактическими параметрами в операторе вызова функции и формальными параметрами в заголовке функции устанавливается взаимно однозначное соответствие. Количество, типы и порядок следования формальных и фактических параметров должны совпадать . Передача параметров выполняется следующим образом. Вычисляются выражения, стоящие на месте фактических параметров. В памяти выделяется место под формальные параметры, в соответствии с их типами. Затем формальным параметрам при-

Источник: studfile.net

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

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

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

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

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

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

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

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

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

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

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

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

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

Источник: radioprog.ru

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

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

20 июн 2016 в 12:24

6 ответов 6

Сортировка: Сброс на вариант по умолчанию

Функции служат структурированию вашей программы.

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

Но если вы хотите сделать код легко читаемым, понятным, поддерживаемым, расширяемым, то вам нужно его структурировать: разделить на осмысленные части, и дать им имя. Это и есть ваши функции.

Заметьте, что вы в любом случае пользуетесь библиотечными функциями, наподобие getchar() : разработчики библиотеки уже структурировали её для вас.

Функции — не единственный метод структурирования программы. Например, ещё одно популярное, более мощное средство структурирования — классы.

Отслеживать
ответ дан 20 июн 2016 в 12:13
206k 27 27 золотых знаков 290 290 серебряных знаков 521 521 бронзовый знак

Есть такое понятие как «декомпозиция», т.е. разделение целого на части. Для элементарных ситуаций разделение не обязательно. Но когда программа становится большой, для того чтобы проще было ей управлять и развивать её, приходится делить на более мелкие сущности, давая им в то же время говорящие имена.

Отслеживать
ответ дан 20 июн 2016 в 12:11
28.4k 10 10 золотых знаков 57 57 серебряных знаков 118 118 бронзовых знаков

+ DRY — don’t repeat yourself — «не повторяй себя» или «не повторяйся». Гораздо удобнее написать имя функции нежели комбинацию из 10 и более команд в 30 различных точках основной программы. А если таких точек ещё больше, и параметры в них должны быть отличные друг от друга — то тут вообще без функций можно сойти с ума. Или упасть без сил после часов беспрерывного набора одного и того же кода с вариациями.

20 июн 2016 в 12:26

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

22 фев 2017 в 20:58

Да все команды можно выполнить в одной функции main() .

Но использование функций позволяет повторно использовать одинаковые блоки исходного кода. Улучшает читаемость исходного кода.

Отслеживать
ответ дан 20 июн 2016 в 12:10
3,020 1 1 золотой знак 11 11 серебряных знаков 20 20 бронзовых знаков

Причин разделения кода на функции несколько.

  1. Повторное использование. Довольно часто требуется многократное использование одной функции в разных частях программы. Было бы крайне не разумно писать один и тот же код повторно. Тем более, что в случае изменений их придется вносить в каждый фрагмент. А если вынести функцию в отдельный файл, то можно использовать ее даже в нескольких проектах.
  2. Читаемость. Читаемость кода очень важная характеристика программы. Даже если программа небольшая и написана одним человеком разделение на функции с понятными именами позволяет довольно быстро понять суть происходящего даже после длительного перерыва работы с кодом. А если код ведут несколько программистов, то читаемость кода очень сильно влияет на скорость и качество разработки, и как следствие, на итоговый результат.
  3. Качество, отладка, тестирование и т.д. Разделение крупной системы на отдельные части (модули) является одним из базовых принципов проектирования не только в программировании. Связано это со многими вещами. Работать с небольшими частями проще, их легче заменить и отладить. Есть понятие юнит-тестов, применимое к функциям. Более того, в различных языках программирования есть свои аспекты применения функций, дающих те или иные преимущества. Например template в C++ или замыкания в JavaScript.
Читайте также:
Как называется программа которая пишет музыку

А вообще советую почитать книгу С.Макконнелла «Совершенный код» или нечто подобное, с общими аспектами программирования.

Отслеживать
ответ дан 20 июн 2016 в 19:36
321 1 1 серебряный знак 5 5 бронзовых знаков

Смотрю, выше привели основную причину — декомпозиция программы на части. Но у функций есть и другие применения.

Например, полиморфизм. Пример: я пишу функцию вывода на экран некоторого объекта. Одна функция делает это красиво но медленно — подойдёт когда времени много, вторая быстро но некрасиво — подходит для сценария когда мы быстро тащим или масштабируем объект. Для этого делаем прототип функции (определяет набор параметров и возвращаемое значение), и реализуем две функции, соответствующие этому прототипу. Указатель на функцию у нас содержит текущий способ рисования — и мы можем вызывать функцию рисования, не зная даже на какую конкретно из них он указывает.

Дальше — мы можем иметь массив таких указателей на функции, с одним и тем же прототипом. Смысл — некоторые из них просто рисуют, другие работают как фильтры. Например, фильтр, подсвечивающий точки объекта, за которые можно «потянуть». Опять же, мы можем вызывать все функции из массива по порядку — чтобы отрисовать объект со всеми фильтрами, и вызывающий их код не знает что они делают.

Отслеживать
ответ дан 20 июн 2016 в 21:14
1,868 9 9 серебряных знаков 21 21 бронзовый знак

  • декомпозиция

выделение функций в отдельные сущности позволяет и работать с ними как с компонентами: отдельно тестировать, отлаженная функция должна работать одинаково во всех ваших (и вашей конторы) программах, и использовать ее можно одновременно во всех 100500 программах, запущенных на суперкластере

наборы готовых функций собираются в библиотеки, распространяются и применяются тысячами программистов по всему миру десятки лет (BLAS/LAPACK/libc/WinAPI), или продаются как самостоятельный продукт — любая ОС является библиотекой функций, см. WindowsSystem*.dll /lib/*.so , и коммерческие библиотеки компонент

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

некоторые программные продукты, например распознаватель Abbyy или ядро САПР, продаются просто в виде кучи скомпилированных функций — 100 рублей штучка, 300 штук кучка, оптовым покупателям документация бесплатно

часто тяжелые коммерческие пакеты САПР,аналитики,расчетов и разнообразное оборудование поставляются опцией или в комплекте с SDK-библиотекой, собранной из интерфейсных функций: в документации описаны их назначение, применение, и типы/диапазоны входных/выходных данных, но сами функции идут в виде машинного кода без исходников (только кучка .h файлов с перечнем extern void to() ; extern double se(int,void*) , и пара .dll)

функция bubblesort() может быть описана в общем виде, сортируя данные любых даже еще не существующих типов, хранящиеся в любом упорядоченном контейнере (например сортировать слонопотамов в сепулькарии), при условии что для данных существует операция сравнения, а для контейнера — передача сообщения двум соседним элементам «сравнитесь между собой» и их перестановка местами (обычно исправляются ссылки кто за кем стоит, но как показывает практика медосмотров даже пятисвязные хешированные списки ничего не гарантируют)

оптимизирующий компилятор может сам решить, когда оформить функцию в виде отдельного блока кода c call/ret вызовом, а когда памяти хватает, межмодульных вызовов нет, и можно развернуть код функции в каждом месте использования, и прогнать по результату всю батарею оптимизаторов, в сишных программах добавляйте inline подсказывая компилятору что этот код можно подставлять а не вызывать, в особо клинических случаях вместо используйте вместо функций макросы (и шаблоны ?)

Источник: ru.stackoverflow.com

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru