Типы функций в C++ и их использование

Использование типов функцийВ предыдущих вам объяснили различные концепции C++, такие как переменные, классы хранения, операторы, массивы, строки и т. д.

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

Как мы определяем функцию?

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

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

Типы функций в C++

В C++ есть два типа функций, они показано ниже:

Типы функций в C++

Встроенные функции

Встроенные функции также называются библиотечными функциями. Это функции, предоставляемые C++, и нам не нужно писать их самим. Мы можем напрямую использовать эти функции в нашем коде.

Эти функции размещены в заголовочных файлах C++. Например , <cmath>, <string> — это заголовки со встроенными математическими функциями и строковыми функциями соответственно.

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

Вывод данных:

Введите строку ввода: Справка по тестированию программного обеспечения
Введенная строка: Справка по тестированию программного обеспечения!
Размер строки: 21

Здесь мы используем заголовки <iostream> и <string>. Типы данных и другие функции ввода/вывода определены в библиотеке <iostream>. Строковые функции, такие как getline, size, являются частью заголовка <string>.

Пользовательские функции

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

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

Общий синтаксис для пользовательских функций (или просто функций) приведен ниже:

Итак, как показано выше, каждая функция имеет::

Return type: это значение, которое функции возвращают вызывающей функции после выполнения определенной задачи.

functionName : Идентификатор, используемый для названия функции.

Parameter List: Обозначается param1, param2,…paramn в приведенном выше синтаксисе. Это аргументы, которые передаются функции при вызове функции. Список параметров является необязательным, т.е. у нас могут быть функции без параметров.

Function body: группа операторов, выполняющих определенную задачу.

Как мы уже говорили, нам нужно «объявить» функцию перед ее использованием.

Объявление функции

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

Мы привели несколько примеров объявления функции ниже:

Вышеприведенное объявление относится к функции «sum» (сумма), которая принимает два целых числа в качестве параметров и возвращает целочисленное значение.

Функция подкачки принимает два параметра типа int и не возвращает никакого значения, поэтому тип возвращаемого значения — недействителен.

Функция display не принимает никаких параметров и не возвращает никакого типа.

Определение функции

Определение функции содержит все, что содержит объявление функции, а также тело функции, заключенное в фигурные скобки ({}).

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

Для приведенного выше объявления функции swap приведено ниже:

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

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

Вывод данных:

Введите два числа, которые нужно поменять местами: 5 и 3
a = 5 b = 3
После замены: a = 3 b = 5

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

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

Вызов функции

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

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

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

Формальные и фактические параметры

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

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

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

Вы можете видеть определения этих параметров в первой строке определения функции. Это формальные параметры.

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

Возвращаемые значения

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

Давайте рассмотрим пример добавления двух чисел, для демонстрации работы типа возвращаемых значений:

Вывод данных:

Введите два числа, которые нужно добавить: 11 и 11
Сумма двух чисел: 22

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

Когда функция выполняется, выражение (a+b), возвращаемое функцией sum, присваивается переменной результата (result), что показывает, как используется возвращаемое значение функции.

Пустые функции

Вы видели, что общий синтаксис функции требует определения возвращаемого типа. Но что, если у нас есть такая функция, которая не возвращает никакого значения, то что мы указываем в качестве возвращаемого типа? Ответ заключается в том, что мы используем не имеющий значения тип «void», чтобы указать, что функция не возвращает значение.

В таком случае функция называется «недействительной функцией», и ее прототип будет иметь вид:

Кстати, считается хорошей практикой включать фразу «return»; (возврат) в конце функции пустоты для ясности.

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

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

В C++ есть определенные способы передачи параметров, о них написано ниже:

Передача по значению

В программе для замены двух целых чисел, которую мы обсуждали ранее, вы видели, что мы просто считываем целые числа «a» и «b» в main и передаем их функции обмена. Это метод передачи по значению.

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

Вывод данных:

Введите два числа, которые необходимо поменять местами: 3 и 2
a = 3 b = 2
После обмена внутри Swap:
a = 2 b = 3
После обмена внутри Main:
a = 3 b = 2

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

Как видно из вывода, изначально мы передаем значения a=3 и b=2. Это реальные параметры. Затем, после подкачки внутри функции подкачки, мы видим, что значения на самом деле поменялись местами: a=2, b=3.

Однако после вызова функции swap в основной функции значения a и b по-прежнему равны 3 и 2 соответственно. Это связано с тем, что фактические параметры передаются в функцию, где у нее есть копия переменных. Следовательно, хотя формальные параметры были заменены в функции подкачки, они не были отражены обратно.

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

Передача по ссылке

Передача по ссылке — это еще один метод, используемый C++ для передачи параметров функциям. В этом методе вместо передачи копий фактических параметров мы передаем ссылки на фактические параметры.

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

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

Мы модифицировали нашу функцию подкачки, чтобы вы могли лучше понять концепцию:

Вывод данных:

Введите два числа, которые нужно поменять местами: 25 50
a = 25 b = 50
После обмена внутри Main:
a = 50 b = 25

Метод передачи по ссылке показан в приведенном выше примере. Вы можете видеть, что фактические параметры передаются как есть. Но мы добавляем символ «&» к формальным параметрам, указывающий, что это ссылка, которую мы используем для этого конкретного параметра.

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

Передача по указателю

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

Единственная разница в том, что при передаче по ссылке мы имеем дело со ссылками или псевдонимами параметров, тогда как при передаче по указателю мы используем переменные-указатели для передачи параметров.

Переменные-указатели различаются ссылками, в которых переменные-указатели указывают на конкретную переменную, и, в отличие от ссылок, мы можем изменить переменную, на которую она указывает.

Мы снова представляем замену двух целых чисел, для демонстрации техники передачи по указателю:

Вывод данных:

Введите два числа, которые нужно поменять местами: 23 и 54
a = 23 b = 54
После замены внутри Main:
a = 54 b = 23

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

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

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

Следующий пример демонстрирует использование параметров по умолчанию:

Вывод данных:

Введите значения для a, b и c: 10, 4 и 6

Вызов mathoperation с 1 аргументом: 15
Вызов mathoperation с 2 аргументами: 20
Вызов mathoperation с 3 аргументами: 6

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

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

Обратите внимание, что при предоставлении параметров по умолчанию мы всегда начинаем с самого правого параметра. Кроме того, мы не можем пропустить промежуточный параметр и предоставить значение по умолчанию для следующего параметра.

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

Постоянные параметры

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

Обратите внимание, что мы не можем передать константный параметр неконстантному формальному параметру. Но мы можем передать константный и неконстантный параметр в константный формальный параметр.

Точно так же мы можем также иметь константный возвращаемый тип. В этом случае также нельзя изменить возвращаемый тип.

Давайте посмотрим на пример кода, в котором используются константные ссылки:

Вывод данных:

Введите два числа, которые необходимо поменять местами: 22 и 33
a = 22 b = 33
Результат сложения: 55

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

Если мы попытаемся изменить значения a или b внутри функции, то компилятор выдаст ошибку.

Встроенные функции

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

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

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

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

Ниже приведен пример встроенной функции:

Как показано выше, мы предваряем определение функции ключевым словом «inline», чтобы сделать функцию встроенной.

Использование структурных переменных в функциях

Мы можем передавать структурные переменные в качестве параметров для работы аналогично тому, как мы передаем в качестве параметров обычные переменные.

Это показано в следующем примере:

Вывод данных:

ведите имя:
Введите возраст:
Введите зарплату:
Структура информации о человеке:
Возраст:
Имя:
Зарплата:

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

Вывод

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

С Уважением, МониторБанк

Добавить комментарий