06. Параметры и аргументы функций
2019-04-08, 1:13 PM

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

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

Например:

1  // Эта функция не имеет параметров
2  void doPrint()
3  {
4   std::cout << "In doPrint()" << std::endl;
5  }

6

7  // Эта функция имеет один параметр типа int: a
8  void printValue(int a)
9  {
10   std::cout << a << std::endl;
11  }

12

13  // Эта функция имеет два параметра типа int: a и b
14  int add(int a, int b)
15  {
16   return a + b;
17  }

Параметры каждой функции действительны только внутри этой функции. Поэтому, если printValue() и add() имеют параметр с именем a, то это не означает, что произойдёт конфликт имён. Эти параметры считаются отдельными и никак не взаимодействуют друг с другом.

Аргумент — это значение, которое передаётся из caller-а в функцию и которое указывается в скобках при вызове функции в caller-е:

1  printValue(7); // 7 – это аргумент функции printValue()
2  add(4, 5); // 4 и 5 – это аргументы функции add()

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

Как работают параметры и аргументы функций?

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

Например:

1  #include <iostream>

2

3  // Эта функция имеет два параметра типа int: a и b
4  // Значения переменных a и b определяет caller
5  void printValues(int a, int b)
6  {
7   std::cout << a << std::endl;
8   std::cout << b << std::endl;
9  }

10

11  int main()
12  {
13   printValues(8, 9); // здесь два аргумента: 8 и 9

14

15   return 0;
16  }

При вызове функции printValues() аргументы 8 и 9 копируются в параметры a и b. Параметру a присваивается значение 8, а параметру b — значение 9.

Результат:

8
9

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

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

1  #include <iostream>

2

3  // Функция add() принимает два целых числа в качестве параметров и возвращает их сумму
4  // Значения a и b определяет caller
5  int add(int a, int b)
6  {
7   return a + b;
8  }

9

10  // Функция main() не имеет параметров
11  int main()
12  {
13   std::cout << add(7, 8) << std::endl; // аргументы 7 и 8 передаются в функцию add()
14   return 0;
15  }

При вызове функции add(), параметру a присваивается значение 7, а параметру b — 8.

Затем функция add() вычисляет их сумму и возвращает результат обратно в main(). Затем уже результат выводится на экран.

Результат выполнения программы выше:

15

Ещё примеры

Рассмотрим ещё несколько вызовов функций:

1  #include <iostream>

2

3  int add(int a, int b)
4  {
5   return a + b;
6  }

7

8  int multiply(int c, int d)
9  {
10   return c * d;
11  }

12

13  int main()
14  {
15   std::cout << add(7, 8) << std::endl; // внутри функции add(): a = 7, b = 8, значит a + b = 15
16  std::cout << multiply(4, 5) << std::endl; // внутри функции multiply(): c = 4, d = 5, значит c * d = 20

17

18   // Мы можем передавать целые выражения в качестве аргументов
19   std::cout << add(2 + 3, 4 * 5) << std::endl; // внутри функции add(): a = 5, b = 20, значит a + b = 25

20

21   // Мы можем передавать переменные в качестве аргументов
22   int x = 4;
23   std::cout << add(x, x) << std::endl; // будет 4 + 4

24

25   std::cout << add(1, multiply(2, 3)) << std::endl; // будет 1 + (2 * 3)
26   std::cout << add(1, add(2, 3)) << std::endl; // будет 1 + (2 + 3)

27

28   return 0;
29  }

Результат выполнения программы выше:

15
20
25
8
7
6

С первыми двумя вызовами всё понятно.

В третьем вызове, параметрами являются выражения, которые сначала нужно обработать. 2 + 3 = 5 и результат 5 присваивается переменной a. 4 * 5 = 20 и результат 20 присваивается переменной b. Результатом выполнения функции add(5, 20) является значение 25.

Следующая пара относительно легкая:

1  int x = 4;
2  std::cout << add(x, x) << std::endl; // будет 4 + 4

Здесь уже a = x и b = x. Поскольку x = 4, то add(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, multiply(2, 3)) => add(1, 6) => 7

Последний вызов может показаться немного сложным из-за того, что параметром функции add() является другой вызов add():

1  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

Тест
1. Что не так со следующим фрагментом кода?

1  void multiply(int a, int b)
2  {
3   return a * b;
4  }

5

6  int main()
7  {
8   std::cout << multiply(7, 8) << std::endl;
9   return 0;
10  }

2. Какие здесь есть две проблемы?

1  #include <iostream>

2

3  int multiply(int a, int b)
4  {
5   int product = a * b;
6  }

7

8  int main()
9  {
10   std::cout << multiply(5) << std::endl;
11   return 0;
12  }

3. Какой результат выполнения следующей программы?

1  #include <iostream>

 

3  int add(int a, int b, int c)
4  {
5   return a + b + c;
6  }

7

8  int multiply(int a, int b)
9  {
10   return a * b;
11  }

12

13  int main()
14  {
15   std::cout << multiply(add(3, 4, 5), 5) << std::endl;
16   return 0;
17  }

4. Напишите функцию doubleNumber(), которая принимает целое число в качестве параметра, умножает его на 2, а затем возвращает результат обратно в caller.

5. Напишите полноценную программу, которая принимает целое число от пользователя (используйте cin), удваивает его с помощью функции doubleNumber() с предыдущего задания, а затем выводит результат на экран.

Категория: C++ теория | Добавил: shadrinuro
Просмотров: 410 | Загрузок: 0 | Рейтинг: 0.0/0
Всего комментариев: 0
avatar