Навчальний простір / Kotlin
Програмування мобільних застосунків

Вступ до розробки Android-застосунків

Мобільні застосунки, платформа Android, Android Studio, SDK, Gradle, структура проєкту, Kotlin, Activity, Jetpack Compose, стан, життєвий цикл, ресурси, дозволи, емулятор, збірка та налагодження.

Зміст матеріалу

Що ви опануєте

Ця лекція формує базову систему понять, яка знадобиться для всього подальшого курсу. Ми розглянемо, як влаштована Android-платформа, які інструменти беруть участь у створенні застосунку, як Kotlin-код потрапляє на пристрій, як формується інтерфейс у Jetpack Compose та як Android керує життєвим циклом компонентів.

Після опрацювання матеріалу ви зможете:

  • пояснити, що таке мобільний застосунок і які задачі він розв’язує;
  • описати базові рівні Android-платформи;
  • пояснити призначення Android Studio, Android SDK, Gradle, ADB та Android Emulator;
  • орієнтуватися у структурі Android-проєкту;
  • читати базовий Kotlin-код;
  • пояснити роль Activity;
  • створити простий UI за допомогою Jetpack Compose;
  • пояснити поняття Composable, state та recomposition;
  • розуміти призначення ресурсів Android;
  • пояснити, як працюють дозволи;
  • описати основні етапи життєвого циклу Activity;
  • запускати застосунок на емуляторі або фізичному пристрої;
  • використовувати Logcat для базової діагностики.

Що таке мобільний застосунок

До таких пристроїв належать:

  • смартфони;
  • планшети;
  • смарт-годинники;
  • телевізори;
  • автомобільні мультимедійні системи;
  • складні пристрої;
  • спеціалізовані термінали;
  • вбудовані Android-пристрої.

Мобільний застосунок може використовувати системні можливості:

  • камеру;
  • мікрофон;
  • геолокацію;
  • Bluetooth;
  • NFC;
  • Wi-Fi;
  • файлову систему;
  • сенсори;
  • сповіщення;
  • біометричну автентифікацію;
  • локальне сховище;
  • мережу;
  • фонові задачі.

Мобільне середовище має власні обмеження: обсяг пам’яті, заряд акумулятора, нестабільність мережі, різні розміри екранів, зміну орієнтації, фонове призупинення процесів і контроль доступу до приватних даних.

Основні підходи до мобільної розробки

Мобільні застосунки можуть створюватися кількома способами.

Нативна розробка

Нативний Android-застосунок створюється для Android-платформи з використанням її SDK, API та інструментів. Для сучасної Android-розробки основною мовою є Kotlin.

Нативний підхід дає прямий доступ до Android API, камери, сенсорів, геолокації, push-сповіщень, локального сховища, системних сервісів і життєвого циклу Android-компонентів.

Кросплатформна розробка

Кросплатформні технології дозволяють створювати спільну кодову базу для кількох платформ.

Приклади:

  • Flutter;
  • React Native;
  • Kotlin Multiplatform;
  • .NET MAUI.

У цьому курсі основна увага приділяється нативній Android-розробці на Kotlin та сучасному UI на Jetpack Compose.

Що таке Android

Android використовується на великій кількості типів пристроїв і має багаторівневу архітектуру.

Спрощена архітектура AndroidОберіть елемент, щоб побачити пояснення

Найвищий рівень, з яким взаємодіє користувач.

Linux Kernel

Ядро Linux відповідає за базові функції операційної системи:

  • керування процесами;
  • керування пам’яттю;
  • роботу драйверів;
  • мережеву взаємодію;
  • файлову систему;
  • енергоспоживання;
  • базові механізми безпеки.

Native Libraries

Системні бібліотеки реалізують графіку, роботу з медіа, базами даних, шифруванням, файлами та іншими низькорівневими функціями.

Android Runtime

ART відповідає за виконання скомпільованого коду та взаємодіє із системними механізмами керування пам’яттю й процесами.

Application Framework

Application Framework надає API для:

  • Activity;
  • ресурсів;
  • сповіщень;
  • геолокації;
  • дозволів;
  • вікон;
  • пакетів;
  • фонових задач;
  • системних служб.

Як Android ізолює застосунки

Кожен застосунок має власний простір даних та системну ідентичність. Це допомагає захищати приватність користувача, файли та системні ресурси.

Android Studio

Android Studio об’єднує:

  • редактор Kotlin-коду;
  • Android SDK;
  • Gradle;
  • систему підказок;
  • статичний аналіз;
  • Device Manager;
  • Android Emulator;
  • Logcat;
  • debugger;
  • profiler;
  • редактори ресурсів;
  • Compose Preview;
  • засоби тестування.
Основні інструменти Android-розробкиОберіть елемент, щоб побачити пояснення

Середовище розробки.

Android SDK

Android SDK містить:

  • Android Platform API;
  • Build Tools;
  • Platform Tools;
  • ADB;
  • Emulator;
  • системні образи;
  • утиліти пакування;
  • інструменти командного рядка.

Рівні API

Кожна версія Android має номер API level.

kotlin
android {
    compileSdk = 36

    defaultConfig {
        minSdk = 24
        targetSdk = 36
    }
}

compileSdk

compileSdk визначає версію Android API, відносно якої компілюється проєкт.

minSdk

minSdk визначає мінімальний API level, на якому застосунок дозволено встановлювати.

targetSdk

targetSdk визначає рівень платформи, під правила поведінки якого підготовлений застосунок.

Gradle

Крок за кроком
  1. Крок 1 із 6

    Читання конфігурації

    Gradle аналізує налаштування проєкту та модулів.

1 / 6

Залежності

kotlin
dependencies {
    implementation("androidx.activity:activity-compose:...")
    implementation("androidx.compose.material3:material3:...")
}

implementation повідомляє Gradle, що модуль використовує вказану бібліотеку.

Що відбувається після Run

Від Kotlin-коду до екрана пристроюОберіть елемент, щоб побачити пояснення

Код у .kt файлах.

APK та AAB

APK містить скомпільований код, ресурси, manifest, метадані та бібліотеки.

Структура Android-проєкту

text
MyApplication/
├── app/
│   ├── src/
│   │   ├── main/
│   │   │   ├── java/
│   │   │   │   └── com/example/myapplication/
│   │   │   │       └── MainActivity.kt
│   │   │   ├── res/
│   │   │   │   ├── drawable/
│   │   │   │   ├── mipmap/
│   │   │   │   ├── values/
│   │   │   │   └── xml/
│   │   │   └── AndroidManifest.xml
│   │   ├── test/
│   │   └── androidTest/
│   └── build.gradle.kts
├── gradle/
├── build.gradle.kts
├── settings.gradle.kts
└── gradle.properties

Модуль app

app — основний модуль застосунку. Він містить Kotlin-код, ресурси, AndroidManifest, залежності, конфігурацію Android та тести.

Каталог src/main

src/main містить код та ресурси основної версії застосунку.

Каталог res

res містить ресурси: рядки, кольори, зображення, іконки, шрифти та XML-конфігурації.

AndroidManifest.xml

xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <application
        android:theme="@style/Theme.MyApplication">

        <activity
            android:name=".MainActivity"
            android:exported="true">

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

        </activity>

    </application>

</manifest>

Що тут відбувається?

  1. <manifest> — кореневий елемент.
  2. <application> описує застосунок.
  3. <activity> реєструє Activity.
  4. android:name містить ім’я класу Activity.
  5. MAIN позначає основну точку запуску.
  6. LAUNCHER дозволяє запускати Activity через іконку застосунку.

Kotlin у контексті Android

kotlin
val studentName: String = "Олена"
val courseNumber: Int = 2
val rating: Double = 91.5
val isActive: Boolean = true

Основні типи:

  • String;
  • Int;
  • Long;
  • Float;
  • Double;
  • Boolean;
  • Char.

val і var

kotlin
val university = "ДДТУ"
var completedLabs = 2

completedLabs = 3

val використовується для значення, яке не переприсвоюється.

var використовується для значення, яке може змінюватися.

Виведення типу

kotlin
val name = "Анастасія"
val age = 20
val progress = 0.75

Компілятор визначає тип автоматично. Це називається type inference — виведення типу.

Функції Kotlin

kotlin
fun greet(name: String): String {
    return "Вітаю, $name!"
}

Що тут відбувається?

  1. fun оголошує функцію.
  2. greet — ім’я функції.
  3. name: String — параметр.
  4. String після дужок — тип результату.
  5. return повертає результат.
  6. $name вставляє значення змінної в рядок.

Умови та when

kotlin
fun getStatus(score: Int): String {
    return if (score >= 60) {
        "Зараховано"
    } else {
        "Потрібне доопрацювання"
    }
}
kotlin
fun getGrade(score: Int): String {
    return when {
        score >= 90 -> "Відмінно"
        score >= 75 -> "Добре"
        score >= 60 -> "Задовільно"
        else -> "Потрібне доопрацювання"
    }
}

Nullable типи

kotlin
var userName: String? = null

Безпечне звернення:

kotlin
val length = userName?.length

Значення за замовчуванням:

kotlin
val displayName = userName ?: "Гість"

Колекції

kotlin
val topics = listOf(
    "Kotlin",
    "Compose",
    "Navigation",
    "Room"
)
kotlin
for (topic in topics) {
    println(topic)
}

Класи та моделі даних

kotlin
data class Student(
    val name: String,
    val group: String,
    val rating: Double
)
kotlin
val student = Student(
    name = "Олена",
    group = "ПЗ-23",
    rating = 91.5
)

data class часто використовується для представлення даних у застосунку.

Лямбда-функції

У Compose лямбди зустрічаються постійно.

kotlin
val onClick = {
    println("Кнопку натиснуто")
}
kotlin
val onNameChanged: (String) -> Unit = { newName ->
    println(newName)
}

Activity

kotlin
package com.example.myapplication

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material3.Text

class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            Text(
                text = "Привіт, Android!"
            )
        }
    }
}

Що тут відбувається?

  1. MainActivity — клас стартової Activity.
  2. ComponentActivity — базовий AndroidX-клас.
  3. onCreate() викликається під час створення Activity.
  4. super.onCreate() виконує базову ініціалізацію.
  5. setContent передає формування UI Jetpack Compose.
  6. Text створює текстовий UI-компонент.

Життєвий цикл Activity

Основні callbacks:

text
onCreate()
onStart()
onResume()
onPause()
onStop()
onDestroy()
Спрощений життєвий цикл ActivityОберіть елемент, щоб побачити пояснення

Початкова ініціалізація.

Спостереження через Logcat

kotlin
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity

class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d("LIFECYCLE", "onCreate")
    }

    override fun onStart() {
        super.onStart()
        Log.d("LIFECYCLE", "onStart")
    }

    override fun onResume() {
        super.onResume()
        Log.d("LIFECYCLE", "onResume")
    }

    override fun onPause() {
        Log.d("LIFECYCLE", "onPause")
        super.onPause()
    }

    override fun onStop() {
        Log.d("LIFECYCLE", "onStop")
        super.onStop()
    }

    override fun onDestroy() {
        Log.d("LIFECYCLE", "onDestroy")
        super.onDestroy()
    }
}

Jetpack Compose

kotlin
@Composable
fun Greeting(name: String) {
    Text(
        text = "Вітаю, $name!"
    )
}

@Composable

@Composable позначає функцію, яка бере участь у формуванні Compose UI.

Декларативний підхід

Корисна модель:

text
UI = f(state)

Інтерфейс формується на основі поточного стану даних.

Перший Compose-екран

kotlin
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp

@Composable
fun StudentScreen() {

    Column(
        modifier = Modifier.padding(24.dp)
    ) {
        Text(text = "Програмування мобільних застосунків")
        Text(text = "Перша Android-сторінка")
    }
}

Що тут відбувається?

  1. StudentScreen() описує UI-компонент.
  2. Column розташовує дочірні компоненти вертикально.
  3. Modifier.padding(24.dp) додає відступ.
  4. dp — density-independent pixel.
  5. Text відображає текст.

Базові layout-компоненти Compose

Розміщує дочірні компоненти вертикально.

Modifier

kotlin
Text(
    text = "Android",
    modifier = Modifier
        .fillMaxWidth()
        .padding(16.dp)
)
Порядок Modifier

Порядок модифікаторів впливає на результат. Кожен наступний модифікатор працює з результатом попереднього кроку.

dp та sp

Material 3

Material 3 надає готові компоненти:

  • Text;
  • Button;
  • Card;
  • TextField;
  • OutlinedTextField;
  • Scaffold;
  • TopAppBar;
  • NavigationBar;
  • FloatingActionButton;
  • AlertDialog.
kotlin
@Composable
fun SaveButton() {

    Button(
        onClick = {
            println("Збереження")
        }
    ) {
        Text(text = "Зберегти")
    }
}

State

Приклади state:

  • введений текст;
  • обрана вкладка;
  • список повідомлень;
  • поточний користувач;
  • стан завантаження;
  • стан авторизації;
  • кількість товарів;
  • вибраний елемент.

mutableStateOf і remember

kotlin
var count by remember {
    mutableStateOf(0)
}

mutableStateOf(0) створює observable state зі стартовим значенням 0.

remember дозволяє Compose зберігати значення між повторними виконаннями composable-функції в межах поточної композиції.

Recomposition

State і recompositionОберіть елемент, щоб побачити пояснення

count = 0

Повний приклад лічильника

kotlin
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp

@Composable
fun CounterScreen() {

    // Стан лічильника.
    var count by remember {
        mutableStateOf(0)
    }

    Column(
        modifier = Modifier.padding(24.dp)
    ) {

        // Текст залежить від count.
        Text(
            text = "Натиснуто: $count"
        )

        Button(
            onClick = {
                // Зміна state.
                count++
            }
        ) {
            Text(text = "Натиснути")
        }
    }
}

Що тут відбувається?

  1. count — observable state.
  2. remember зберігає стан у поточній композиції.
  3. Text читає значення count.
  4. Button генерує подію натискання.
  5. count++ змінює state.
  6. Compose оновлює частини UI, які читають count.

Поле введення

kotlin
@Composable
fun StudentForm() {

    var name by remember {
        mutableStateOf("")
    }

    Column(
        modifier = Modifier.padding(24.dp)
    ) {
        OutlinedTextField(
            value = name,
            onValueChange = { newValue ->
                name = newValue
            },
            label = {
                Text("Ім’я студента")
            }
        )

        Text(
            text = "Введено: $name"
        )
    }
}

State hoisting

kotlin
@Composable
fun StudentScreen() {

    var name by remember {
        mutableStateOf("")
    }

    StudentNameInput(
        name = name,
        onNameChange = { newName ->
            name = newName
        }
    )
}

@Composable
fun StudentNameInput(
    name: String,
    onNameChange: (String) -> Unit
) {
    OutlinedTextField(
        value = name,
        onValueChange = onNameChange,
        label = {
            Text("Ім’я")
        }
    )
}

rememberSaveable

Для стану, який має переживати типові відтворення Activity, Compose надає rememberSaveable.

kotlin
var count by rememberSaveable {
    mutableStateOf(0)
}

Preview

kotlin
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview

@Preview(showBackground = true)
@Composable
fun StudentScreenPreview() {
    StudentScreen()
}

Preview допомагає перевіряти layout, текст, тему та різні стани UI.

Тема застосунку

kotlin
MyApplicationTheme {
    CourseScreen()
}

Тема може визначати кольори, типографіку, форми, світлу та темну схеми.

kotlin
Text(
    text = "Заголовок",
    style = MaterialTheme.typography.headlineMedium,
    color = MaterialTheme.colorScheme.primary
)

Ресурси Android

Android має спеціальну ресурсну систему.

xml
<resources>
    <string name="app_name">Mobile Course</string>
    <string name="welcome_message">Вітаємо у застосунку</string>
</resources>

У Compose:

kotlin
Text(
    text = stringResource(R.string.welcome_message)
)

Об’єкт R

Android генерує спеціальний клас R.

text
R.string.app_name
R.drawable.logo
R.color.primary

Локалізація

text
res/values/strings.xml
res/values-uk/strings.xml
res/values-en/strings.xml

Android вибирає потрібний ресурс відповідно до конфігурації пристрою.

Дозволи Android

xml
<uses-permission
    android:name="android.permission.CAMERA" />
Крок за кроком
  1. Крок 1 із 5

    Декларація

    Застосунок описує потрібний permission.

1 / 5

Android Emulator

Емулятор дозволяє тестувати різні версії Android, екрани, орієнтацію, геолокацію, темну тему, мову та мережеві умови.

AVD

AVD включає модель пристрою, розмір екрана, API level, системний образ, архітектуру процесора та параметри пам’яті.

Запуск на фізичному пристрої

Крок за кроком
  1. Крок 1 із 6

    Увімкнути Developer options

    На Android-пристрої активується режим розробника.

1 / 6

ADB

bash
adb devices
text
List of devices attached
emulator-5554    device

Logcat

kotlin
Log.d(
    "COURSE",
    "MainActivity створено"
)

Основні рівні:

text
V — verbose
D — debug
I — info
W — warning
E — error

Як читати помилки

Крок за кроком
  1. Крок 1 із 6

    Знайдіть першу змістовну помилку

    Довгий журнал може містити багато похідних повідомлень.

1 / 6

Compile-time та runtime помилки

kotlin
val count: Int = "п'ять"

Stack trace

text
FATAL EXCEPTION: main
java.lang.IllegalStateException: ...
    at com.example.mobilecourse.StudentScreen(...)
    at com.example.mobilecourse.MainActivity(...)

Під час аналізу шукайте:

  • тип винятку;
  • повідомлення;
  • перший рядок із пакетом вашого застосунку;
  • файл;
  • номер рядка.

Конфігурації пристрою

Android-застосунок має працювати в різних умовах:

  • портретна орієнтація;
  • альбомна орієнтація;
  • світла тема;
  • темна тема;
  • інша мова;
  • планшет;
  • складний пристрій;
  • збільшений шрифт;
  • багатовіконний режим.

Простий повний екран

kotlin
package com.example.mobilecourse

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp

class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            MaterialTheme {
                Surface {
                    CourseScreen()
                }
            }
        }
    }
}

@Composable
fun CourseScreen() {

    var completedTopics by remember {
        mutableStateOf(0)
    }

    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(24.dp),
        verticalArrangement = Arrangement.spacedBy(16.dp)
    ) {

        Text(
            text = "Програмування мобільних застосунків",
            style = MaterialTheme.typography.headlineMedium
        )

        Text(
            text = "Вивчено тем: $completedTopics",
            style = MaterialTheme.typography.bodyLarge
        )

        Button(
            onClick = {
                completedTopics++
            }
        ) {
            Text(text = "Позначити тему")
        }
    }
}

Архітектура першого навчального застосунку

Архітектура першого Android-застосункуОберіть елемент, щоб побачити пояснення

Android entry point.

У наступних темах до цієї схеми поступово додаватимуться:

text
ViewModel
Navigation
Repository
REST API
Room
Coroutines
Flow
Dependency Injection
Testing

Типові помилки на старті

Android Studio не бачить SDK
Перевірте SDK Manager та шлях до Android SDK. Має бути встановлена потрібна SDK Platform і Build Tools.
Gradle Sync Failed
Прочитайте перше змістовне повідомлення помилки. Перевірте доступ до мережі, версії плагінів і залежностей.
Емулятор не запускається
Перевірте системні вимоги, доступну оперативну пам’ять, віртуалізацію та конфігурацію AVD.
Пристрій не видно в Android Studio
Перевірте USB debugging, кабель, підтвердження довіри та результат adb devices.
Unresolved reference
Перевірте import, назву символу, залежності Gradle та успішність Gradle Sync.
Composable invocations can only happen...
Перевірте, чи викликається composable-функція з composable-контексту.

Мініексперимент

kotlin
@Composable
fun LearningScreen() {

    var lessonNumber by remember {
        mutableStateOf(1)
    }

    Column(
        modifier = Modifier.padding(24.dp),
        verticalArrangement = Arrangement.spacedBy(12.dp)
    ) {

        Text(text = "Мобільна розробка")

        Text(
            text = "Поточна тема: $lessonNumber"
        )

        Button(
            onClick = {
                lessonNumber++
            }
        ) {
            Text(text = "Наступна тема")
        }
    }
}

Визначте:

  • початкове значення lessonNumber;
  • текст після першого запуску;
  • текст після одного натискання;
  • текст після п’яти натискань;
  • змінну state;
  • подію, яка змінює state;
  • компонент, який залежить від state.

Самоперевірка термінів

Картки для повторення
01 Що таке Android SDK?Показати відповідь

Набір API та інструментів для створення, збірки, запуску й налагодження Android-застосунків.

02 Для чого використовується Gradle?Показати відповідь

Для автоматизації збірки, конфігурації проєкту та керування залежностями.

03 Що таке Activity?Показати відповідь

Android-компонент із власним життєвим циклом, який представляє точку взаємодії користувача із застосунком.

04 Що означає @Composable?Показати відповідь

Анотація позначає функцію, яка бере участь у побудові Compose UI.

05 Що таке state?Показати відповідь

Дані, значення яких впливає на UI або поведінку застосунку.

06 Що таке recomposition?Показати відповідь

Повторне виконання залежних частин Compose UI після зміни observable state.

07 Що таке AVD?Показати відповідь

Конфігурація віртуального Android-пристрою.

08 Що таке Logcat?Показати відповідь

Система перегляду журналів Android і повідомлень застосунку.

09 Що таке APK?Показати відповідь

Пакет Android-застосунку, який може бути встановлений на пристрій.

Перевірка розуміння

Перевірте розуміння
Яка технологія відповідає за побудову сучасного декларативного UI в Android?
Перевірте розуміння
Яка роль Gradle в Android-проєкті?
Перевірте розуміння
Який callback Activity виконується під час початкового створення екземпляра?

Питання для самоперевірки

Навіщо Android-проєкту потрібен AndroidManifest.xml?
Manifest описує системну конфігурацію застосунку: компоненти, дозволи, характеристики та інші параметри, потрібні Android.
Чому Compose потрібен state?
State містить дані, від яких залежить інтерфейс. Коли observable state змінюється, Compose може оновити відповідні частини UI.
Що відбувається після натискання Run в Android Studio?
Gradle збирає проєкт, формується пакет, Android Studio передає його на пристрій або емулятор, Android встановлює застосунок і запускає стартову Activity.

Практична перевірка після лекції

Я готовий працювати з першим Android-проєктом

Карта понять

Карта понять лекціїОберіть елемент, щоб побачити пояснення

Операційна система та платформа.

Джерела для подальшого вивчення

Опрацювали матеріал?

Збережіть цей крок у своєму прогресі.

← Повернутися до дисципліни
© 2026 Анастасія Іскандарова-МалаЕлектронний навчальний посібник · ДДТУ

Пошук у посібнику

Спробуйте «C++», «RAII» або «бази даних».