- Структуры и объединения
- Работа
Структуры и объединения
Часто требуется объединить несколько переменных или типов данных (одинаковых или разных) в некую группу. Например, обрабатывая список сотрудников, удобно объединить в одну группу фамилию, имя и отчество сотрудника, и хранить такие группы в массиве. Это, с одной стороны, позволило бы при подсчете общего количества сотрудников просто считать такие группы, но с другой стороны, в любой момент можно получить имя любого из сотрудников по его номеру. Для подобной группировки введено понятие структуры.
Структура – это особая форма слияния нескольких переменных, называемых полями структуры, в единое целое.
Для определения структуры используется ключевое слово struct. Шаблон определения структуры следующий:
struct {<поле 1>; <поле 2>; … ; <поле N>;};
Здесь в фигурных скобках перечисляются поля структуры, которые есть ничто иное, как объявления переменных. Обратите внимание, на точки с запятой, завершающие определение каждого поля структуры. Структура – это разновидность типа, поэтому определение переменной типа структура осуществляется аналогично ранее рассмотренному объявлению простых переменных:
struct {int a; long b; char c;} st;
Этот пример показывает, как объявляется переменная st типа структура с полями а (типа int), b (типа long) и с (типа char). Обращение к переменным-полям структуры осуществляется через так называемую точечную нотацию, когда поле структуры отделяется от ее идентификатора точкой: st.a позволит обратиться к полю, а переменной st, а st.c – к полю ее полю с.
Ничто не препятствует объявить массив таких структур:
struct {int a; long b; char c;} st[5];
Этот пример определяет массив st, состоящий из 5-и элементов, каждый из которых имеет поля a, b и с соответствующих типов. Точечная нотация продолжает действовать и при обращении к элементам массива структур: st[1].a – поле a второго элемента массива, st[4].c – поле с последнего элемента.
Так же ничто не препятствует определить структуру как тип, и использовать для определения новых переменных уже этот тип:
typedef struct { int a; long b; char c;} strc;
strc st;
strc arr_st[5];
Язык Си считается самым низкоуровневым языком среди высокоуровневых. Под этим следует понимать, что язык позволяет получить возможность практически так же манипулировать данными, как и ассемблер. Одной из таких «низкоуровневых» возможностей являются объединения.
По виду описания объединение (определяемое ключевым словом union) очень похоже на структуру:
union { int a; long b; char c;} uni;
Однако, принципиальное отличие от структуры в том, что все поля объединения физически соответствуют одной и той же области памяти! Размер области памяти, выделяемой компилятором, определяется так, чтобы поместилось поле наибольшего размера, т.е. для вышеприведенного примера будет выделено 4 байта для переменной uni. При этом при обращении к uni.b будет задействована вся эта область, при обращении к uni.a - только первые 2 байта этой области, а uni.c позволит оперировать лишь первым байтом. То есть налицо обращение к одной и той области памяти, как к переменным разного типа.
Объединение, так же как и структура, может использоваться в описании нового типа, быть элементом массива и полем структуры. Действует правило: все, что уже определено, может быть использовано. Разумеется, все равнее сказанное в отношении переменных, применимо и к структурам и объединениям.