Справочник от Автор24
Поделись лекцией за скидку на Автор24

Структуры данных

  • 👀 404 просмотра
  • 📌 340 загрузок
Выбери формат для чтения
Загружаем конспект в формате pdf
Это займет всего пару минут! А пока ты можешь прочитать работу в формате Word 👇
Конспект лекции по дисциплине «Структуры данных» pdf
Лекция 8 Структуры данных Вы могли задаваться вопросом: а как писать по-настоящему сложные программы? Оперировать числовыми с строковыми переменными не слишком удобно. Почему нет возможности сделать свой супер тип? Возможность есть, и сейчас мы узнаем, как она выглядит в коде. Простейшие данные можно объединять. Возможно, кто-то заметил, что держать размер массива в другой переменной не слишком удобно. В конце концов, почему массив сам не знает своего размера? В языках высокого уровня массивы лишены этого недостатка, но Си — язык, который экономит на всем, на чем можно. Хранение размера штука затратная, и не всегда это нужно, поэтому программист сам заботится об этом. Я не буду приводить пример для массива и его размера, это довольно уныло. Давайте рассмотрим другой пример. Допустим нам понадобилось хранить данные о клиентах. Упростим задачу, оставим имя (сhar*), адрес (address) и номер счета (int). Для удобства мы можем объединить даже разнотипные данные в одну переменную: struct Client { char *Name; Address Adr; int NumberCount; }; Мы создали свой тип. Си не знает что такое Address, но это тоже наш тип, мы могли объявить его ранее: struct Address { char *Street; int HouseNumber; int FlatNumber }; Обратите внимание на точку с запятой после структуры, она очень важна. Если ее забыть ошибки будут очень непонятные, иногда разные, и указывать совсем на другую строку. Объявление переменной от пользовательского типа (или проще структуры) нечем не отличается от встроенного: Client c; Уже в структуре клиента я объявил переменную адрес. Теперь о неприятном: стандарт Си очень вежливо просит различать встроенные типы от пользовательских. Все выше написанное не скомпилируется, потому что при записи пользовательского типа мы обязаны ставить struct. В С++ этой проблемы нет, потому что вездесущие struct очень сильно засоряют код, но напишем согласно стандарту Си: #include #include struct Address { char *Street; int HouseNumber; int FlatNumber; }; struct Client { char *Name; struct Address Adr; int NumberCount; }; int main () { struct Client c; return 0; } Работать с переменной пользовательского типа столь же просто. Но для доступа к конкретным полям структуры, например, к счету, нужно воспользоваться оператором . (точка). Вообще, называется он member selector, но в русской литераторе по языкам С/С++ это название редко встречается. Тем не менее довольно безграмотно зазывать его оператором точкой. c.NumberCount = 4; strcpy(c.Name, “Max”); //уже не сработает Почему вторая строка не будет работать вы уже знаете, но как записать значение в поле Name? Переделать в массив (char Name[256])? И как часто клиенты меняют имена? Нет, тут поможет инициализация: struct Client c = {.Name = "Max"}; Для инициализации адреса код будет выглядеть чуть сложнее: struct Client c = {.Name = "Max", .Adr = { .Street = "Pushkina", .HouseNumber = 4, .FlatNumber = 4 }, .NumberCount = 5}; printf("%s, %s, %i, %i", c.Name, c.Adr.Street, c.Adr.HouseNumber, c.Adr.FlatNumber); Код выглядит запутанным, но только с непривычки. Для структур мы также можем выделять память динамически: struct Client *c1 = malloc(sizeof(struct Client)); free(c1); Для указателей оператор селектор превращается из точки в стрелку (->). У многих возникает с этим путаница. На самом деле, тут нет путаницы, точка также продолжает работать, просто, обращаясь к полям через указатель, вы обращаетесь к адресу переменной, так что нужно писать: (*c1).NumberCount = 3; или короче: c1->NumberCount = 3; С инициализацией для динамических переменных сложнее, а конкретно — мы не можем их инициализировать. Но мы можем скопировать блок памяти и разместить его по их адресу: int main () { struct Client c = {.Name = "Max", .adr = { .Street = "Pushkina", .HouseNumber = 4, .FlatNumber = 4 }, .NumberCount = 5}; printf("%s, %s, %i, %i\n", c.Name, c.Adr.Street, c.Adr.HouseNumber, c.Adr.FlatNumber); struct Client *c1 = malloc(sizeof(struct Client)); memcpy(c1, &c, sizeof(struct Client)); //копирование блока памяти в с1 printf("%s, %s, %i, %i", c1->Name, c1->Adr.Street, c1->Adr.HouseNumber, c1->Adr.FlatNumber); free(c1); } Переменные пользовательского типа также можно объединять и в массивы, и работать с ними точно также, как и с обычными массивами. struct Client clients[10]; clients[0].NumberCount = 4; Передача в качестве аргумента структур также не отличается от встроенных типов: void func(struct Client client) { } Имейте ввиду, что при такой передаче происходит копирование структуры, как и в случае, описанном на прошлой лекции. Только теперь копируется не 4 байта, а гораздо больше. Сколько? Можно узнать выведя на экран sizeof(struct Client) Так что передавайте структуры через указатели: void func(struct Client *client) { } И если функция не меняет аргумент, то используйте const. Интересная штука, насчет размера структуры: сейчас он равен 20 байт. Действительно 4*5 = 20. Но изменив всего тип одной переменной мы можем увеличить размер в 2 раза. Первый, кто изменит тип так, что сделает размер структуры Client равным 40, получит +1 балл. Стоило бы упомянуть еще и о union, но суровая правда жизни говорит о том, что объединения можно редко удачно использовать, так что это будет материалом для самостоятельного изучения. Это основы работы со структурами, но самые классные фичи мы рассмотрим в 9 лекции. Лабораторная работа №8 Задание 0. Дана информация о десяти рабочих цеха. Структура имеет вид: фамилия, размер зарплаты, стаж работы. Вывести данные о рабочих с наибольшей зарплатой и наименьшим стажем в порядке убывания этого отношения. Задание 1. Создать базу студентов. У студента есть имя, оценка по математике, русскому и литературе. Программа должна уметь добавлять студента с консоли, выводить весь список студентов, удалять студентов и находить отличников и двоечников. Массивы для хранения студентов должны быть динамическими. Задание 2. Программа должна уметь сохранять базу в файл, читать ее из файла, модифицировать выбранного студента, меняя имя и оценки по выбору пользователя. Также программа должна сортировать студентов в лексикографическом порядке по имени.
«Структуры данных» 👇
Готовые курсовые работы и рефераты
Купить от 250 ₽
Решение задач от ИИ за 2 минуты
Решить задачу
Найди решение своей задачи среди 1 000 000 ответов
Найти

Тебе могут подойти лекции

Смотреть все 493 лекции
Все самое важное и интересное в Telegram

Все сервисы Справочника в твоем телефоне! Просто напиши Боту, что ты ищешь и он быстро найдет нужную статью, лекцию или пособие для тебя!

Перейти в Telegram Bot