Глава №1. Итоговый тест

  Юрий  | 

  |

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

 157872

 ǀ   96 

Данные задания призваны улучшить запоминание пройденного материала и показать его применение на практике.

Задание №1

Напишите однофайловую программу (с именем main.cpp), которая запрашивает у пользователя два целых числа, складывает их, а затем выводит результат. В программе должно быть 3 функции:

   функция readNumber(), которая запрашивает у пользователя целое число, а затем возвращает его в main();

   функция writeAnswer(), которая выводит результат на экран. Функция должна быть без возвращаемого значения и иметь только один параметр;

   функция main(), которая соединяет всё и вся.

Подсказки:

   Для выполнения операции сложения не нужно создавать отдельную функцию (просто используйте оператор +).

   Функцию readNumber() нужно вызывать дважды.

Ответ №1

main.cpp:

Задание №2

Измените программу из задания №1 так, чтобы функции readNumber() и writeAnswer() находились в отдельном файле io.cpp. Используйте предварительные объявления для доступа к этим функциям с функции main().

Подсказка: Если у вас возникли проблемы, убедитесь, что io.cpp правильно добавлен к вашему проекту и подключен к компиляции (см. Урок №20. Многофайловые программы).

Ответ №2

io.cpp:

main.cpp:

Задание №3

Измените программу из задания №2 так, чтобы она использовала заголовочный файл io.h для доступа к функциям (вместо использования предварительных объявлений). Убедитесь, что ваш заголовочный файл использует header guards.

Ответ №3

io.cpp:

io.h:

main.cpp:

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

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

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

  1. Лев Мираж:

    Решил первую задачу, вот собственно и сам код:

  2. Jenia:

    Первое задание сделал вот так:

  3. Давид:

    первое задание сделал вот так.

    все нормально работает.

  4. Рома:

    Во время выполнения заданий я открыл для себя одну вещь. Пользователь вводит два числа за один раз, при этом функция readNumber срабатывает два раза:

    файл io.cpp

    файл io.h

    файл main.cpp

  5. Егор:

    Сидел и думал над первым заданием 10 минут, все получилось, я рад)

    1. Егор:

      Блин, я забросил учиться, и вот заново начал и дошел до этого момента и вот что получилось:

      И вот я пересмотрел свой первый код, и мне кажется, что я сильно перемудрил и даже не понял что на "кодил", я сейчас сделал намного проще.

  6. Алексей:

    Добрый день!
    Первое задание выполнил вот так. Правильно ли? Прошу прокомментировать
    Код программы:

    1. SerJ:

      Never use translit! Никогда не используйте транслит.

  7. Гога:

    Вопрос по заданию 3. Сделал так-же, как и в ответе , но в main.cpp подключал <iostream> и всё работает. Увидел что в ответе не подключается, убрал — работает. Не понимаю, почему, ведь в main.cpp мы подключаем только io.h, а в нем только функции объявлены, iostream и io.cpp туда не "инклудится" ?

    1. Фото аватара Юрий:

      Библиотеку iostream мы подключаем в io.cpp, потому что в этом файле используются объекты cout и cin (которые могут работать только при подключенной библиотеке iostream). Файл io.cpp подключается к проекту, в котором находятся файлы main.cpp и io.h, поэтому дополнительно подключать файл io.cpp из кода программы не нужно (нужно только правильно подключить данный файл к проекту через IDE).

      Библиотека iostream подключается единожды в проекте, т.е. вы можете "инклудить" iostream только в одном файле, а действие библиотеки распространится на весь проект. Следовательно, в файле main.cpp нет нужды подключать второй раз библиотеку iostream. По логике вещей, если подключить любую библиотеку в один и тот же проект более 1 раза, то компилятор должен выдать предупреждение/ошибку.

      + в файле main.cpp мы не используем объекты, для которых требуется подключение библиотеки iostream.

      1. Никита:

        Почему тогда если добавить еще один фаил в проект, допустим такой же как наш io.cpp, который будет запрашивать третье значение у пользователя, и дописать его везде где нужно, но в нем не прописывать #include <iostream> — то выдаст ошибку при сборке? Как только дописываем #include <iostream> — все работает.

        io.cpp

  8. Gevorg:

    main.cpp

    io.h

    io.cpp

    При выполнении выдает ошибку:
    1>io.obj : error LNK2005: "int __cdecl readNumber(void)" (?readNumber@@YAHXZ) уже определен в main.obj
    1>io.obj : error LNK2005: "void __cdecl writeNumber(int)" (?writeNumber@@YAXH@Z) уже определен в main.obj
    1>Debug\io.obj : warning LNK4042: объект указан более одного раза; лишние не учитываются
    1>C:\Users\Dante\source\repos\educ\Debug\educ.exe : fatal error LNK1169: обнаружен многократно определенный символ — один или более

    Что делать?

    1. Константин:

      У вас первые строчки в main.cpp и io.cpp перепутаны местами. В main записывается #include <iostream>, в io @include "io.h"

  9. Никита:

    Не могу все понять, как функции из io.cpp попадают в main.cpp (2 задание). Программы мы нигде не связали, но функции все равно определяются отдельно и работают..

    1. eumenth:

      Либо вручную(G++), либо IDE (Visual studio) автоматом добавляет файлы из проэкта для компиляции.
      Таким образом файлы попадают в один исполяемый файл.

      Компоновщик (линкер) связывает все объектные файлы и статические библиотеки в единый исполняемый файл, который мы и сможем запустить в дальнейшем.

  10. Alexandr:

    Доброго времени суток ,решил первые два задания.Хотелось бы спросить,что не так?

    1 — задание

    main.cpp

    2 — задание

    io.cpp

    1. Alexandr:

      и третье задание.

      io.h

      1. Алексей:

        в файле io.cpp заменить int writeAnswer() на void writeAnswer(), так как функция ничего не возвращает, а у вас она возвращает 0

  11. Ezio575:

    Первое задание

  12. debeqp:

    main.cpp

    io.cpp

    io.h

    Просто и элегантно.

    1. Adiana:

      Ошибочка у вас. Из io.h необходимо убрать инициализацию переменной a. Так же убрать int "readNumber();" оттуда же, поскольку эта функция и так находится в области видимости функции writeAnswer();
      А теперь в идеале: заменить функцию writeAnswer() из int на void (поскольку нам не требуется чтобы она возвращала значение). То же самое — int main() поменять на void main(). Поубирать ретурны где не надо.

      1. Тим:

        в уроке говориться, что int main предпочтительнее)

  13. Alexandr:

    Юрий,доброго времени суток,хотел бы спросить по поводу первого задания,и правильно ли я его понял,заранее спасибо за ответ,очень благодарен 🙂

    Вот сам код:

    1. Adiana:

      В функции int main() стоит убрать лишний вызов функции readNumber(), её уже вызывает функция writeAnswer().

      Из функции readNumber() стоит убрать строчку:

      и дополнить:

      Тогда все будет правильно.

  14. vova1227:

    /* вот так сделал. компилятор не материться. прошу ответить возможен ли такой вариант и есть ли здесь ошибки */

    PS; Сначала не хотел делать задания, типа понятно все и так. Потом думаю дай попробую. Провозился около 1.5 часа, то точку ; , то в линкинге ошибся. Оказалось что файл нужно «исключить из проекта» в пункте меню, а не как я просто закрыть))

    1. Adiana:

      Лайфхак — в функции writeAnswer() в вашем случае не обязательно создавать переменные. Их можно просто убрать, все что нужно функции:

      Иначе теряется смысл использования функций.
      Еще один лайфхак: void main()

  15. AHTOH:

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

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

  16. Александр:

    Спасибо!
    Всё получилось.
    Правда, пришлось кое-где возвращаться и исправлять ошибки ( в основном — в настройках VS2019.
    Был вопрос с выводом в консоли русского текста — тоже решил, покопавшись в комментариях к "Решениям распространённых проблем…" (решилось изменением шрифта в настройках консоли).
    Рад, что влез в эти уроки.
    Всем — добра))

  17. Pavel:

    Получилось как то так:

    main.cpp:

    source.h:

    source.cpp:

  18. Вячеслав:

    Добрый день,
    у меня получился следующий код:

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

      Вопрос по ответу- почему в параметре функции void writeAnswer() записана int x. ведь это один аргумент который этой функцией выводится на экран.ведь можно было в main() создать переменную допустим z которая равнялась x+y. И тогда в параметре writeAnswer() записали бы int z. и соответственно в самом теле .А так я не пойму- мы в параметре записали int x. И программа работает. Почему?

  19. Андрей:

    Файл A.cpp:

    Файл B.h:

    Файл main.cpp

    P.S мне компилятор помогает)
    Я могу не писать хедер гварды)
    так коротко и ясно)

  20. Sagynysh:

    Первое задание у меня получилось вот так 😀
    Вроде всё корректно

    1. Andrey:

      У вас не правильно так как вы умножаете целое число на два, вместо того, чтобы выводить сумму двух целых чисел. То есть пользователь может ввести 4 + 5 = 9, а у вас будет 4*2 = 8

  21. ХейЛонг:

    А у меня получилась совсем новая концепция. Я не сразу понял, что сумму нужно передавать аргументом. Хотя учитывая ограниченный функционал этой тестовой работы, я не хочу считать мой вариант некорректным. По крайней мере оно скомпилировалось и выдаёт адекватный результат.

  22. александр:

    немного непонятен момент: почему в нашем тесте тип возврата " void writeAnswer(int x)" мы не можем написать без инициализации ( типа вот так — void writeAnswer( )). а с "int" такого не происходит. Пожалуйста объясните! Спасибо!

    1. Константин:

      (int x) — энто такая ловушка, созданная в функции, для улавливания аргумента, пуляемого коллером — здесь значение будет схвачено и отхвуячено согласно "Протоколам сионских мудрецов":-)шутка — обработано стейтментами, прописанными в колли (Caller -> Callee)

  23. A-Lex:

    (не судите строго за имена переменный — писал на работе, спешил)
    Первое задание получилось както так:

  24. Андрей:

    По другому не смог решить первое задание 😛

    1. Юра:

      Андрей, попробуйте применить функцию readNumber1() для ввода значения х и значения y в int main(). Получится, что readNumber2() не нужна.

  25. Алексей:

    1. Андрей:

      Жестка

  26. Steve:

    Качественные и бесплатные уроки. Написано все доходчиво, простым языком с детальным разъяснением, в отличие от некоторых книг, якобы для "начинающих". Огромное спасибо за ваш труд. Ставлю 5 звёзд под каждым уроком 🙂

    1. Фото аватара Юрий:

      Спасибо! Очень приятно)

  27. Максим:

    1. Максим:

      Я короче понял. Это у вас ошибка в ответе на первое задание с void и int

      1. Денис:

        Это у вас ошибка.
        Никакого return x там не надо.
        Функцию требовалось объявить void.

  28. Максим:

    Спасибо за уроки и потраченное время на их создание. Пока что в первой главе всё понятно. Я пытался выучить c++ до этого по другим урокам, но там почти ничего не понятно.

    1. Фото аватара Юрий:

      Пожалуйста))

  29. zevs:

    Что то не понимаю, если количество аргументов должно совпадать с количеством параметров, то почему writeAnswer с двумя аргументами в main компилируется, при том, что в определении функции writeAnswer, мы указали один параметр. Т.е параметр один а аргументов два.

    1. ShnokDog:

      Нет, вы передаёте параметр в виде суммы то есть сперва x прибавится к y потом полученное число передастся в виде одного аргумента!

      1. zevs:

        В таком случае каким образом сумма выражения x + y из main(), присваивается переменной(?) X в функции writeAnswer() ? И вообще является ли X переменной, т.к в функции writeAnswer() мы ее нигде не определяем. Так каким образом компилятор узнает что результат вычисления выражения x+y, надо присваивать X ( что это вообще?)
        Или же int x, которую мы указываем в параметре функции является неинициализированной переменной, и результат вычисления автоматически присваивается ей? В таком я просто этого не знал, т.к раньше об этом в этом курсе не писалось.

        1. zevs:

          Я просто как прочитал задание сразу понял как это реализовать через возвращаемую функцию,

          И соответственно с двумя аргументами у вызываемой функции из main()

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

  30. Алексей:

    Немного тупил в первом задании, но все сразу.
    Единственное — сам делаю с помощью vim в Убунту, мне надо включить в файл .h io.cpp.

    Сам код:

    По ответу у меня ошибка.

    /tmp/cccxYR0a.o: In function main':
    main.cpp:(.text+0x9): undefined reference to
    readNumber()'
    main.cpp:(.text+0x11): undefined reference to readNumber()'
    main.cpp:(.text+0x23): undefined reference to
    writeAnswer(int)'
    collect2: error: ld returned 1 exit status

    1. Алексей:

      Замечание по 3му тесту.
      Я уже за 37м уроком, но повтор не помешает. Тренировка, как-никак.

      Так вот — я один раз объявил х для пустотной функции и этого достаточно.
      Компилится, считается, проблем нет.

  31. zashiki:

    Здравствуйте, насчет 1го вопроса: у меня вариант ниже, результат правильный, НО выходит такое:

    введите число: 8
    введите число: 7
    сумма: 7+8=15

    Почему числа в сумме меняются местами, никак не могу сообразить?

    Сам код:

    спасибо

    1. zashiki:

      а, проглядела, что writeAnswer должна быть с одним параметром. Но все равно остается вопрос.

      1. Nikita:

        Аналогичный фейл с моментом что переменные меняются местами. В операциях суммирования и умножения это не проблема. А вот разницы и деления…

        1. Алексей:

          У вас в строка "writeAnswer(readNumber(), readNumber());" компилятор не читает справа налево, а вначале запрашивает второй параметр потом первый, но вы этого понять не можете поскольку функция одна и та-же.

        2. zashiki:

          Алексей, извиняюсь за свою тупость, но:

          1) если он запрашивает сначала 2й параметр, то почему выводит сначала 1 параметр, потом 2й, а потом уже складывает 2й+1й?

          2)если разные функции в параметрах writeAnswer(g1(), g2()), то получается та же фигня,
          НО если в этих функциях возвращается сразу число, к примеру, а=1 или return 1, то все норм…

        3. Алексей:

          Объясняю (хотя каюсь все еще не запускал компилятор и все только рассуждения как должно быть) вы пишете:
          "writeAnswer(readNumber(), readNumber());"
          в водите 8 затем 7 и поскольку вначале запускается вторая функция то это будет тоже что:
          "writeAnswer(7, 8);" — первая вызвалась функция readNumber() во втором параметре ! если хотите убедится надо сделать не только функции с разным именем, но и с разным текстом запроса "Введите число 1" и "Введите число 2".
          Сама функция writeAnswer(7, 8) параметры не переставляет у нее все четко расписано как есть "a" есть "b" и выводит все правильно как в ней записано 7+8, ошибка в том что вы думаете что первое число которое вы вводите оно подставляется в функцию первым, а на самом деле вы вводите 2-рой параметр функции.

    2. Andrew:

      zashiki, добрый день.
      Не смогли бы вы прокомментировать смысл этого фрагмента:

      Спасибо. С увжением.

  32. Анастасия:

    У меня всё получилось сделать ровно за 20 минут. Смущает, что нельзя прописать #include <iostream> только в главном файле (в одном месте), странно, что его нужно прописывать в каждом файле с функциями, которые могут его использовать.

  33. Илья:

    Здравствуйте!
    Спасибо за Ваши труды!
    У меня к Вам такой вопрос (может быть я где то упустил этот момент, если так, прошу просто скинуть ссылку=) ): у Вас в программе в исполнительных файлах обращение к <iostream> то есть, то нет, в итоге не понятно, когда есть необходимость подключать данную библиотеку, а когда нет? Не понимаю от слова совсем=)
    Я создал main файл, в нем вбил #include "pch.h" и #include <iostream>, потом создал (по аналогии с вашим примером) исполнительный файл io уже без использования данных директив, в итоге получил сбой ещё на этапе компиляции. добавил #include "pch.h" и #include <iostream> — всё заработало. попробовал убрать только #include <iostream> — программа продолжила стабильно работать. т.е. проблема именно в отсутствии #include "pch.h"?
    Но, если я правильно понял статью, то когда мы создаем исполнительный файл, main остаётся своего рода главным файлом, обращаясь лишь к информации в исполнительном, соответственно зачем ему директивы в исполниловке? Он вроде как должен читать код другого файла, использую свои директивы?
    И про заголовочные файлы тоже немножко путаница в голове.
    В общем, про многофайловые программы есть множество вопросов, был бы премного благодарен за ответы. И, если честно, думаю, Ваша аудитория была бы Вам тоже очень благодарна, если бы Вы сделали отдельный урок или статью о том, как заголовочные и исполнительные файлы взаимодействуют между собой. Ну т.е. подробно: какой файл к какому обращается, как они зависят друг от друга, можно ли с помощью заголовочного файла подключить библиотеки к исполнительным, или может это можно сделать с помощью другого файла. Было бы очень интересно понять этот процесс с точки зрения железа — как оно обрабатывает эти файлы.

    Извините, если комментарий получился очень большим=)Просто очень хочется разобраться=)

    1. Константин:

      Илья, ты объявления, стоя на остановках, читал? Вот заголовочный файл (с расширением .h) это то же объявление с остановки. В нём прописано нечто тебя интересующее и доступ к нему. По прописанному ты устанавливаешь доступ и получаешь интересующее тебя. Переходишь к следующему объявлению и всё повторяешь. Некоторые объявления написаны от руки, поэтому они в "таких" кавычках, некоторые напечатаны в типографии поэтому они в <таких> кавычках. Например, вызываешь функцию girlByCall(). В объявлении указано: love girlByCall(long long double siski, char pussy); love — это тип возвращаемого значения (т. е. ты от неё получаешь любовь), long long double siski & char pussy — это её параметры, в которые ты передаёшь свои аргументы — денежные знаки. А void — это например собственные дети — ничего тебе не возвращают, но аргументы ты им передаёшь. Ещё вариант — вызов например "Скорая Медицинская помощь": help ambulance(); , которая хранится в библиотеке предварительно скомпилированных заголовков <call911> и приклеена к столбу (как и все другие заголовочные файлы) клеем #include. Ну и последний вариант: void commentaryIntoInternet(); — ты не передаёшь туда никаких денежных значений и не ждёшь оттуда никаких поступлений. Просто комментарий живёт своей жизнью и производит какое-то воздействие на читателя… Я так себе это всё представляю.

  34. Эрик:

    Спасибо за уроки, сделал с первого раза. Была проблема с директивами и препроцессором в этой главе, пришлось обращаться к сторонним видео урокам, чтобы въехать в суть. Но в основном все легко усваивается. Спс)

  35. nickatin:

    Получилось даже без ошибок. И все благодаря очень подробным урокам)

  36. Антгон:

    Хотел немного усложнить задание и добиться, чтобы в строке вывода был не просто результат сложения, а, например, так:
    Итого: 5 + 6 = 11
    При написании в main строки

    все показывает как мне нужно, но при попытке написать код для функции void writeAnswer все идет кувырком. Перепробовал кучу вариантов, но без результата.
    Пожалуйста, подскажите, как сделать правильный код для функции, чтобы при компиляции появлялся именно такой результат!

    1. Константин:

      Про побочные эффекты читал? Делай минимум действий в каждом стейт-менте — тогда и кувырки в прог-е меньше отжигать будут.

    2. Alexey:

      Скорее всего из-за того, что вы отправляете на в функцию печати всего одно значение, а хотите использовать все 3. Измените функцию так, чтобы она получала все 3 значения.

  37. GAS:

  38. Лёха:

    То чувство, когда все на изи этот тест пишут, а я ни одного задания не сделал, половину кода не понимаю. Придётся заново всё перечитывать, пока не начну понимать 🙁

  39. ufo:

    Пример хороший но не логичнее ли будет вписать #include <iostream>в io.h (а также все нужные инклюды которые могут потребоваться для других функций).
    После чего в io.cpp и в main.cpp в инклюдах надо писать только #include "io.h" (вместо дублирования инклюдов а их может быть много, тем более у нас хеадергвард прописан)
    врезультате например std::cout<<"ALL OK"; в конце main будет работать.

  40. Руслан:

    а таким способом будет правильно?

    1. Steve Dekart:

      Нет, там говорится использовать только 3 функции, а не 4.

  41. Andrey:

    Решил «тупо» переписать ответы на тесты, что бы набить руку.(Итоговый тест 1). Первое задание откомпелировалось без проблем. А второе из 2-х файлов никак не компилируется. И в первом и во втором случае выдаёт ошибку 1010 и советуе добавить #include ‘’stdafx.h’’, но я точно копирую ответ. В чем прикол? Я полный ‘’чайник’’, но тема зашла, хочется дойти до сути.

  42. Рома:

    Здравствуйте, в 3 задании сделал точно также как и у вас в ответе, но мне выдает две ошибки :
    1) идентификатор readNumber() не определён
    2) идентификатор writeAnswer() не определён
    в чём может заключаться проблема?
    Проверял уже много раз код один в один с вашим .

    1. Алексей:

      Тут 2 варианта. Либо в main.cpp не прописан файл заголовка (#include "io.h"), либо в файлезоголовка не объявлены указанные функции. Подробнее здесь: Урок 21. Заголовочные файлы.

    2. Эрик:

      Подключение io.h идет до подключения <iostream>?

      1. Рома:

        Эрик, спасибо огромное, у меня в принципе #include <iostream> не был подключен в этом была вся проблема , не понимаю как я упустил это, ещё раз огромное спасибо )))

      2. Алексей:

        Файл заголовка можно подключить и до и после jostream.

  43. Tahir:

    Отличный тест. Без лишней теории и охватывает все основные аспекты Главы1. Спасибо за Ваш труд!

    1. Фото аватара Юрий:

      Спасибо, что читаете 🙂

  44. Даниил:

    Здравствуйте , такой вопрос )
    Во второй функции мы вводим одну переменную x
    А в функции main() мы выводим эту функцию и (x+y)….
    Уточните пожалуйста что здесь и как )

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

      А что там не понятного? Мы вызываем функцию writeAnswer() А "x+y" — это параметр этой функции, который равен сумме x и y, и вот это значение присваивается переменной x в функции writeAnswer() Просто нужно внимательно читать уроки. У каждой функции своя переменная с именем "X" (в каждом городе есть своя улица Ленина)

    2. Алексей:

      Все просто. Каждая из предстваленных функций "не знает", что одноименные переменные есть в других функциях.
      Подробнее тут: Урок 15. Локальная область видимости.

  45. Алекей:

    Есть недочет. После каждого урока надо штук по 10 практических заданий для закрепления материала. Все получилось с первого раза! Но практики очень не хватает.

    1. Максим:

      Согласен, это уже будет полировка, а так все хорошо.

    2. Константин:

      Да-да, полностью поддерживаю Алексея: Юрий, пожалуйста, прибавьте контрольных заданий, а то как-то мало связей между нейронами образуется у меня в голове от одного задания:-(

  46. илья:

    у меня в 1задании 39 ошибок, придется кодить сначала

  47. Игорь...:

    Прикольно, первое задание выполнил так же как и в ответе, кроме…

    Работает… Но правильно ли так?

    1. Фото аватара Юрий:

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

      1. Nikita:

        Я когда сделал вот так как на скрине (похоже), у меня почему то 1я и 2е число меняются местами. Например деление, происходит 2ого числа на 1е, и так и не понятно почему(

  48. Diana:

    В итоге все получилось, не без ошибок, конечно, но получилось) очень рада) спасибо за Ваш труд!)

    1. Фото аватара Юрий:

      Пожалуйста 🙂

  49. Дима:

    Хм….урок без коментов.
    У всех все просто получилось?!)

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

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