6 етапів на шляху до С++ інженера. Основні теми та нюанси
Привіт! Мене звати Єгор Великожон, я працюю Software Engineer у SoftServe близько 2 років і приблизно стільки ж програмую на С++. Від знайомих та колег часто чув питання — як почати програмувати на С++? І кожен раз раджу подумати, для чого вам С++.
Так, «плюси» хороша перша мова через те, що використовує багато механік, зав’язаних на операційних системах, і є низькорівневою. Але цей бонус потребує додаткових зусиль. Як людина, що вибрала С++ першою мовою і зараз з нею працює, можу виділити декілька причин для обрання цього шляху:
- Знаючи С++, набагато легше вивчити будь-яку іншу мову програмування.
- Глибоке розуміння пам’яті комп’ютера.
- Глибоке розуміння структур даних.
- Можливість перейти як до інших низькорівневих мов, так і до високорівневих.
Якщо ви розібралися зі своєю мотивацією, то почнімо заглиблюватися в основи. У статті ми розберемося, які перші кроки та теми необхідні для вивчення С++.
Окей, вважатимемо, що ви вже обрали С++. Що далі?
Для початку потрібно налаштувати своє оточення. Найпростіший варіант — використання Visual Studio на Windows. У такому випадку ви уникнете проблем з налаштуванням проєкту через Makefile або CMake під час роботи на POSIX системах. Але фактично код можна писати на будь-якій платформі, просто у кожної своя специфіка. Гайд для подібного ви можете знайти інтернеті — їх купа як текстових, так і відеоінструкцій.
Добре, найскладніший крок — почати щось робити — ви вже виконали, тепер залишилися дрібниці — все інше. Моя основна порада — не орієнтуйтеся тільки на один гайд/ курс, а шукайте інформацію всюди. У цій статті я розповідатиму про основні теми, що необхідно знати та розуміти. Ваша ж мета — для кожної з них знаходити інформацію, статті тощо, а потім — експериментувати. Лише через власний досвід знання відкладуться у довгострокову пам’ять.
І невелика нотатка особисто від мене — будь-який код, який напишете, це чітка інструкція для машини, і вона послідовно виконуватиме її. Ніякої магії тут немає, все відбувається за описаним в програмі порядком. Якщо у вас щось не працює, не варто будувати здогадки: просто сядьте і послідовно, рядок за рядком, у голові продумайте, що саме БУДЕ (а не «повинно» бути) виконано. Це допоможе уникнути втрати часу.
Етап 1. Основні концепції мови
Змінні та типи даних
Це перша і, ймовірно, основна тема. Для зручності почнемо зі змінною. Фактично, це просто певна ділянка пам’яті, куди ми записуємо певне значення. Звучить досить просто, чи не так? Тоді час для прикладу:
Я хочу покласти 1 залізну монетку і 1 дерево.
Погодьтеся, класти ці 2 речі в одне місце виглядає не дуже ефективно — вони не тільки різних розмірів, але навіть спосіб їхнього застосування дуже різний. Це — один з багатьох прикладів опису «тип даних». У нього багато різних визначень, але мені дуже подобається таке: «Тип даних — це множина значень та операцій з ними». Якщо вам стало зрозуміло — можете пропустити пояснення.
Припустимо, що тип даних монети — це «гроші». У такому разі, «множина значень» — це всі значення, які підходять «грошам». Тобто, це числові значення. Дивно звучить «горила» грошей, так? Аналогічно з «операції з ними». Не можна «налити» гроші, правда?
Закінчуємо ліричний відступ і повертаємося до С++. Як я казав вище, змінні — ділянка пам’яті, куди можна зберегти значення. Її розмір дуже залежить від самого типу, але має бути достатнім, що умістити релевантні значення. Та й рідко бувають ситуації, коли вам в одну й ту саму ділянку потрібно класти зовсім різні речі. Це лише кілька з багатьох причин, чому в С++ види змінних важливі для ефективної роботи.
Які типи даних є
Дані можуть бути:
- цілі;
- з плаваючою точкою;
- символьні;
- булівські;
- поінтери (pointer).
Це базовий список того, що буде далі описано, але їх набагато більше. Про інші ви дізнаєтесь самі під час вивчення синтаксису.
Важливо розуміти, що у кожного типу даних є свої особливості використання.
Наприклад, цілочисленні. Вони діляться на знакові (тобто можу мати негативні значення — ’-1′ як приклад) та беззнакові. Якщо ви розумієте, що ваша змінна не зможе отримати негативне значення, то чи варто використовувати знакові типи даних?
Як для новачка, вам достатньо зрозуміти різницю між різними типами цього виду. Наприклад, чим відрізняється int та long
Числа з плаваючою крапкою — тут трохи складніше, просто враховуйте, що 0.22, найімовірніше, не дорівнюватиме 0.22 під час їхнього порівняння. Швидше за все, про це буде написано у вашому гайді, але про всяк випадок, нехай буде і тут.
Символьні — хоча вони і використовуються, щоб зберігати літері, врахуйте, що кожен символ має числове уявлення (ASCII кодування). Тип char у С++ може зберігати лише 1 символ, а ʼ (одинарна лапка) та ’’ (подвійні лапки) відрізняються — перше використовується для одного символу, друге — для цілої послідовності. Цей тип дещо особливий — зазвичай він використовується, щоб зберігати «слова», тобто набір символів. Для цього використовується масив «чарів» (array of chars), але ця тема потребує деякого розуміння поінтерів, тому про неї я говорити не буду — гайди вам допоможуть краще.
Моя порада — не забувайте візуалізувати у пам’яті вашої програми такі «слова», чи то за допомогою малюнків, чи то у голові.
Булівські — змінна, що має 2 стани, true або false, а якщо уявити це у форматі числа — 0 це брехня (false), все інше — правда (true).
Поінтери — особливість С++ (та С). Її ціль — зберігати адресу іншої змінної. Її синтаксис, як вона працює, особливості створювання — досить складні теми, на які важливо виділити достатньо часу, оскільки дуже багато інших механізмів у С++ працюють за допомогою цього типу.
Для кращого розуміння цього типу можна лише порадити більше з ним працювати. Але пам’ятайте, що при роботі з поінтерами ви працюєте з пам’яттю, а не зі значеннями, доки не використаєте оператори «*» чи «->».
І фінальна порада — не варто витрачати занадто багато часу на вивчення тільки цієї теми, просто сформулюйте для себе основну різницю між різними типами даних, пограйтесь з максимальними-мінімальними значеннями та спробуйте придумати, де у вашому повсякденному житті який тип даних більш застосовний. Вже при вивченні операторів, вбудованих функцій та іншого ви зможете детальніше зрозуміти різницю.
Етап 2. Оператори
Так, а от і наступна тема. Оператори. Що це таке? Фактично, це якась операція або, для простоти, — дія, яка використовує навколишні змінні як операнди (те, що використовує операція, тобто учасник «дії»).
Здається складно, але насправді дуже прозаїчна тема.
Найпростіший приклад — оператор присвоєння «=». «int a = 5 + 5» — тут ми створюємо змінну «а» і записуємо в неї значення, що має бути підрахованим.
Фактично, першим буде виконано підрахунок оператора «+», у якого дві «5» є операндами. А далі це значення буде призначено у змінну «а».
Новий приклад:
int a;
a = 5;
Ось тут вже використовується оператор присвоєння з операндами «а» та «5». Фактично він бере значення правого операнда і зберігає в змінну, написану зліва.
Приємного пошуку гайдів, що можу сказати.
І ще одна невелика порада — фактично, багато операторів схожі на математичні (*, /, =, >, <= і т.д.), так що, ваша мета — підтвердити для себе, що вони роблять і зрозуміти, у якого оператора який пріоритет. Зазвичай у гайдах буде таблиця, але якщо що — ось тут є зручні приклади.
Етап 3. Вбудовані функції
Це найсмачніша частина для новачка. Фактично перший складний челендж. Гайди, гайди та знову гайди. Не зрозуміли, як працює цикл for? Варто спробувати інші лекції, матеріали або взагалі переглянути відео. Ключова мета — розуміти синтаксис, ціль використання та вміння поєднувати кілька функцій.
Сподіваюся, на цей момент ви знаєте, що таке цикл while і if.
Класичний приклад.
Завдання просте — просити користувача вводити число, доки він не введе число 13.
Якщо не використовувати цикл, вам доведеться написати наступний код:
int user_input = 0; std::cin >> user_input; if (user_input == 13) return 0; // end of program
І цей шматок коду має повторюватися так багато разів, поки вам не набридне копіювати та вставляти його. І тоді, якщо користувач не надто наполегливий, у вас вийде створити в нього відчуття «нескінченності спроб». Звучить як маячня, правильно?
Окей, тут ви згадали, що «мета використання» циклів — декілька разів повторити ті самі дії (інструкції), доки умова не перестане бути правдивою (умова != true)
Швидко переписали код, вийшло дуже лаконічно:
int user_input = 0;
while ( user_input != 13 )
{
std::cin >> user_input;
}
return 0;
Тобто, при вивченні цієї теми, ви повинні намагатися зрозуміти «а навіщо взагалі ця штука потрібна, га?» та довести її корисність самому собі.
Моя порада — як зрозумієте суть вбудованої функції, спробуйте застосувати її в реальності.
На прикладі цих трьох тем я спробував показати, як саме ви повинні підходити до вивчення будь-якої з тем — не тільки читати інструкції, повторювати їх у коді, а потім переходити далі, а саме досліджувати. А що, як зробити так? А як мені зламати те, що я вже написав? А чи є у реальному житті щось схоже?
Далі я коротко опишу теми та мінімальні речі, що вам необхідно зрозуміти. Але не варто зупинятися на цьому — подробиць завжди в рази більше, ніж описано в будь-якому гайді. Отже, відтепер ви дослідник.
Етап 4. Додаткові нюанси
Далі перераховані теми і на що звертати увагу в першу чергу.
(Опціонально) Константи. У чому на відміну від звичайних змінних і покажчиків.
Масиви фіксованого розміру. Як у пам’яті, чому їм потрібні поінтери.
Динамічна пам’ять. Не забувайте, що її потрібно видаляти. Тут важливі експерименти — що буде, якщо видалити виділену пам’ять, а потім щось призначити туди? А що, якщо навпаки, не виділити пам’яті для вказівника, але спробувати щось записати?
(Опціонально) Час життя. Глобальні та локальні змінні, скільки живуть і коли вмирають.
Опції. Навіщо використовувати поінтери чи посилання як параметри, який час життя змінних (у функціях, статичні змінні, оголошені у них тощо), навіщо їх взагалі використовувати.
Кілька файлів для коду. Для чого код необхідно розділяти? Навіщо використовувати #pragma once? А як працюють глобальні змінні у такому разі?
(Опціонально) Одиниці трансляції. Просто розуміння, як формуються файли.
Область видимості. Спробуйте розділити на namespaces свій раніше написаний і поділений на файли код, що з цього вийде?
Етап 5. ООП
До цього моменту швидше за все базові елементи С++ та їх особливості ви вже зрозуміли чи спробували, час переходити до ООП. Важлива ремарка: у статті немає пояснення ООП, лише структури даних С++. Якщо хочете краще зрозуміти цей підхід — пошукайте додаткову інформацію.
Структура. Що це взагалі таке і навіщо воно потрібне? Тут треба розібратися саме з тим, що це певний саме вами тип даних, а, значить, ви створюватимете об’єкти цього типу даних і потім вже використовувати їх. Так само як оголошувати атрибути та як їх використовувати.
Класи. Дуже велика тема. Ключова відмінність від попереднього етапу — тут важливо зрозуміти механізми та фічі, що надає С++. Далі йдуть теми, що розкривають суть цієї.
Конструктори та деструктори. Коли викликаються, що мають робити які проблеми з ними можуть бути. Які види конструкторів бувають.
Модифікатори доступу. Навіщо це взагалі потрібно. (Так, тут уже входить поняття наслідування, але про нього трохи пізніше).
Методи: статичні, константні та інші. Важливо розуміти, що для чого використовується, як викликати, що таке this та інше.
Спадкування. Особливості використання модифікаторів доступу, порядок виклику конструктора-деструктора, віртуальні методи, ромбоподібна проблема та її вирішення.
Крім синтаксису, вам необхідно зрозуміти нащо це все загалі. Спробуйте зрозуміти принцип SOLID та погратись з патерами дизайну, але ця тема може бути ще досить складною, тому перейти до STL-бібліотеки теж непогане рішення.
Етап 6. Що далі
І ось тут настає питання — а що далі? І це складне питання. Правильна відповідь одна — все, але не відразу. Отже, вивчати вам ще дуже багато всього, але, ймовірно, на цьому етапі можна вже задуматися про спробу потрапити на якийсь курс/ стажування від компанії. Кожна подальша тема дійсно потребує окремої статті, так що будьте готові шукати інформацію самостійно.
Робота з кодом. Це улюблена тема на співбесідах. Вам необхідно зрозуміти, які етапи проходить вами написаний код від моменту початку компіляції до запуску виконуваного файлу. Бажано відразу спробувати трохи Makefile і CMake.
Структури даних та алгоритми. Фактично в університетах це окремий предмет «Алгоритми та структури даних». Річ одночасно складна та проста. Найкраща порада — прочитайте для початку книгу Grokking Algorithms: An Illustrated Guide for Programmers and Other Curious People Адітья Бхаргава. У ній чудово описані всі базові концепції. І пам’ятайте: найважливіше під час читання книг з програмування — намагатися писати все те, про що у них йде мова.
STL. Мабуть, ви вже використовували щось зі стандартної бібліотеки, наприклад — cout та cin. Тепер час навчитися використовувати vector, list і т.д. Головна порада до теми в цілому — прочитавши про вид контейнера, спробуйте написати його самі.
Багатопотокове програмування. Майже на всіх співбесідах, де я був, про нього питали. Спробуйте розібратися, але тема досить складна та глибока. Для новачка необхідно розуміти хоча б що таке потоки, мьютекси, які проблеми з нею можуть бути.
Шаблони. Не менша об’ємна тема, але мінімально її розуміти необхідно. Складно щось порадити, гайди, що я бачив переважно на достатньому рівні їх пояснюють.
Думаю, дійшовши до цього етапу, ви вже здатні потрапити в IT-компанію. Але розслаблятися рано — найцікавіше попереду. Втім, про це вже не в цій статті. Далі буде наведено кілька цікавих посилань. Але на цьому, гадаю, можна попрощатися. До зустрічі на кавабрейках!
Корисні посилання
- Текстові гайди — чудові гайди, перевірені часом.
Відеокурси:
- непоганий базовий гайд C++;
- Chili Tomato Noodle — на каналі є різні плейлисти для складніших тем, як-от багатопоточка та std.
Цікаві посилання:
- Сppreference.com — опис усіх методів базового С++ та std бібліотеки;
- Cplusplus.com — схожий за контентом сайт;
- Github.com/practical-tutorials — чим можна зайнятися далі у плані розвитку себе як С++ розробника.
Сподобалась стаття? Підписуйтесь на автора, щоб отримувати сповіщення про нові публікації на пошту.

34 коментарі
Додати коментар Підписатись на коментаріВідписатись від коментарів