У цьому розділі ми розглянули багато матеріалу. Якщо ви дійшли до цього моменту, то я вас вітаю — ви пройшли досить чимало і це вже хороший крок на шляху до вивчення 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
#include <iostream> #include <string> // Визначаємо класс enum з типами монстрів enum class MonsterType { OGRE, GOBLIN, SKELETON, ORC, TROLL }; // Наша структура представляє одного монстра struct Monster { MonsterType type; std::string name; int health; }; // Повертаємо тип монстра у вигляді рядка std::string getMonsterTypeString(Monster monster) { if (monster.type == MonsterType::OGRE) return "Ogre"; if (monster.type == MonsterType::GOBLIN) return "Goblin"; if (monster.type == MonsterType::SKELETON) return "Skeleton"; if (monster.type == MonsterType::ORC) return "Orc"; if (monster.type == MonsterType::TROLL) return "Troll"; return "Unknown"; } // Виводимо інформацію про монстра void printMonster(Monster monster) { std::cout << "This " << getMonsterTypeString(monster); std::cout << " is named " << monster.name << " and has " << monster.health << " health.\n"; } int main() { Monster goblin = { MonsterType::GOBLIN, "John", 170 }; Monster orc = { MonsterType::ORC, "James", 35 }; printMonster(goblin); printMonster(orc); return 0; } |
Відповідь до С++11
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
#include <iostream> #include <string> // Визначаємо перерахування з типами монстрів enum MonsterType { MONSTER_OGRE, MONSTER_GOBLIN, MONSTER_SKELETON, MONSTER_ORC, MONSTER_TROLL }; // Наша структура представляє одного монстра struct Monster { MonsterType type; std::string name; int health; }; // Повертаємо тип монстра у вигляді рядка std::string getMonsterTypeString(Monster monster) { if (monster.type == MONSTER_OGRE) return "Ogre"; if (monster.type == MONSTER_GOBLIN) return "Goblin"; if (monster.type == MONSTER_SKELETON) return "Skeleton"; if (monster.type == MONSTER_ORC) return "Orc"; if (monster.type == MONSTER_TROLL) return "Troll"; return "Unknown"; } // Виводимо інформацію про монстра void printMonster(Monster monster) { std::cout << "This " << getMonsterTypeString(monster); std::cout << " is named " << monster.name << " and has " << monster.health << " health.\n"; } int main() { Monster goblin = { MONSTER_GOBLIN, "John", 170}; Monster orc = { MONSTER_ORC, "James", 35}; printMonster(goblin); printMonster(orc); return 0; } |