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

  Юрий  | 

  Обновл. 2 Сен 2020  | 

 92644

 ǀ   59 

На предыдущем уроке мы говорили о том, что функция может возвращать значение обратно в 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(), которая принимает целое число в качестве параметра, удваивает его, а затем возвращает результат обратно в 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.

Ответ №4

Ответ №5

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

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

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

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

  1. Аватар Rock:

    Да простят меня те кто буду это читать)))

  2. Аватар Fray:

    Вопрос по второму заданию.
    Решил дописать в конце тела объявления функции multiply следующее: «return a * b;» и мне выдало следующую ошибку: «unused variable 'product'», что можно перевести как «неиспользованная переменная 'product'». Но какая разница какая переменная, ведь возвращаемое значение есть и это "return a * b".

    вот отредактированный код, чтобы лучше было видно:

    Однако если написать вместо "return a * b;" — "return product", то все сработает как надо.

    То есть, объявляя переменную в объявлении функции и присваивая ей определенное значение, нужно вернуть именно ее в caller? Потому что чтобы я не писал в return, мне выдавало ошибку «unused variable 'product'».

    Прошу прощения за свою невнимательность, если где то что то пропустил или мои вопросы звучат глупо, я еще в этом пытаюсь разобраться.
    Еще раз спасибо за предоставленные материалы.

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

      Проверил твой код, у меня все норм работает, ide — Visual Studio 2019 Community

    2. Аватар Никита:

      Скорее всего всё из-за настроек из предыдущих уроков. Если делали всё по урокам, то все Предупреждения(Warnings) распознаются как ошибки. В качестве Warning он ругается, дескать зачем объявили переменную, если не использовали вообще в функции — странно это, батенька. А так как Warning = ошибка при заданных по урокам настройках IDE, то он и не идёт дальше, сообщая об ошибке.
      Собственно ничего страшного нет и всё будет работать, но для этого автор и говорил о важности обращать внимания на предупреждения и подчищать хвосты.

    3. Аватар Spectre:

      По сути ты занял память переменной "product", которую не используешь, поэтому компилятор ругается, критической ошибки нет, просто ты нерационально используешь ресурсы.

  3. Аватар Asklepiy:

    Я параллельно вашим урокам начал читать другую литературу по С++. Где-то вычитал, что в идеале функция main() должна лишь вызывать другие функции, не принимая участия в вычислениях. Это верно?

    1. Аватар Руслан:

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

  4. Аватар ХейЛонг:

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

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

    И почему вы раньше мне не попадались??! От многих заумных фраз других сайтов в состоянии "Взрыв мозга"

  6. Аватар Вадим:

    Сколько лучше читать уроков в день? Что бы не загружаться лишний раз и запомнить то что я прочитал)

  7. Аватар Daler:

    это 4

    вот 5

  8. Аватар Oleg:

    Спасибо вам огромное за бесплатные уроки! Мне очень нравится, всё понятно и в конце каждого урока тест, а это важно. Я до этого немного изучал Java, поэтому мне пока что всё просто. Вот моё решение №5:

  9. Аватар Олег:

  10. Аватар Владимир:

    Я в шоке, это лучшие уроки что я видел. Очень просто о том, что ранее не вмещалось в башку. Пока все понятно, и тесты реально закрепляют знания. Спасибо!

    1. Юрий Юрий:

      Пожалуйста 🙂

  11. Аватар Владимир:

    Спасибо за это замечательное объяснение, подобного нигде не встретил,замечательно!

    1. Юрий Юрий:

      Пожалуйста)

  12. Аватар diflikator:

    Вариант выполнения задания №2.

  13. Аватар Владимир:

    Здравствуйте, я может что то не так делаю, но VS 19 не работает если имя тела программы какое то кроме как int main. int doubleNumber() вот так уже не работает только main? в чем может быть проблема?

  14. Аватар Aleksandr:

    Я все усложнил в 1000 раз, оказывается можно было намного проще код написать. Все верно получилось, но написал вот так:

    1. Аватар Sergey:

  15. Аватар Дмитрий:

    Чувак спасибо :))
    {
    благодарочка
    }

    1. Юрий Юрий:

      {
      Пожалуйста 😉
      }

  16. Аватар steyrin:

    Выдает ошибка "doubleNumber: функция не принимает 0 аргументов"

    1. Аватар Sergey:

      Как в поговорке a и b сидели на трубе)))

  17. Аватар Михалыч:

    альтернатива для пятого задания

    1. Аватар Innor:

      В задании было сказано: "Напишите функцию doubleNumber()". А вы её написали? Это задание ведь на проверку усвоения урока "Параметры и аргументы функции". Но согласен: путей решения задачи несколько.

    2. Аватар Vladimir Dal':

      Точно также решил

  18. Аватар Алексей:

    Немного другим путем пошел сразу после прочтения "В программировании есть много случаев, когда одну задачу можно решить несколькими способами."

    Подумал, так же и есть, а если…

  19. Аватар Steve Dekart:

    Я уже дошёл до этой темы и боюсь забыть прошлые темы. Боюсь что на 200 теме буду не помнить какую-нибудь там 30 тему

  20. Аватар Данис:

    А можете ли объяснить , я прост не понимаю почему в 3 задание в функции multiply b=5?

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

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

  22. Аватар yrneero:

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

    1. Юрий Юрий:

      Пожалуйста 🙂

  23. Аватар Eugen:

    Добрый день.

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

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

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

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

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

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

    2. Юрий Юрий:

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

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

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

    3. Аватар Alexey:

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

  25. Аватар Ray:

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

    1. Юрий Юрий:

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

  26. Аватар master114:

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

    1. Юрий Юрий:

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

  27. Аватар Parenochek1488:

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

    1. Юрий Юрий:

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

      1. Аватар Parenochek1488:

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

        1. Юрий Юрий:

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

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

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

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

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

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

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

    1. Юрий Юрий:

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

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

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

  31. Юрий Юрий:

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

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

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

    1. Юрий Юрий:

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

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

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

    1. Юрий Юрий:

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

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

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