Лекції по c
Лекції по C / C ++: складові типи даних (структури)
Уявімо собі, що нам потрібно програмно обробити інформацію про студентів. Дані про кожного студента включають в себе величини декількох типів - рядок з ім'ям і ініціалами, ціле число, що показує вік студента в роках, середній бал, який є речовим значенням, і т.д. Найпростіший шлях вирішення завдання - описати в програмі набір відповідних змінних:
Коли студентів стає кілька, нам доведеться перейти від змінних до масивів:
Щоб витягти інформацію про останньому студента, нам потрібно обробити величини name [4]. age [4] і ball [4]. Таким чином, інформація про один об'єкт виявляється "розкидана" по декільком контейнерів-масивів, що робить вкрай незручними операції зі "студентом" як єдиним об'єктом. Подолати цю незручність може структура. що дозволяє об'єднувати в одному об'єкті різнотипні дані.
Отже, структура - це основний складовою тип даних. На відміну від масиву, вона об'єднує в одному об'єкті значення, які можуть мати різні типи даних. Це робить структури основним засобом моделювання в програмі об'єктів реального світу:
Для сумісності з мовою C перед ключовим словом struct часто записують оператор визначення типу typedef. На C ++ цей оператор є зайвим.
Наведемо змінні "нового" типу даних student.
Ніякої різниці з описом змінних простих типів int. float і т.д. немає.
Для доступу до окремих даних про студента, перерахованим в описі структурного типу (полів структури) служить операція. ( "Точка"), застосовна в запису виду структура.поле. Наприклад, s.name означатиме поле "ім'я" студента, інформація про який збережена в змінної з ім'ям s.
При цьому, з полем структури дозволені всі ті ж операції, що і з "звичайної" змінної відповідного типу даних:
Розглянемо перші два дії на прикладі.
1. Функція st_print виводить інформацію про структуру типу student. переданої в якості параметра;
2. Функція st_new заповнює нову структуру student даними за замовчуванням і повертає структуру. За рахунок того, що підтримується присвоювання структур, отримана з функція інформація дублюється в структурі s2 функції main.
Зауважимо, що передача в якості параметрів функції або повернення з функції структур великого розміру можуть бути чреваті переповненням стека. А визначити обсяг структури в оперативній пам'яті можна стандартними засобами:
Для збереження інформації про 20 студентів групи природним виглядає опис масиву структур:
Доступ до структури можна здійснювати і через покажчик.
Після цього можна виконувати ptr ++ для сканування списку або масиву структур таким чином, як ми жили згідно з покажчиками на прості типи даних.
Доступ до поля структури через покажчик має наступний вигляд:
Круглі дужки тут потрібні через пріоритетів операцій мови C ++. Запис виглядає громіздкою, тому, замість неї, як правило, застосовують мнемонічне скорочення
Приклад 1. Функція show друкує інформацію про студента s (без покажчика):
Та ж функція з покажчиком:
У першому випадку через стек передано sizeof (student) = sizeof (char) * 20 + sizeof (int) + sizeof (float) байт (від 28 байт, якщо символи char - однобайтові), у другому випадку - 4 або 8 байт (в залежно від розміру покажчика в 32-розрядної або 62-розрядної архітектури ЕОМ).
Для i-го елемента нашого масиву структур виклик першої функції мав би вигляд
Приклад 2. Показана вище функція st_new з використанням покажчика прийняла б вигляд
Оскільки оператор new виділяє пам'ять в "купі", а не в стеці, її потім можна звільнити оператором delete.
Пояснимо на прикладі 2 програм.
У першій програмі все поля структури student - статичні, під них не виділялася динамічна пам'ять, тому присвоювання таких структур коректно:
Як варіант, поставимо замість рядка
Елемент структури може бути структурою іншого структурного типу або покажчиком на структуру свого типу. Останнє важливе властивість структур дозволяє організовувати динамічні структури даних, такі як стеки, черги або дерева. Динамічним структурам буде присвячена окрема тема.
Нарешті, зауважимо, що найбільш природним виглядає збереження статичних структур в бінарних файлах даних (так як розмір такої структури в байтах - фіксований) та обмін даними з цими файлами за допомогою методом fread / fwrite з stdio.h або read / write з fstream:
До структурам з покажчиками в загальному випадку сказане не застосовується. В якості альтернативи напишемо програму, що дозволяє прочитати масив структур student з динамічним полем name з текстового файлу data.txt такого вигляду:
і т.д. Передбачається, що файл знаходиться в поточній для виконуваного файлу програми папці. Максимальне число записів поки що обмежимо константою ST.
Програма також містить найпростішу захист від невірних даних у вихідному файлі.