Программа с использованием функции

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

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

Подпрограмма — именованная, логически законченная группа операторов языка, которую можно вызвать для выполнения любое количество раз из различных мест программы. В языке C++ подпрограммы реализованы в виде функций [4 ]

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

Функция — это поименованный набор описаний и операторов, выполняющих определённую задачу. Функция может принимать параметры и возвращать значение. Информация, передаваемая в функцию для обработки, называется параметром, а результат вычисления функции её значением. Обращение к функции называют вызовом. Как известно (п.

Функции №2. Использование функции»ЕСЛИ» в программе «Эксель».

2.8), любая программа на C++ состоит из одной или нескольких функций. При запуске программы первой выполняется функция main . Если среди операторов функции main встречается вызов функции, то управление передаётся операторам функции. Когда все операторы функции будут выполнены, управление возвращается оператору, следующему за вызовом функции.

Перед вызовом функция должна быть обязательно описана. Описание функции состоит из заголовка и тела функции:

тип имя_функции(список_переменных)

  • тип возвращаемого функцией значения, он может быть любым; если функция не возвращает значения, указывают тип void ;
  • имя_функции ;
  • список_переменных — перечень передаваемых в функцию величин (аргументов), которые отделяются друг от друга запятыми; для каждой переменной из списка указывается тип и имя ; если функция не имеет аргументов, то в скобках указывают либо тип void , либо ничего.

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

В общем виде структура программы на C++ может иметь вид:

директивы компилятора тип имя_1(список_переменных) < тело_функции_1; >тип имя_2(список_переменных) < тело_функции_2; >. тип имя_n(список_переменных) < тело_функции_n; >int main (список_переменных) < //Тело функции может содержать операторы вызова функций имя_1, имя_2, . имя_n тело_основной_функции; >

Однако допустима и другая форма записи программного кода :

директивы компилятора тип имя_1(список_переменных); тип имя_2(список_переменных); . тип имя_n(список_переменных); int main (список_переменных) < //Тело функции может содержать операторы вызова функций имя_1, имя_2, . имя_n тело_основной_функции; >тип имя_1(список_переменных) < тело_функции_1; >тип имя_2(список_переменных) < тело_функции_2; >. тип имя_n(список_переменных)

Здесь функции описаны после функции main() , однако до неё перечислены заголовки всех функций. Такого рода опережающие заголовки называют прототипами функций. Прототип указывает компилятору тип данных, возвращаемых функцией, тип переменных, выступающих в роли аргументов, и порядок их следования. Прототипы используются для проверки правильности вызова функций в основной программе. Имена переменных, указанные в прототипе функции, компилятор игнорирует:

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


//Записи равносильны. int func ( int a, int b ); int func ( int, int );

Вызвать функцию можно в любом месте программы. Для вызова функции необходимо указать её имя и в круглых скобках, через запятую перечислить имена или значения аргументов, если таковые имеются:

имя_функции(список_переменных);

Рассмотрим пример. Создадим функцию f() , которая не имеет входных значений и не формирует результат. При вызове этой функции на экран выводится строка символов «С Новым Годом, » .

#include using namespace std; void f ( ) //Описание функции. < cout int main ( ) < f ( ); //Вызов функции. cout <<«Студент!» << endl; f ( ); //Вызов функции. cout <<«Преподаватель!» << endl; f ( ); //Вызов функции. cout

Результатом работы программы будут три строки:

С Новым Годом, Студент! С Новым Годом, Преподаватель! С Новым Годом, Народ!

Далее приведён пример программы, которая пять раз выводит на экран фразу «Здравствуй, мир!» . Операция вывода строки символов оформлена в виде функции fun() . Эта функция также не имеет входных значений и не формирует результат. Вызов функции осуществляется в цикле:

#include using namespace std; void fun ( ) < cout int main ( )

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

return (выражение);

Далее приведён пример программы, которая вычисляет значение выражения sin^2(alpha)+cos^2(alpha)при заданном значении α. Здесь функция radian выполняет перевод градусной меры угла в радианную 1 Чтобы найти радианную меру какого-нибудь угла по заданной градусной мере, нужно помножить число градусов на frac<pi>, число минут на frac<pi>, число секунд на frac<pi> и найденные произведения сложить. .

N

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

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

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

Функции в C++ — урок 6

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

Читайте также:
Как пользоваться программой saver

#include #include using namespace std; int main() < string valid_pass = «qwerty123»; string user_pass; cout else < cout return 0; >

А вот аналогичный пример с функцией:

#include #include using namespace std; void check_pass (string password) < string valid_pass = «qwerty123»; if (password == valid_pass) < cout else < cout > int main()

По сути, после компиляции не будет никакой разницы для процессора, как для первого кода, так и для второго. Но ведь такую проверку пароля мы можем делать в нашей программе довольно много раз. И тогда получается копипаста и код становится нечитаемым. Функции — один из самых важных компонентов языка C++.

  • Любая функция имеет тип, также, как и любая переменная.
  • Функция может возвращать значение, тип которого в большинстве случаев аналогично типу самой функции.
  • Если функция не возвращает никакого значения, то она должна иметь тип void (такие функции иногда называют процедурами)
  • При объявлении функции, после ее типа должно находиться имя функции и две круглые скобки — открывающая и закрывающая, внутри которых могут находиться один или несколько аргументов функции, которых также может не быть вообще.
  • после списка аргументов функции ставится открывающая фигурная скобка, после которой находится само тело функции.
  • В конце тела функции обязательно ставится закрывающая фигурная скобка.

Пример построения функции

#include using namespace std; void function_name () < cout int main() < function_name(); // Вызов функции return 0; >

Перед вами тривиальная программа, Hello, world, только реализованная с использованием функций.

Если мы хотим вывести «Hello, world» где-то еще, нам просто нужно вызвать соответствующую функцию. В данном случае это делается так: function_name(); . Вызов функции имеет вид имени функции с последующими круглыми скобками. Эти скобки могут быть пустыми, если функция не имеет аргументов. Если же аргументы в самой функции есть, их необходимо указать в круглых скобках.

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

В предыдущих примерах мы использовали функции типа void , которые не возвращают никакого значения. Как многие уже догадались, оператор return используется для возвращения вычисляемого функцией значения.

Рассмотрим пример функции, возвращающей значение на примере проверки пароля.

#include #include using namespace std; string check_pass (string password) < string valid_pass = «qwerty123»; string error_message; if (password == valid_pass) < error_message = «Доступ разрешен.»; >else < error_message = «Неверный пароль!»; >return error_message; > int main()

В данном случае функция check_pass имеет тип string, следовательно она будет возвращать только значение типа string, иными словами говоря строку. Давайте рассмотрим алгоритм работы этой программы.

Самой первой выполняется функция main(), которая должна присутствовать в каждой программе. Теперь мы объявляем переменную user_pass типа string, затем выводим пользователю сообщение «Введите пароль», который после ввода попадает в строку user_pass. А вот дальше начинает работать наша собственная функция check_pass() .

В качестве аргумента этой функции передается строка, введенная пользователем.

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

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

После того, как произошел вызов функции check_pass() , начинает работать данная функция. Если функцию нигде не вызвать, то этот код будет проигнорирован программой. Итак, мы передали в качестве аргумента строку, которую ввел пользователь.

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

Теперь мы проверяем, правильный ли пароль ввел пользователь или нет. если пользователь ввел правильный пароль, присваиваем переменной error_message соответствующее значение. если нет, то сообщение об ошибке.

После этой проверки мы возвращаем переменную error_message . На этом работа нашей функции закончена. А теперь, в функции main(), то значение, которое возвратила наша функция мы присваиваем переменной error_msg и выводим это значение (строку) на экран терминала.

Также, можно организовать повторный ввод пароля с помощью рекурсии (о ней мы еще поговорим). Если объяснять вкратце, рекурсия — это когда функция вызывает сама себя. Смотрите еще один пример:

#include #include using namespace std; bool password_is_valid (string password) < string valid_pass = «qwerty123»; if (valid_pass == password) return true; else return false; >void get_pass () < string user_pass; cout else < cout > int main()

Функции очень сильно облегчают работу программисту и намного повышают читаемость и понятность кода, в том числе и для самого разработчика (не удивляйтесь этому, т. к. если вы откроете код, написанный вами полгода назад,не сразу поймете соль, поверьте на слово).

Не расстраивайтесь, если не сразу поймете все аспекты функций в C++, т. к. это довольно сложная тема и мы еще будем разбирать примеры с функциями в следующих уроках.

Читайте также:
Autocad map 3d описание программы

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

Если Вы найдете какие-либо ошибки в моем коде, обязательно напишите об этом в комментариях. здесь же можно задавать все вопросы.

Источник: code-live.ru

Функции (C++)

Функции — это блоки кода, выполняющие определенные операции. Если требуется, функция может определять входные параметры, позволяющие вызывающим объектам передавать ей аргументы. При необходимости функция также может возвращать значение как выходное. Функции полезны для инкапсуляции основных операций в едином блоке, который может многократно использоваться. В идеальном случае имя этого блока должно четко описывать назначение функции. Следующая функция принимает два целых числа от вызывающего объекта и возвращает их сумму; a и b — это параметры типа int .

int sum(int a, int b)

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

int main() < int i = sum(10, 32); int j = sum(i, 66); cout

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

Функции, определенные в области видимости класса, называются функциями-членами. В C++, в отличие от других языков, функции можно также определять в области видимости пространства имен (включая неявное глобальное пространство имен). Такие функции называются свободными или не-членами; они широко используются в стандартной библиотеке.

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

Части объявления функции

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

int sum(int a, int b);

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

int sum(int a, int b)

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

При объявлении функции необходимо указать:

  1. Тип возвращаемого значения, который указывает тип значения, возвращаемого функцией, или void значение , если значение не возвращается. В C++11 является допустимым типом возвращаемого значения, auto который указывает компилятору вывести тип из оператора return. В C++14 decltype(auto) также разрешено. Дополнительные сведения см. в подразделе «Выведение возвращаемых типов» ниже.
  2. Имя функции, которое должно начинаться с буквы или подчеркивания и не может содержать пробелы. Как правило, символы подчеркивания в начале имен функций стандартной библиотеки указывают на частные функции-члены или функции, не являющиеся членами, которые не предназначены для использования в коде.
  3. Список параметров, заключенный в скобки. В этом списке через запятую указывается нужное (возможно, нулевое) число параметров, задающих тип и, при необходимости, локальное имя, по которому к значениям можно получить доступ в теле функции.

Необязательные элементы объявления функции:

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

constexpr float exp(float x, int n) < return n == 0 ? 1 : n % 2 == 0 ? exp(x * x, n / 2) : exp(x * x, (n — 1) / 2) * x; >;
//Declare printf with C linkage. extern «C» int printf( const char *fmt, . );
inline double Account::GetBalance()
#include template T copy_object(T int value ; MyClass mc; if(strcmp(s, «default») != 0) < value = mc.do_something(i); >return value; >

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

MyClass int value ; MyClass mc; mc.Initialize(i,s); return mc; >

Функции const и constexpr

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

Объявите функцию как constexpr , если значение, которое она создает, можно определить во время компиляции. Функция constexpr обычно выполняется быстрее, чем обычная функция. Для получения дополнительной информации см. constexpr .

Шаблоны функций

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

template auto Add2(const Lhs rhs) < return lhs + rhs; >auto a = Add2(3.13, 2.895); // a is a double auto b = Add2(string< «Hello» >, string< » World» >); // b is a std::string

Дополнительные сведения см. в разделе Шаблоны функций.

Параметры и аргументы функций

У функции имеется список параметров, в котором через запятую перечислено необходимое (возможно, нулевое) число типов. Каждому параметру присваивается имя, по которому к нему можно получить доступ в теле функции. Шаблон функции может указывать дополнительные параметры типа или значения. Вызывающий объект передает аргументы, представляющие собой конкретные значения, типы которых совместимы со списком параметров.

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

Читайте также:
Лучшие программы для стресс теста системы

void DoSomething(std::string:

void DoSomething(const std::string

Несмотря на то, что нельзя указывать void аргумент, за исключением описанного здесь, типы, производные от типа void (например, указатели void на и массивы ) могут отображаться в любом месте списка объявлений аргументов void .

Аргументы по умолчанию

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

int DoSomething(int num, string str, Allocator . >// OK both parameters are at end int DoSomethingElse(int num, string str = string< «Working» >, Allocator . >// C2548: ‘DoMore’: missing default parameter for parameter 2 int DoMore(int num = 5, // Not a trailing parameter! string str, Allocator

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

Завершающие возвращаемые типы

«Обычные» возвращаемые типы расположены слева от сигнатуры функции. Конечный тип возвращаемого значения находится в правой части сигнатуры и предшествует оператору -> . Завершающие возвращаемые типы особенно полезны в шаблонах функций, когда тип возвращаемого значения зависит от параметров шаблона.

template auto Add(const Lhs rhs) -> decltype(lhs + rhs)

При auto использовании в сочетании с конечным типом возвращаемого значения он просто служит заполнителем для выражения типа decltype и сам не выполняет выведение типа.

Локальные переменные функции

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

В C++ локальные переменные можно объявлять как статические. Переменная является видимой только в теле функции, однако для всех экземпляров функции существует только одна копия переменной. Локальные статические объекты удаляются во время завершения, определенного директивой atexit . Если статический объект не был создан, так как поток управления программы обошел его объявление, попытка уничтожить этот объект не предпринимается.

Выведение возвращаемых типов (C++14)

В C++14 можно использовать auto , чтобы указать компилятору выводить тип возвращаемого значения из текста функции, не указывая конечный тип возвращаемого значения. Обратите внимание, что auto всегда выводит значение , возвращаемое по значению. Используйте auto , чтобы дать компилятору команду выведения ссылки.

В этом примере auto будет выведено как неконстная копия значения суммы lhs и rhs.

template auto Add2(const Lhs rhs) < return lhs + rhs; //returns a non-const object by value >

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

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

template, int. I> decltype(auto) apply_(F f, Tuple args, index_sequence) < return std::forward(f)(std::get(std::forward(args)). ); > template, typename Indices = make_index_sequence> decltype( auto) apply(F f, Tuple args) < return apply_(std::forward(f), std::forward(args), Indices()); >

Возврат нескольких значений из функции

Существует несколько способов возврата нескольких значений из функции:

    Инкапсулируйте значения в именованном объекте класса или структуры. Требует, чтобы определение класса или структуры было видимым для вызывающего объекта:

#include #include using namespace std; struct S < string name; int num; >; S g() < string t< «hello» >; int u< 42 >; return < t, u >; > int main()
#include #include #include using namespace std; tuple f() < int i< 108 >; string s< «Some text» >; double d< .01 >; return < i,s,d >; > int main() < auto t = f(); cout (t) (t) (t)
#include #include #include using namespace std; tuple f() < int i< 108 >; string s< «Some text» >; double d< .01 >; return < i,s,d >; > struct S < string name; int num; >; S g() < string t< «hello» >; int u< 42 >; return < t, u >; > int main() < auto[x, y, z] = f(); // init from tuple cout

Указатели функций

Как и в C, в C++ поддерживаются указатели на функции. Однако более типобезопасной альтернативой обычно служит использование объекта-функции.

Рекомендуется использовать для typedef объявления псевдонима для типа указателя функции при объявлении функции, возвращающей тип указателя функции. Например.

typedef int (*fp)(int); fp myFunction(char* s); // function returning function pointer

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

int (*myFunction(char* s))(int);

Предыдущее объявление эквивалентно объявлению, использующим typedef ранее.

Источник: learn.microsoft.com

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