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

  Юрий  | 

  |

  Обновл. 24 Окт 2020  | 

 62009

 ǀ   34 

В этой главе мы рассмотрели много материала. Если вы дошли до этого момента, то я вас поздравляю — вы проделали немало работы и это уже хороший шаг на пути к изучению языка C++ в частности и программированию в целом! Сейчас же давайте закрепим пройденный материал.

Оглавление:

Теория

Блок стейтментов (или «составной оператор») обрабатывается компилятором так, как если бы это был один стейтмент. Составные операторы помещаются в фигурные скобки { и } и используются почти везде.

Локальные переменные создаются в точке определения и уничтожаются при выходе из блока, в котором они объявлены. Доступ к ним возможен только внутри этого же блока.

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

Ключевое слово static может использоваться для преобразования глобальной переменной во внутреннюю (с внутренней связью), чтобы её можно было использовать только в том файле, в котором она объявлена. Также ключевое слово static используют для указания того, что локальная переменная должна иметь статическую продолжительность жизни. А это означает, что она будет сохранять свое значение даже после выхода из своей области видимости.

Пространство имен — это область, в которой гарантируется уникальность всех имен. Отличный способ избежать конфликтов имен. Не используйте using-стейтменты вне тела функций.

Неявное преобразование типов данных происходит, когда один тип данных конвертируется в другой тип без использования одного из операторов явного преобразования. Явное преобразование типа происходит, когда один тип данных конвертируется в другой с помощью одного из операторов явного преобразования. В некоторых случаях это абсолютно безопасно, в других случаях данные могут быть потеряны. Избегайте использования конвертации C-style, вместо нее используйте оператор static_cast.

std::string — это простой способ работы с текстовыми строками (текст помещается в двойные кавычки).

Перечисления позволяют создавать собственные (пользовательские) типы данных. Классы enum — это те же перечисления, но надежнее и безопаснее. Используйте их вместо обычных перечислений, если ваш компилятор поддерживает C++11.

typedef позволяет создавать псевдонимы для типов данных. Целочисленные типы данных с фиксированным размером реализованы с помощью typedef. Псевдонимы типов полезны для присваивания простых имен сложным типам данных.

И, наконец, структуры. Они позволяют сгруппировать отдельные переменные в единое целое. Доступ к членам структуры осуществляется через оператор выбора членов (.). Объектно-ориентированное программирование в значительной степени основывается именно на структурах, поэтому, если вы изучили только одну вещь из этой главы, то лучше, чтобы это были структуры.

Тест


При разработке игры мы решили, что в ней должны быть монстры, потому что всем нравится сражаться с монстрами. Объявите структуру, которая представляет вашего монстра. Монстр может быть разным: ogre, goblin, skeleton, orc и troll. Если ваш компилятор поддерживает C++11, то используйте классы enum, если нет — обычные перечисления.

Каждый монстр также должен иметь имя (используйте std::string) и количество здоровья, которое отображает, сколько урона он может получить, прежде чем умрет. Напишите функцию printMonster(), которая выведет все члены структуры. Объявите монстров типа goblin и orc, инициализируйте их, используя список инициализаторов, и передайте в функцию printMonster().

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

This Goblin is named John and has 170 health.
This Orc is named James and has 35 health.

Ответ C++11

Ответ до С++11

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

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

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

  1. Сашуня:

    Задание:

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

    Со второго раза получилось так

    PS.
    C удовольствием провожу время на пенсии, большое спасибо разработчикам сайта. Жаль в начале 80 нас не учили программированию.

    1. Илья:

      Решение неплохое, но есть один недочёт. В функции вывода написан несчастный cout пять раз, хотя меняется в нём только одно поле — название типа монстра. Гораздо лучше вычислить его заранее — в отдельной функции и просто подставлять результат её выполнения. Любой множественный повтор должен вызывать мысль оптимизировать код, это упрощает его поддержку в дальнейшем.

  3. Андрей:

    Немного расширил задание. Выводит класс монстра при правильном вводе названия класса монстра в консоль.

  4. Anton:

    написал версию с выбором любого из 5 предоставленых мобов, вывод значения переменной enum только в виде int конечно все портит)

  5. Fray:

    Потому как в задании было сказано, что "Каждый монстр также должен иметь имя и количество здоровья, которое отображает, сколько урона он может получить, прежде чем умрет.",
    я понял что должно быть только два члена структуры и не учел слова "также", что подразумевалось больше чем два члена структуры. Изначально хотел написать с тремя: тип монстра, имя монстра и количество хп, но умудрился написать только с двумя членами структуры. Прошу прощения, если что то неправильно написал. Хочу поблагодарить автора за эти уроки. Спасибо!

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

    Собственно не понятно следующее: ожидаю что строка

    будет возвращать хотя бы Тип: MonstersType::ogre. Это не красиво, но хотя бы логично. Но фактически от такого варианта программа ломается и компиляция не происходит. Приходится городить if/else, что на мой взгляд портит всю прелесть соединения перечислений со структурой. Почему так? Можно ли сделать вывод di.type по другому, без использования if/else?

  7. Flaca:

    Тоже микро игру сделал

  8. Руслан:

  9. VEX:

    Капец, сделал архитектуру программки, все сделал правильно, а в итоге получил 9 ошибок и 5 сообщений, а как только поменял местами структуру и перечисление типов монстров, все стало работать отлично.

  10. Владимир:

    Сделал небольшую игру)

  11. Владимир:

    Не судите строго, пожалуйста)

  12. Андрей:

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

    Объясните пожалуйста.

    p.s я в ответ не заглянул,ибо не хочу списывать.

    1. Сергей:

      Понимаю,что код плохой, но я только начал программировать.

  13. Yerdurshlak:

  14. Марат:

  15. Владимир:

  16. Aur1IIad0r:

    // Example program

  17. Илья:

    Добрый день!
    Знаете, если честно, я так и не понял преимущества использования enum. Я написал две программы. Принципиально с enum, чтобы разобраться с ними, и без enum, так, как на мой взгляд проще. И могу сказать, что без enum действительно получилось намного проще и, на мой взгляд, код тоже читать проще.
    Вот и сижу, мучаюсь догадками. Есть три предположения=))
    1) Вы плохо объяснили все преимущества перечислителей. В этом я сильно сомневаюсь, т.к. всем предыдущие уроки прошли на ура, Вы очень хорошо расписываете материал=)
    2) "На вкус и цвет товарищей нет" — т.е. каждый работает по своему, у каждого свои принципы работы и каждый делает так, как ему удобно (не пренебрегая, конечно, общими правилами, чтобы други могли разобраться в коде)
    3) Перечислители действительно не так уж и полезны, как утверждают некоторые кодеры=)
    Очень интересно узнать Ваше мнение по этому поводу=)Заранее спасибо!
    Вот те самые программы с enum и без (программа без enum была написана последней, поэтому в ней, опять же на мой взгляд, лучше подобраны имена переменных и т.п.). Без перечислителей:

    ____________________________________
    Вариант с enum:

    1. Алексей:

      Возможно, экономия памяти. Если к примеру известно что переменная может хранить значение только "Самолёт взлетел", "Самолёт летит" и "Самолёт приземлился", "Самолёт разбился",то для этого можно использовать перечисление. Тогда переменная будет иметь объём 4 байта (на моём компиляторе, VS 2019 Windows 10 x64, на другом может быть будет по-другому). Причём даже не важно, будут строки эти длиннее или короче, чем мною приведённые. А если использовать для этого строки, то понадобится не меньше 20 байт. Но это опять таки только догадка, возможно, у перечислений есть ещё какие-то преимущества.

      PS. В универе нам тоже не объяснили накой перечисления сдались. Зато во всю заставляли использовать)))))

    2. Николай:

      Перечисления — это один из подходов по избавлению от "магических чисел" в коде. "Магические числа" на то и магические, что они выполняют какую-то непонятную магию в программе. enum позволяет раскрыть секреты этой магии, но при этом не запрещает использовать "магию" неправильно (присвоить значение, не входящее в набор определенных инструментов "магии"). enum class начиная с C++11 позволяет взять эту магию под полный контроль, т.е. неправильное использование магии требует дополнительных осознанных действий, т.е. ты знаешь, что собираешься делать.

      Другое объяснение enum. Ни для кого не секрет, что enum — это другое представление перeменных типа int. Только в отличие от int, где все значения диапазона обезличены, в enum определен очень сильно ограниченный набор чисел из диапазона int, при этом каждое такое значение уже имеет свое лицо или назначение.

      Какой из подходов использовать, начиная с С++11: enum или enum class, — зависит от назначения. Если с данными числами нужно будет выполнять арифметические операции и трансляция в другие формы (передача в структуре протокола), то проще использовать enum. Если планируются только операции чтения и записи, то предпочтительнее использовать enum class. Например, enum class очень хорошо подходит для хранения кодов ошибок: набор строго ограничен, арифметические операции не требуются, выполняются только операции чтения и записи, если нужно передать по протоколу, то достаточно одной операции преобразования типа.

  18. Alexey:

    Игра против компьютера…

  19. Владимир:

  20. Дмитрий:

    Так же решил создать мини игру, на основании изученного с данного сайта материала.
    Комментировал на сколько мог, надеюсь кому то пригодится для разбора.
    Спасибо автору сайта, за предоставленную возможность.
    П.С. Циклы просматривал до этого, с другого сайта (но мельком). 🙂

    1. zvezdonom:

      В строке

      опечатка/ошибка.
      Должно быть

  21. rpa4:

    Вот, исходя из всех уроков 4-й главы, сделал такую вот игру с монстрами. Прошу прощения за длинный код.

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

      Реально прикольно получилось 🙂 Долго делал?

      1. rpa4:

        Ну где-то часик 🙂

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

          Нормально.

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

          Уважаемый rpa4! Подскажите мне, пожалуйста, как Вы кодите предложение, в котором тип монстра задаётся буквами, а не как у меня — числом:

    2. Игорь:

      Тоже была такая же идея) Но я что-то не пойму, я что, где-то пропустил циклы в предыдущих уроках?

  22. Герман:

    Уважаемый автор, какой смысл функцией getMonsterTypeString(Monster monster) проверять логические условия, если типы "монстров" и так объявлены в enum class MonsterType?
    Заранее спасибо!

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

      В getMonsterTypeString мы присваиваем значения для MonsterType::GOBLIN и MonsterType::ORC — Goblin и Ork соответственно. Если бы мы не использовали getMonsterTypeString, то вместо MonsterType::GOBLIN выводилось бы 1, а вместо MonsterType::ORC — 3. Функция getMonsterTypeString — это инициализация элементов структуры и заодно проверка.

      1. Герман:

        Про инициализацию элементов структуры я не сообразил. Спасибо!

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

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