Из базовых типов данных (и типов определенных программистом) можно формировать производные типы, к которым относятся указатели, массивы, функции, структуры и объединения.
Данные базовых типов (int, float, …) считаются скалярными данными. Массивы и структуры являются агрегирующими типами данных в отличие от объединений и скалярных данных, которые относятся к неагрегирующим типам. Т.е. агрегирующий тип включает несколько компонентов, например, массив в общем случае состоит из совокупности элементов. Для агрегирующего типа данных выделяется такое количество памяти, чтобы разместить одновременно значения всех его элементов. Кроме массивов, состоящих из однородных элементов, в языке С определен такой агрегирующий тип данных как структура.
Структура – это совокупность переменных, объединенных одним именем, представляющая общепринятый способ хранения информации.
Структуры помогают в организации сложных данных (особенно в больших программах) поскольку позволяют группу связанных между собой элементов трактовать не как множество отдельных элементов, а как единое целое.
Например, состав зачетной ведомости группы может быть представлен следующими данными:
- номер в списке (int);
- фамилия имя отчество студента (char[]);
- оценка (int).
Структуры могут копироваться, над ними могут выполняться операции присваивания, их можно передавать функциям в качестве аргументов, а функции могут возвращать их в качестве результатов.
Для определения таких данных в программе и используется структурный тип данных, для описания которого используется ключевое слово struct:
struct InspectSheet {
int Number;
char Names[40];
int Mark;
};
1. В общем случае формат определения структурного типа таков:
struct <имя_структурного_типа>
{<определения_элементов>};
struct – спецификатор структурного типа.
<имя_структурного_типа> - идентификатор, произвольно выбираемый программистом.
<определения_элементов> - совокупность одного или более описаний объектов, каждый из которых служит прототипом для элементов вводимого структурного типа.
Следует обратить внимание на то, что <имя_структурного_типа> в некотором смысле эквивалентно типу (int, double и т.п.), а не имени переменной.
2. Еще одним способом определения структур является использование препроцессорной директивы typedef:
typedef struct {<определения_элементов>}
<обозначение_структурного_типа>;
В этом случае используется так называемый безымянный структурный тип.
При определении структурного типа при помощи typedef можно указывать еще и имя типа:
typedef struct COMPLEX
{
double real;
double imag;
} complex;
Это позволяет впоследствии использовать как имя структурного типа, так и его обозначение. Правильно будет:
complex first; // Определяем переменную типа complex
struct COMPLEX first; // Определяем переменную типа complex
Теперь рассмотрим правила определения элементов в структурах. В принципе они подобны определениям данных соответствующих типов. Однако имеется и существенное отличие: при определении типа не создается соответствующий объект в памяти, а это значит - элементы структуры нельзя инициализировать. Только после определения типа можно определять соответствующую программную переменную. Однако допустимо определение структур одновременно с их описанием. В этом случае используется конструкция:
struct List {//Определяем тип данных – обычно в заголовочном файле
int n;
char Name[40];
} Var1, Var2, Var3;
Размер памяти, выделяемый для размещения объектов структурного типа можно получать при помощи операции
sizeof(<имя структуры>)
sizeof(<имя структурного типа>)