C Урок 25. Структуры



В данном уроке мы познакомимся со структурами, для чего они нужны и как мы их можем использовать в наших программах.

Нередко в программе может потребоваться объединить несколько переменных различного типа в какой-то один набор для достижения той или иной общей цели. Например, нам нужно описать какой-нибудь товар и создать для него какую-то переменную, которая могла бы хранить ряд его свойств — наименование полное, наименование краткое, вес, цену, количество, единицу измерения и так далее. Эти свойства здесь имеют, как мы видим, различный тип данных, здесь есть и строки, есть и числа с плавающей точкой, могут быть и другие типы данных, а объединить мы их все хотим в какую-то общую группу, присвоить ей какое-то своё отдельное имя, создавать потом с этим именем переменные и обращаться к ним по данному имени, чтобы получить затем вышеперечисленные значения, а также их изменять в ходе нашей программы.

Вот именно в такой ситуации нам на помощь и приходят структуры.

Структура в языке C — это сгруппированные (ая) под одним именем одна или несколько переменных (возможно, различных типов). В качестве этих переменных могут быть также массивы данных, указатели на различные типы данных, также переменные других типов структур и т.д.

Вот общий вид объявления структуры

 

 

Это самое классическое объявление структур, но используется часто.

Вот так например, мы можем описать структуру для какого-то товара

 

struct goods

{

   char nm[60];

   float amount;

   char measure[20];

   float price;

   float wieght;

};

 

Затем в коде мы можем объявлять переменные типа нашей структуры вот таким образом

 

struct goods st1;

 

Затем мы можем обращаться к данным нашей структуры через точку.

Давайте проинициализируем переменные нашей структуры, которые, кстати, называются ещё полями

 

strcpy(st1.nm, "Цемент");

st1.amount = 551.;

strcpy(st1.measure, "мешок");

st1.price = 350.35;

st1.wieght = 50.;

 

Объявлять наши структуры мы можем также и через стандартное объявление типов с помощью директивы typedef, тогда уже имя типа данных нашей структуры будет следовать после блока с переменными

 

typedef struct

{

   char nm[60];

   float amount;

   char measure[20];

   float price;

   float wieght;

} goods;

 

Переменные типов таких структур мы уже объявляем без ключевого слова struct

 

goods st1;

 

После этого мы с данной переменной работаем таким же образом, как и с переменными типов структур, объявленных классическим способом.

Также не лишним будет упомянуть, что переменные наших структур могут использоваться в функциях в качестве возврата. Это один из способов вернуть сразу несколько значений разного типа из функции.

Инициализировать поля переменных типов структур мы можем также и во время их объявления.

 

 

Например, наш товар мы можем описать вот таким способом

 

goods st1 = {"Цемент", 551., "мешок", 350.35, 50.};

 

Также структуры можно объявлять с помощью создания указателей на них, но это будет рассмотрено в более поздних уроках, когда мы познакомимся с указателями и их использованием.

А, думаю, что пока нам теории по структурам вполне достаточно.

Давайте теперь поработаем со структурами практически.

Создадим проект с именем MYPROG25, который был сделан на основе проекта прошлого урока с именем MYPROG24.

Откроем наш проект в Eclipse, произведём его первоначальную настройку и удалим весь наш код из функции main() за исключением возврата, а то больно много там всего набралось. Функция main() приобретёт вот такой вид

 

int main()

{

   return 0; //Return an integer from a function

}

 

Удалим также объявление перечисления, в том числе и закомментированное, также объявление переменной пользовательского типа. Удалим функции print_res и my_counter с их телами, а также прототипы на них.

Представим, что у нас есть задача описать несколько студентов, у которых будут ФИО, возраст и информация о том, на каком курсе данный студент обучается, так сказать, минимальная информация.

Объявим вот такую глобальную структуру (хотя если мы с данной структурой хотим работать только в рамках какого-то блока, то она вполне имеет право быть и локальной)

 

 

Мы объявили структуру, с именем student, в которой присутствуют переменные (поля) — строковый массив и две беззнаковых целочисленных переменных, также имеющих свои имена.

В функции main() объявим переменную типа нашей структуры

 

 

Проинициализируем её поля

 

 

Мы объявили переменную нашей структуры, и заполнили её поля, тем самым мы получили переменную, в которой описали одного студента — его ФИО, возраст и курс. Выведем эти данные в консоль

 

 

 

Соберём код и посмотрим, что у нас получилось

 

 

Если у кого-то некорректно выводится кириллица, то настройки находятся в Window -> Preferences вот в этой ветке

 

 

Добавим ещё одного студента и выведем в консоль и его данные аналогичным образом

 

 

Посмотрим результат в консоли

 

 

Отлично!

Попробуем теперь объявить тип данных структуры с помощью директивы typedef. Закомментируем предыдущее объявление структуры и объявим её следующим образом

 

 

В main в объявлениях переменных типа нашей структуры теперь мы можем ключевое слово struct убрать

 

struct student st1;

struct student st1;

 

После этого наш код будет также успешно работать.

Только вот если у нас будет много студентов, то так работать с ними будет неудобно. Поэтому закомментируем наш код и объявим массив таких структур

 

 

Инициализируем несколько элементов нашего массива и выведем наших студентов в цикле в консоль

 

 

Посмотрим результат

 

 

Объявление массива оставим, остальной код закомментируем.

Создадим глобальный счётчик наших студентов

 

 

Ниже функции main() добавим вот такую функцию

 

 

Данная функция будет получать в качестве параметров ФИО, курс и возраст нашего студента, объединять всё это в переменную структуры и возвращать её.

Добавим на нашу функцию прототип

 

 

Теперь в функции main() добавим вот такой код

 

 

Данный код будет добавлять студента с его данными в массив, проверяя, не превысили ли мы максимальное количество элементов нашего массива, так как язык такие вещи самостоятельно не контролирует. Затем мы в цикле выводим в консоль наши данные. Проверим работу нашего кода

 

 

Всё выводится.

Итак, на данном занятии мы познакомились со структурами, для чего они нужны и как мы можем их использовать в нашем коде.

Всем спасибо за внимание!

 

 

Предыдущий урок Программирование на C Следующий урок

 

Исходный код

 

 

Смотреть ВИДЕОУРОК (нажмите на картинку)

 

C Структуры

8 комментариев на “C Урок 25. Структуры
  1. Влад:

    student st[0]; выдаёт ошибку «could not be resolved». Пересборка индексов командой «Project->C/C++ Index->Re-resolve unresolved includes» не даёт результата. Команда «Project->C/C++ Index->Search for unresolved includes» возвращает «0 unresolved includes». Понимаю, что это ошибка самого Eclipse. Лезть в Error Parsers боюсь, т.к. ничего о нём не знаю.

  2. Влад:

    Решено. Пришлось переписать Makefile. Извиняюсь за беспокойство.

  3. rediska:

    Описали, объявили-понятно
    Вдруг — хрясь! — strcpy
    Что это, зачем это? Посмотреть на каком-то другом сайте? Так может и про структуры там же прочитать?

  4. Андрей:

    Откуда взялось st1 после имени структуры в объявлении? Ни на одном сайте не пишут, откуда это берется и что это такое. Такое ощущение, что сами не знают…

  5. Снимаю перед вами шляпу, ибо еще в далеком 88 году (и еще несколько лет потом) писал на С программы, но даже с таким «багажом» узнаю не мало интересного по ходу пьесы )) Но иногда впадаю просто в ступор. Попробую обьяснить почему на примере концовки урока. Проверяем мы выход за границы массива структур в теле main, а вот индекс массива меняем … в процедуре. Я сначала подумал что запись создастся одна (ибо ожидал увидеть ++ индекса в майн))) При таком подходе как у Вас логичнее было бы и массив структур делать глобальным (и часто так и делается в реальных проектах) и, если уж индекс мы меняем в процедуре, в ней же и проверять выход за границы масива и вносить/не вносить данные соответственно. Такие «места» в логике потом очень большое недоумение вызывают, когда программа вроде работает и без ошибок, но не так как хотелось бы )) Все таки новичков учите. Но это я так. Брюзжу наверное… Большое спасибо за уроки, особенно по микропроцессорам. Там реально не паханный для меня край ))

  6. TheBlindWatchmaker:

    Подвохи классные.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*