Урок №13. Параметры и аргументы функций

На прошлом занятии мы обсуждали возможность функции возвращать значение обратно вызывающему коду с помощью оператора return. Сегодня мы поговорим о том, что представляют собой аргументы и параметры в функции.
Параметры и аргументы функций
Часто возникает необходимость передавать данные в функцию, чтобы она могла с ними взаимодействовать. Например, при написании функции умножения двух чисел необходимо указать, какие именно числа будут умножаться. Без этой информации функция не сможет выполнить свою задачу. Для передачи данных в функцию используются параметры и аргументы.
Функциональный параметр - это переменная, которая применяется внутри функции и получает значение от вызывающего объекта. Параметры указываются в круглых скобках при объявлении функции. Если параметров много, то они перечисляются через запятую, например:
// Эта функция не имеет параметров
void doPrint ( )
{
std :: cout << "In doPrint()" << std :: endl ;
}
// Эта функция имеет один параметр типа int: a
void printValue ( int a )
{
std :: cout << a << std :: endl ;
}
// Эта функция имеет два параметра типа int: a и b
int add ( int a , int b )
{
return a + b ;
}
Локальные переменные каждой функции действительны только внутри своей области видимости. Таким образом, если у функций printValue() и add() есть параметр с именем a, это не приведет к конфликту имен. Эти параметры считаются независимыми и не взаимодействуют друг с другом.
Значение, передаваемое из caller-а в функцию и указываемое в скобках при вызове функции в caller-е, называется аргументом функции:
printValue ( 7 ) ; // 7 – это аргумент функции printValue()
add ( 4 , 5 ) ; // 4 и 5 – это аргументы функции add()
Важно помнить, что аргументы перечисляются через запятую. Количество аргументов должно точно соответствовать количеству параметров, иначе компилятор выдаст ошибку.
Как работают параметры и аргументы функций?
При выполнении функции, все передаваемые параметры автоматически создаются как локальные переменные, и значение каждого аргумента копируется в соответствующий параметр (локальную переменную). Этот метод передачи параметров называется передачей по значению. Например:
#include
// Эта функция имеет два параметра типа int: a и b
// Значения переменных a и b определяет caller
void printValues ( int a , int b )
{
std :: cout << a << std :: endl ;
std :: cout << b << std :: endl ;
}
int main ( )
{
printValues ( 8 , 9 ) ; // здесь два аргумента: 8 и 9
return 0 ;
}
Когда функция printValues() вызывается, значения 8 и 9 копируются в переменные a и b соответственно. Переменной a присваивается значение 8, а переменной b - значение 9.
Итак, в итоге:
8
9
Как работают параметры и возвращаемые значения функций?
Путем использования аргументов и возвращаемых значений, мы можем разрабатывать функции, которые принимают и обрабатывают информацию, после чего возвращают результат обратно вызывающему коду.
К примеру, можно создать простую функцию, которая принимает на вход два целых числа и возвращает их сумму:
#include
// Функция add() принимает два целых числа в качестве параметров и возвращает их сумму
// Значения a и b определяет caller
int add ( int a , int b )
{
return a + b ;
}
// Функция main() не имеет параметров
int main ( )
{
std :: cout << add ( 7 , 8 ) << std :: endl ; // аргументы 7 и 8 передаются в функцию add()
return 0 ;
}
При вызове функции add(), параметру a присваивается значение 7 , а параметру b — значение 8 . Затем функция add() вычисляет их сумму и возвращает результат обратно в main(). И тогда уже результат выводится на экран.
Результат работы программы:
Пятнадцать
Еще примеры
Давайте рассмотрим еще несколько примеров вызовов функций:
#include
int add ( int a , int b )
{
return a + b ;
}
int multiply ( int c , int d )
{
return c * d ;
}
int main ( )
{
std :: cout << add ( 7 , 8 ) << std :: endl ; // внутри функции add(): a = 7, b = 8, значит a + b = 15
std :: cout << multiply ( 4 , 5 ) << std :: endl ; // внутри функции multiply(): c = 4, d = 5, значит c * d = 20
// Мы можем передавать целые выражения в качестве аргументов
std :: cout << add ( 2 + 3 , 4 * 5 ) << std :: endl ; // внутри функции add(): a = 5, b = 20, значит a + b = 25
// Мы можем передавать переменные в качестве аргументов
int x = 4 ;
std :: cout << add ( x , x ) << std :: endl ; // будет 4 + 4
std :: cout << add ( 1 , multiply ( 2 , 3 ) ) << std :: endl ; // будет 1 + (2 * 3)
std :: cout << add ( 1 , add ( 2 , 3 ) ) << std :: endl ; // будет 1 + (2 + 3)
return 0 ;
}
Результат работы программы:
15
20
25
8
7
6
Первые два вызова были понятны сразу.
При третьем вызове функции передаются выражения, которые необходимо вычислить сначала. Например, 2 + 3 = 5, и результат 5 присваивается переменной a. Также 4 * 5 = 20, и результат 20 присваивается переменной b. После этого вызывается функция add(5, 20), результатом которой является значение 25.
Далее идущая пара довольно проста в понимании:
int x = 4 ;
std :: cout << add ( x , x ) << std :: endl ; // будет 4 + 4
В этом месте уже имеются значения a = x и b = x. Поскольку x равно 4, то при сложении x и x получаем add(4, 4). Полученный результат равен 8.
Давайте теперь рассмотрим более сложный вызов:
std :: cout << add ( 1 , multiply ( 2 , 3 ) ) << std :: endl ; // будет 1 + (2 * 3)
При выполнении данного выражения процессору необходимо определить значения параметров a и b функции add(). Значение параметра a уже известно - мы передаем значение 1 (a = 1). Чтобы определить значение параметра b, необходимо выполнить операцию умножения: multiply(2, 3), результат которой равен 6. Затем add(1, 6) вернет число 7, которое будет выведено на экран.
В общем, чтобы сказать кратко:Вызов функции add с аргументами 1 и результатом умножения 2 на 3 приведет к add(1, 6), что равно 7.
Последний запрос может показаться немного запутанным, так как в качестве аргумента функции add() используется другой вызов add():
std :: cout << add ( 1 , add ( 2 , 3 ) ) << std :: endl ; // будет 1 + (2 + 3)
Однако здесь все аналогично предыдущему примеру. Прежде чем процессор выполнит внешний вызов функции add(), он должен обработать внутренний вызов функции add(2, 3). Результатом add(2, 3) будет число 5. Затем процессор обрабатывает функцию add(1, 5), что приводит к результату 6. Затем число 6 выводится в std::cout.
В общем, чтобы сказать кратко:Выполнение операции add(1, add(2, 3)) приводит к add(1, 5), что равно 6.
Тест
Первое задание: Что не так с данным отрывком кода?
#include
void multiply ( int a , int b )
{
return a * b ;
}
int main ( )
{
std :: cout << multiply ( 7 , 8 ) << std :: endl ;
return 0 ;
}
Вторая задача: Какие две сложности возникают здесь?
#include
int multiply ( int a , int b )
{
int product = a * b ;
}
int main ( )
{
std :: cout << multiply ( 5 ) << std :: endl ;
return 0 ;
}
Третье задание: Что будет результатом работы данной программы?
#include
int add ( int a , int b , int c )
{
return a + b + c ;
}
int multiply ( int a , int b )
{
return a * b ;
}
int main ( )
{
std :: cout << multiply ( add ( 3 , 4 , 5 ) , 5 ) << std :: endl ;
return 0 ;
}
Четвертое задание: Реализуйте функцию doubleNumber(), которая принимает на вход целое число, умножает его на два и возвращает результат.
Пятая задача: Разработайте программу, которая запрашивает у пользователя целое число (используйте std::cin), увеличивает его вдвое с помощью функции doubleNumber() из предыдущего упражнения, и затем отображает результат на экране.
Пожалуйста, оставляйте свои ответы в комментариях ниже!
Comments