14.3. Объявление структурных переменных
Как уже отмечалось само описание структуры не приводит к выделению под нее места в ОП. Теперь необходимо создать нужное количество переменных с приведенной структурой и сделать это можно двумя способами.
Способ 1. В любом месте программы для декларации структурных переменных, массивов, функций и т.д., используется объявленный в шаблоне структурный тип, например:
struct Stud_type student; — структурная переменная;
Stud_type Stud[100]; — массив структур;
int Fun(Stud_type W); — прототип функции с параметром структурного типа,
(Слово struct в первом примере является необязательным, и в остальных примерах оно опущено).
Способ 2: в шаблоне структуры между закрывающейся фигурной скобкой и символом «;» указывают через запятые идентификаторы структурных данных.
Для нашего примера, используя, можно записать:
char Number[10], Fio[40];
Если дальше в программе не понадобится вводить новые данные объявленного структурного типа, имя типа «Stud_type» можно не указывать.
При декларации структурных переменных возможна их одновременная инициализация
char Number[10], Fio[40];
Отметим, что если список инициализации будет короче, то оставшиеся поля структурной переменной будут заполнены нулями.
14.4. Обращение к полям структуры
Обращение к полю структуры производится при помощи составных имен, которые образуются с использованием операции принадлежности (.) в виде:
ID_структуры . ID_поля
Пример обращения для объявленного ранее шаблона:
Stud_Type s1, s2;
Обращение к полям этих структур будет иметь вид:
s1. Number, s1. Fio, s1. S_b;
s2. Number, s2. Fio, s2. S_b;
Примеры операторов с обращением к их полям:
int k=strcmp(s1. Number, s2. Number);
14.5. Операции со структурой как единым целым
Для структур одинакового типа допустимы следующие операции:
Сравнение на равенство и неравенство: s1==s2 либо s1!=s2
Подстановка в качестве аргумента на место параметра функции:
int Fun(Stud_type W);
14.6. Вложенные структуры
Структуры могут быть вложенными, т.е. поле структуры может cамо быть структурой, описание которой должно предшествовать описанию внешней структуры.
Например, в структуре person, содержащей сведения — Ф.И.О., дата рождения, можно сделать дату рождения внутренней структурой date по отношению к структуре person. Тогда шаблон такой конструкции будет выглядеть так:
int day, month, year;
Объявляем переменную такой структуры:
struct person a;
Тогда, обращение к полям структурной переменной a будет выглядеть следующим образом:
a .fio a.f1.day a.f1.month a.f1.year
14.7. Массивы структур
Структурный тип «struct ID_структуры», как правило, используют для декларации массивов, элементами которых являются структурные переменные. Это позволяет создавать программы, оперирующие с «примитивными базами данных». Например:
struct person spisok[100]; // spisok — массив структур
Или можно записать так:
int day, month, year;
В данном случае обращение к полю day i-той записи может быть выполнено, например, так:
Синтаксис: структуры в C и С++
Структура — это агрегатный тип данных, так как может содержать в себе разнотипные элементы. Синтаксис объявления структуры в С++ отличается от C. Хотя версия C остается правильной для C++. Получается, что в С++ можно двумя стилями объявления структур пользоваться, а в языке C — только одной. Смотрим синтаксис объявления структуры в языке С++:
- struct — ключевое слово, которое начинает определение структуры
- Name — имя структуры
- type — тип данных элемента структуры
- atrib — элемент структуры
- structVar1-2 — структурные переменные
Объявление структуры всегда должно начинаться с ключевого слова struct . Необязательно, чтобы структура имела имя, но тогда такая структура обязательно должна иметь структурные переменные, объявленные между закрывающей фигурной скобкой и точкой с запятой, строка 5. Обязательно в объявлении структуры должны присутствовать фигурные скобочки, они обрамляют тело структуры, в котором объявляются её атрибуты (элементы), строка 3. Структурные переменные, при объявлении структуры, указывать необязательно, строка 5.
Так как структура это тип данных, то, для того, чтобы использовать этот тип данных, необходимо объявить структурную переменную, а вместо типа данных указать имя структуры.
Синтаксис объявления структуры в языке Си:
Синтаксис объявления структуры в языке Си предполагает два варианта. П ервый, опустить ключевое слово typedef , при этом имя newStructName тоже не используется, и имя структуры, тогда обязательно необходимо при объявлении структуры использовать структурные переменные — structVar , строка 6. Смотрим пример:
Или вы можете воспользоваться typedef , для объявления псевдонима структуры newStructName , псевдоним:
В любом случае, если вы хотите, объявить указатель на структуру внутри структуры, вы должны использовать первый синтаксис:
Объявление указателя на структуру
Синтаксис объявления указателя на структуру в Си неоднозначен. В Си, если вы не используете typedef при определении структуры, то, в обязательном порядке необходимо использовать структурные переменные, между закрывающейся фигурной скобочкой и точкой с запятой.
В C++, этого не требуется. Чтобы объявить указатель на структуру, в С++ вы просто перед именем структурной переменной ставите символ указателя — * .
или так, тоже для СИ:
Доступ к элементам структуры
Доступ к элементам структуры так же прост, как использование символа «точка». Предположим. что у нас есть структурная переменная с именем car и у нее есть элемент с именем speed , к которому, мы сейчас получим доступ:
Доступ к элементам указателя на структуру
Чтобы получить доступ к элементам структуры, через указатель на структуру, вместо оператора «точка», используйте оператор стрелка -> :
Как стать программистом
Это моя личная ссылка-приглашение на Stepik для вас. Регистрируясь по этой ссылке, записываясь на курсы и решая задачи, Вы помогаете автору данного сайта принять участие в конкурсе платформы Stepik! Подробности конкурса здесь: https://vk.cc/75rKuS
среда, 7 января 2015 г.
Структуры в языке Си.
Прежде чем говорить о структурах, вспомним массивы. Как вы, наверное, помните, массивы предназначены для хранения однотипных данных. Другими словами каждый элемент массива представляет собой значение определенного типа: целое число, символ, строка. Но зачастую, в программах, требуется хранить в одном месте данные разных типов. В качестве примера, в этом уроке будем рассматривать программу каталог книг. Про каждую книгу нам известно: название, автор, год издания, количество страниц, стоимость.
Типы переменных, используемые для хранения подобных данных очевидны:
char[] – автор, название.
int – год издания, количество страниц.
float – стоимость.
На ум сразу приходит следующий вариант реализации. Завести для каждого отдельного качества отдельный массив. Например:
Тогда, обращаясь по i -му номеру к соответствующему массиву, мы могли бы получить требуемую информацию. Например, вот так мы могли бы вывести на экран автора, название и количество страниц четвертой книги (не забываем, что нумерация элементов массива начинается с нуля).
Оставим пока что эту реализацию, и посмотрим, как выполнить такую же задачу с использованием структур. Но прежде всего, определим, что такое структура.
Задумаемся, что такое структура в обычном понимании этого слова. Структура – это строение или внутренне устройство какого-либо объекта.
Структура в языке Си – это тип данных, создаваемый программистом, предназначенный для объединения данных различных типов в единое целое.
Прежде чем использовать в своей программе структуру, необходимо её описать, т.е. описать её внутреннее устройство. Иногда это называю шаблоном структуры. Шаблон структуры описывается следующим образом. На картинке слева, мы описали шаблон структуры с именем point . В любом шаблоне структуры можно выделить две основных части: заголовок (ключевое слово struct и имя структуры) и тело (поля структуры, записанные внутри составного оператора).
Точка с запятой в конце обязательна, не забывайте про неё.
Возвращаясь к нашему примеру, опишем структуру book с полями date, pages, author, title, price соответствующих типов.
Попутно отметим, что в качестве полей структуры могут выступать любые встроенные типы данных и даже другие структуры. Подробнее об этом я расскажу в другом уроке. На имена полей накладываются те же ограничения, что и на обычные переменные. Внутри одной структуры не должно быть полей с одинаковыми именами. Имя поля не должно начинаться с цифры. Регистр учитывается.
После того, как мы описали внутреннее устройство структуры, можно считать, что мы создали новый тип данных, который устроен таким вот образом. Теперь этот тип данных можно использовать в нашей программе.
ПРИМЕЧАНИЕ: Обычно структуры описываются сразу после подключения заголовочных файлов. Иногда, для удобства, описание структур выносят в отдельный заголовочный файл.
Объявление структурной переменной происходит по обычным правилам.
struct book kniga1;
Такое объявление создает в памяти переменную типа book , с соответствующими полями.
Отличие структурной переменной от обычной переменной удобно проиллюстрировать на примере с коробками. Считаем, что обычная переменная это просто коробка, в которую можно положить объект определенного типа, например, целое число.
Структурная переменная, это тоже коробка, внутри которой есть отдельные секции для хранения различных данных. Количество этих секций и типы данных, которые мы можем там хранить, задаются шаблоном структуры. На рисунке я постарался схематично изобразить устройство структурной переменной.
Отмечу, что я сознательно не касаюсь вопроса о том, как хранится структура в памяти, так как считаю, что для новичков эти тонкости будут излишни.
Кроме того, еще одну удобную интерпретацию структуры дает нам книга K&R. Можно думать о ней, как о строчке в таблице, где столбцами выступают поля структуры.
Если кто-то имел дело с реляционными базами данных (MySQL, Oracle), то вам эта такая интерпретация будет очень знакома.
Хорошо, переменную мы объявили. Самое время научиться сохранять в неё данные, иначе, зачем она нам вообще нужна. Мы можем присвоить значения сразу всем полям структуры при объявлении. Это очень похоже на то, как мы присваивали значения массиву при его объявлении.
Важный момент. Порядок и тип аргументов, должен совпадать с порядком и типом полей, описанных в шаблоне структуры. В нашем примере мы сначала записали дату, потом количество страниц, имя автора, название книги и стоимость. Пропустить какой-то аргумент нельзя, но можно не объявлять несколько последних. Т.е. вполне допустима следующая конструкция:
Для обращения к отдельным полям структуры используется оператор доступа «.» . Да-да, обычная точка.
Примеры:
Задание: Проверить, что хранится в полях структуры до того, как им присвоено значение.
Сейчас, в одной переменной типа book храниться вся информация об одной книге. Но так как в каталоге вряд ли будет всего одна книга, нам потребуется много переменных одного и того же типа book . А значит что? Правильно, нужно создать массив таких переменных, то есть массив структур. Делается это аналогично, как если бы мы создавали массив переменных любого стандартного типа.
Каждый элемент этого массива это переменная типа book . Т.е. у каждого элемента есть свои поля date, pages, author, title, price . Тут-то и удобно вспомнить о второй интерпретации структуры. В ней массив структур будет выглядеть как таблица.
Используя массив структур получить информацию об отдельной книге можно следующим образом.
Обращаясь к kniga[3].author мы обращаемся к четвертой строке нашей таблицы и столбику с именем author . Удобная интерпретация, не правда ли?
На данном этапе мы научились основам работы со структурами. Точнее мы переписали с использованием структур тот же код, который использовал несколько массивов. Кажется, что особой разницы нет. Да, на первый взгляд это действительно так. Но дьявол, как обычно, кроется в мелочах.
Например, очевидно, что в нашей программе нам часто придется выводить данные о книге на экран. Разумным решением будет написать для этого отдельную функцию.
Если бы мы пользуемся несколькими массивами, то эта функция выглядела бы примерно так:
А её вызов выглядел как-то вот так:
Не очень-то и компактно получилось, как вы можете заметить. Легче было бы писать каждый раз отдельный printf(); .
Совсем другое дело, если мы используем структуры. Так как структура представляет собой один целый объект (большую коробку с отсеками), то и передавать в функцию нужно только его. И тогда нашу функцию можно было бы записать следующим образом:
И вызов, выглядел бы приятнее:
Вот это я понимаю, быстро и удобно, и не нужно каждый раз писать пять параметров. А представьте теперь, что полей у структуры бы их было не 5, а допустим 10? Вот-вот, и я о том же.
Стоит отметить, что передача структурных переменных в функцию, как и в случае обычных переменных осуществляется по значению. Т.е. внутри функции мы работаем не с самой структурной переменной, а с её копией. Чтобы этого избежать, как и в случае переменных стандартных типов используют указатель на структуру. Там есть небольшая особенность, но об этом я расскажу в другой раз.
Кроме того, мы можем присваивать структурные переменные, если они относятся к одному и тому же шаблону. Зачастую это очень упрощает программирование.
Например, вполне реальная задача для каталога книг, упорядочить книги по количеству страниц.
Если бы мы использовали отдельные массивы, то сортировка выглядела бы примерно так.
Совсем другой дело, если мы используем структуры.
Неоспоримое удобство, не правда ли?
Надеюсь, у меня получилось достаточно убедительно показать преимущества использования структур.
На этой радостной ноте, я и завершаю сегодняшний урок.
C++. Структуры. Часть 1. Составные типы данных. Шаблон структуры. Структурная переменная. Структуры в среде CLR. Объявление и инициализация структурной переменной
Структуры. Часть 1. Составные типы данных. Шаблон структуры. Структурная переменная. Структуры в среде CLR . Объявление и инициализация структурной переменной
Содержание
- 1. Какое отличие между базовыми и составными типами данных?
- 2. Какие типы данных в C++ принадлежат к составным или агрегатным типам данных?
- 3. Что называется структурой в C++ ? Что называется полем структурной переменной?
- 4. Каким образом классифицируются структуры в среде CLR ? Native -структуры. Managed -структуры
- 5. Какая общая форма объявления native -структуры (шаблона структуры)?
- 6. Какая общая форма объявления managed -структуры с квалификаторами ref и value ?
- 7. Что такое шаблон (формат) структуры? Примеры задания шаблона
- 8. Что такое структурная переменная? Способы объявления структурных переменных. Доступ к полям структурной переменной
- 9. Где можно задавать шаблон структуры в среде CLR ?
- 10. Как осуществляется инициализация структурной переменной при ее объявлении? Пример инициализации native -структурной переменной
- Связанные темы
Поиск на других ресурсах:
1. Какое отличие между базовыми и составными типами данных?
Все типы данных в C++ делятся на:
- базовые типы данных ;
- составные (агрегатные) типы данных.
Переменные базовых типов данных состоят из одного элемента данных. Переменные составных типов данных содержат два и больше элемента данных.
2. Какие типы данных в C++ принадлежат к составным или агрегатным типам данных?
Составные типы данных еще называют агрегатными или конгломератными типами данных.
К составным или агрегатным типам данных принадлежат:
- массивы;
- структуры;
- объединения;
- перечисления ( enumeration );
- классы.
3. Что называется структурой в C++ ? Что называется полем структурной переменной?
Структура – это объединения одной или больше переменных в одной области памяти, которая имеет одно имя.
Структура – это объединение (группирование) переменных, которые родственны между собою по некоторому критерию.
Переменные, входящие в структуру называются полями структуры. Такие переменные могут быть разных типов. Имена полей (переменных) в одном шаблоне должны быть уникальными. Однако, в разных шаблонах имена могут повторяться.
4. Каким образом классифицируются структуры в среде CLR ? Native -структуры. Managed -структуры
Среда CLR поддерживает объявление структур двух видов:
- native -структуры;
- managed -структуры или управляемые структуры.
Native -структуры – это классические структуры языка C/C++.
Managed -структуры – это структуры, которые размещаются в памяти, которая выделяется и управляется средой CLR .
Managed -структуры могут быть объявлены с одним из двух квалификаторов:
- квалификатор ref – означает, что структура есть ссылочного типа;
- квалификатор value – означает, что структура есть типом-значением.
Отличие между квалификаторами ref и value состоит в способе выделения памяти для указателя на структуру. Более подробно работа с указателями на managed -структуры описана здесь .
5. Какая общая форма объявления native -структуры (шаблона структуры)?
Для объявления native -структуры (или шаблона структуры) используется ключевое слово struct . Общая форма объявления структуры:
- имя_типа_структуры – название шаблона структуры. Шаблон структуры описывает новый тип данных, который может быть использован в дальнейшем в программе на C++ ;
- тип – тип данных, которые имеются в наличии на данный момент в программе;
- элемент1 , элемент2 , …, элементN – названия элементов (переменных), входящих в структуру. Элементы структуры еще называются полями структуры;
- структурные_переменные – это переменные, которые есть структурами. В случае объявления шаблона структуры структурные_переменные могут отсутствовать (смотрите следующие пункты).
6. Какая общая форма объявления managed -структуры с квалификаторами ref и value ?
Общая форма объявления структуры (шаблона структуры) с квалификатором ref :
Общая форма объявления структуры (шаблона структуры) с квалификатором value :
В вышеприведенных описаниях:
- имя_типа_структуры – название шаблона структуры. Шаблон структуры образовывает новый тип данных, который может быть использован в дальнейшем в программе;
- тип – тип данных, имеющихся на данный момент в программе;
- элемент1 , элемент2 , …, элементN – названия элементов (переменных), входящих в структуру. Элементы структуры еще называются полями структуры;
- структурные_переменные – это переменные, которые есть структурами. В случае объявления шаблона структуры структурные_переменные могут отстствовать.
Более подробно работа с managed -структурами описана в теме:
7. Что такое шаблон (формат) структуры? Примеры задания шаблона
Чтобы описать структурную переменную, нужно сначала задать шаблон структуры. Шаблон структуры еще называется формат структуры. При задании шаблона структуры память не выделяется. Шаблон – это только описание (информация), переменные каких типов должны входить в структуру.
Пример 1. Описание шаблона структуры, которая описывает информацию об отработанных часах работником.
Шаблон содержит следующую информацию:
- код работника;
- фамилия и имя работника;
- количество отработанных часов;
- расценка за 1 час.
В данном примере шаблон называется Worker . В шаблоне описываются следующие поля (переменные):
- code – код работника;
- name – имя работника;
- hours – количество отработанных часов;
- cost – расценка за 1 час.
Пример 2. Объявление шаблона с именем Laboratory , содержащего информацию о лаборатории в учебном заведении:
- номер лаборатории;
- название лаборатории;
- площадь лаборатории;
- количество посадочных мест.
Для managed-структур перед словом struct указывается квалификатора ref или value .
8. Что такое структурная переменная? Способы объявления структурных переменных. Доступ к полям структурной переменной
Структурная переменная – это переменная типа, который задан в шаблоне структуры. Если объявляется такая переменная, то происходит выделение памяти для нее. Структурная переменная еще называется экземпляром структуры.
Структурную переменную можно объявить несколькими способами:
- на основе шаблона, который был объявлен раньше;
- во время объявления шаблона;
- с помощью квалификатора typedef .
Ниже приведены все 3 способы объявления структурной переменной, которая базируется на основе шаблона Worker , описывающего информацию о работнике. Рассмотрен пример для native -структуры.
Тогда структурную переменную можна описать следующими способами.
Способ 1. Описание переменной на основе ранее заданного шаблона Worker . В этом случае сначала задается шаблон структуры, затем описывается переменная (экземпляр структуры).
В вышеприведенном примере объявляется переменная с именем w на основе ранее описанного шаблона Worker . Затем для примера заполняются поля структурной переменной.
Способ 2. Объявление переменной во время задания шаблона. В этом способе объединяется объявление шаблона структуры и создание экземпляра структуры (переменной).
Доступ к полям переменной w1 из другого прогаммного кода
Способ 3. Объявление переменной на основе типа, созданного с помощью квалификатора typedef .
Пусть в некоторой части программы объявлен новый тип WORKER , который основан на структуре Wrk , содержащей информацию о работнике:
Тогда, чтобы использовать переменную с именем w2 типа WORKER , нужно написать следующий код:
В этом способе задавать имя шаблона структуры Wrk необязательно. То есть, следующая запись также есть корректной
9. Где можно задавать шаблон структуры в среде CLR ?
В среде CLR рекомендуется объявлять шаблон структуры или новый тип на базе структуры (средство typedef ) в отдельном «*.h» файле, например «MyStruct.h» . Тогда удобно подключать эту структуру в другие модули программы, например:
10. Как осуществляется инициализация структурной переменной при ее объявлении? Пример инициализации native -структурной переменной
Пусть задан шаблон структуры Worker
Тогда инициализация структурной переменной может быть такой.
Способ 1. Объявление и инициализация переменной после того, как раньше был задан шаблон структуры Worker
Способ 2. Объединение задания шаблона, описания структурной переменной и ее инициализации.
Способ 3. Если задан тип с помощью квалификатора typedef , тогда инициализация структурной переменной будет следующей