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

  Юрий  | 

    | 

  Обновл. 4 Мар 2019  | 

 34152

 ǀ   28 

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

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

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

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

Например:

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

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

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

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


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

Например:

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

Результат:

8
9

Как работают параметры и возвращаемые значения функций?

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

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

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

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

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

15

Ещё примеры


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

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

15
20
25
8
7
6

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

В третьем вызове, параметрами являются выражения, которые сначала нужно обработать. 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.

Короче говоря:

add(1, add(2, 3)) => add(1, 5) => 6

Тест

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

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

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

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

5. Напишите полноценную программу, которая принимает целое число от пользователя (используйте 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.

Ответ №4

Ответ №5


Примечание: У вас могут быть и другие решения заданий №4 и №5 — всё ок. В программировании есть много случаев, когда одну задачу можно решить несколькими способами.

Оценить статью:

Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5 (259 оценок, среднее: 4,94 из 5)
Загрузка...

Комментариев: 28

  1. Аватар олег:

    А такой вариант плох тем что одна функция выполняет 3 действия?
    И еще вопрос, почему code::blocks спокойно выводит в консоль русские буквы без добавления set_locale?

  2. Аватар yrneero:

    Один из лучших сайтов где можно выучить C++. Понятно все до мелочей, автору респект!!! Было бы неплохо добавить к примеру видео-уроки)). Еще раз спасибо за ваши старания

    1. Юрий Юрий:

      Пожалуйста 🙂

  3. Аватар Eugen:

    Добрый день.

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

    И конечно мой код:

  4. Аватар Илья:

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

    1. Аватар Илья:

      P.S:
      В таком решении ,когда мы в фукции main вызываем функцию doubleNumber(),её аргументом можно прописать произвольное число при этом считать умножаться будет то число,которое мы пропишем в консоли,а не аргумент.Кстати с аргументом "а" в функции doubleNumber код не компиллируется.

    2. Юрий Юрий:

      Вот беру и смотрю.

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

      У тебя doubleNumber выполняет две задачи: принимает число и умножает его. Для такой простенькой программы, как эта (это даже не программа — 13 строк кода всего лишь), можно использовать и такой, как у тебя вариант, и такой, как у меня, и другие, которые предлагали в комментариях. В более сложных программах оптимальным вариантом было бы сделать отдельную функцию для получения значения от пользователя и отдельную для умножения значения.

    3. Аватар Alexey:

      так будет правильнее

  5. Аватар Ray:

    У Вас, в примерах к уроку 13 указывается: using namespace std; и дальше везде все равно прописываются std: Корректно ли использование std: в добавок к using namespace std; ? Думаю, что они должны быть взаимоисключающими, я не прав ?

    1. Юрий Юрий:

      Вы правы. Спасибо за бдительность, исправил.

  6. Аватар master114:

    Сделал через функции, так сказать с заделом на правильность — http://www.onlinegdb.com/B1-Zzq3hM.

    1. Юрий Юрий:

      Всё правильно и согласно рекомендациям из этого туториала. Радует, что уловили суть и пишите программы с самого начала правильным образом.

  7. Аватар Parenochek1488:

    Я какой-то не правильный(

    1. Юрий Юрий:

      У вас тут несколько замечаний (по поводу using namespace std и объявления переменных в глобальной области видимости). Продолжайте читать уроки — постепенно всё узнаете и сами поймете, что у вас не так.

      1. Аватар Parenochek1488:

        Никак не могу запомнить, как работают параметры. Это решение единственное, которое пришло на ум. Но, как по мне, главное, что оно работает и введённое "a" умножается на два. Но урок я явно не усвоил, так что буду пробовать ещё. Спасибо за такой удобный сайт.

        1. Юрий Юрий:

          Пожалуйста. По поводу параметров есть не один урок, всё, что нужно — рассматривается.

  8. Аватар Семён:

    Спасибо ! Но по мне так лучше пока все поэтапно Но их плюс в том , что их можно повторять много раз .

  9. Аватар Александр:

    Для чего костыли с std:: ? Если можно реализовать все быстрее без него с помощью using namespace std;.

  10. Аватар Дарья:

    Все прекрасно! Спасибо Вам! Не думала, что когда-нибудь возьмусь за изучение и что моей головы на это хватит! Написала решение к 5 заданию и какого было мое удивление когда она заработала!))

    1. Юрий Юрий:

      Никогда не знаешь, пока не попробуешь 🙂

    2. Аватар максим:

      какого пачему твой код сильно похож на мой? рандом наверно

  11. Аватар Yaroslav:

    Вам нужно после каждого урока приписывать авторство, как сделано в начале, типа: «Материал переведен с сайта LearnCpp.com».
    А то получается, что человек, который зашел просто с поиска на какой либо урок, посчитает Вас автором этого материала, что является ошибочным, так как Вы только переводчик =)

    1. Юрий Юрий:

      По началу так и делал. Но практика такая не прижилась, как видите 🙂

  12. Аватар Сергей:

    Нужно добавить на сайте систему (лайк,дизлайк) к коментариям.

    1. Юрий Юрий:

      Ну это уже в перспективе.

  13. Аватар Сергей:

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

    1. Юрий Юрий:

      Спасибо, приятно 🙂

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

Ваш E-mail не будет опубликован. Обязательные поля помечены *