Урок №13. Параметры и аргументы функций
На предыдущем уроке мы говорили о том, что функция может возвращать значение обратно в caller, используя оператор return. На этом уроке мы узнаем, что такое аргументы в функции и что такое параметры в функции.
Параметры и аргументы функций
Во многих случаях нам нужно будет передавать данные в вызываемую функцию, чтобы она могла с ними как-то взаимодействовать. Например, если мы хотим написать функцию умножения двух чисел, то нам нужно каким-то образом сообщить функции, какие это будут числа. В противном случае, как она узнает, что на что перемножать? Здесь нам на помощь приходят параметры и аргументы.
Параметр функции — это переменная, которая используется в функции, и значение которой предоставляет caller (вызывающий объект). Параметры указываются при объявлении функции в круглых скобках. Если их много, то они перечисляются через запятую, например:
Параметры каждой функции действительны только внутри этой функции. Поэтому, если printValue() и add() имеют параметр с именем a , то это не означает, что произойдет конфликт имен. Эти параметры считаются независимыми и никак не взаимодействуют друг с другом.
Аргумент функции — это значение, которое передается из caller-а в функцию и которое указывается в скобках при вызове функции в caller-е:
Обратите внимание, аргументы тоже перечисляются через запятую. Количество аргументов должно совпадать с количеством параметров, иначе компилятор выдаст сообщение об ошибке.
Как работают параметры и аргументы функций?
При вызове функции, все её параметры создаются как локальные переменные, а значение каждого из аргументов копируется в соответствующий параметр (локальную переменную). Этот процесс называется передачей по значению. Например:
При вызове функции printValues() аргументы 8 и 9 копируются в параметры a и b . Параметру a присваивается значение 8 , а параметру b — значение 9 .
Как работают параметры и возвращаемые значения функций?
Используя параметры и возвращаемые значения, мы можем создавать функции, которые будут принимать и обрабатывать данные, а затем возвращать результат обратно в caller.
Например, простая функция, которая принимает два целых числа и возвращает их сумму:
При вызове функции add(), параметру a присваивается значение 7 , а параметру b — значение 8 . Затем функция add() вычисляет их сумму и возвращает результат обратно в main(). И тогда уже результат выводится на экран.
Результат выполнения программы:
Еще примеры
Рассмотрим еще несколько вызовов функций:
Результат выполнения программы:
С первыми двумя вызовами всё понятно.
В третьем вызове параметрами являются выражения, которые сначала нужно обработать. 2 + 3 = 5 и результат 5 присваивается переменной a . 4 * 5 = 20 и результат 20 присваивается переменной b . Результатом выполнения функции add(5, 20) является значение 25 .
Следующая пара относительно лёгкая для понимания:
Здесь уже a = x и b = x . Поскольку x = 4 , то add(x, x) = add(4, 4) . Результат — 8 .
Теперь рассмотрим вызов посложнее:
При выполнении этого стейтмента процессор должен определить значения параметров a и b функции add(). С параметром a всё понятно — мы передаем значение 1 ( a = 1 ). А вот чтобы определить значение параметра b , нам необходимо выполнить операцию умножения: multiply(2, 3) , результат — 6 . Затем add(1, 6) возвращает число 7 , которое и выводится на экран.
add(1, multiply(2, 3)) => add(1, 6) => 7
Последний вызов может показаться немного сложным из-за того, что параметром функции add() является другой вызов add():
Но здесь всё аналогично вышеприведенному примеру. Перед тем, как процессор вычислит внешний вызов функции add(), он должен обработать внутренний вызов функции add(2, 3) . add(2, 3) = 5 . Затем процессор обрабатывает функцию add(1, 5) , результатом которой является значение 6 . Затем 6 передается в std::cout.
Задание №1: Что не так со следующим фрагментом кода?
Задание №2: Какие здесь есть две проблемы?
Задание №3: Какой результат выполнения следующей программы?
Задание №4: Напишите функцию doubleNumber(), которая принимает целое число в качестве параметра, удваивает его, а затем возвращает результат обратно в caller.
Задание №5: Напишите полноценную программу, которая принимает целое число от пользователя (используйте std::cin), удваивает его с помощью функции doubleNumber() из предыдущего задания, а затем выводит результат на экран.
Ответы
Чтобы просмотреть ответ, кликните на него мышкой.
Ответ №1
Функция multiply() имеет тип возврата void, что означает, что эта функция не возвращает значения. Но, так как она все равно пытается возвратить значение с помощью оператора return, мы получим ошибку от компилятора. Функция должна иметь тип возврата int.
Ответ №2
Проблема №1: main() передает один аргумент в multiply(), но multiply() имеет два параметра.
Проблема №2: multiply() вычисляет результат и присваивает его локальной переменной, которую не возвращает обратно в main(). А поскольку тип возврата функции multiply() — int, то мы получим ошибку (в некоторых компиляторах) или неожиданные результаты (в остальных компиляторах).
Ответ №3
Функция multiply() принимает следующие параметры: a = add(3, 4, 5) и b = 5 . Сначала процессор обрабатывает a = add(3, 4, 5) , т.е. 3 + 4 + 5 = 12 . Затем уже выполняет операцию умножения, результатом которой является 60 . Ответ: 60.