
- •21. Структуры и объединения
- •21.1. Понятие структуры
- •21.2. Декларация структурного типа данных
- •21.3. Объявление структурных переменных
- •21.4. Обращение к полям структуры
- •21.5. Операции со структурой как единым целым
- •21.6. Вложенные структуры
- •21.7. Массивы структур
- •21.8. Размещение структурных переменных в памяти
- •21.9. Битовые поля
- •21.10. Объединения
- •21.11 . Указатели на структуры
- •22. Файлы в языке с
- •22.1. Типы файлов.
- •22.2. Открытие файла
- •22.3. Закрытие файла
- •22.4. Запись - чтение информации
- •А) Посимвольный ввод-вывод
- •Б) Построчный и форматированный ввод-вывод
- •В) Блоковый ввод-вывод
- •Int fflush(file *stream);
- •22.5. Текстовые файлы
- •22.6. Перенаправление стандартного ввода-вывода
- •22.7. Бинарные файлы
- •22.8. Дополнительные полезные функции
- •22.9. Простейший пример создания собственной базы данных
21.7. Массивы структур
Структурный тип "struct ID_структуры", как правило, используют для декларации массивов, элементами которых являются структурные переменные. Это позволяет создавать программы, оперирующие с "примитивными базами данных". Например:
struct person spisok[100]; // spisok - массив структур
Или можно записать так:
struct person {
char fio[40];
int day, month, year;
} spisok[100];
В данном случае обращение к полю day i-той записи может быть выполнено, например, так:
spisok[i].day=22;
21.8. Размещение структурных переменных в памяти
Элементы структур в общем случае размещаются в памяти последовательно с учетом выравнивания начальных адресов полей.
Выравнивание (align) означает, что компилятор выбирает адреса переменных (в т.ч. полей структуры) так, чтобы они были кратны некоторой величине. Эта величина определяется типом переменной и особенностями адресации данных этого типа на аппаратном уровне (чаще всего она равна 2). Часто выравнивание не обязательно, но при этом скорость обращения к объекту может снижаться. Если выравнивание производится, компилятор может быть вынужден добавить между полями структуры пустые байты, и тогда размер структуры (определяемый с помощью sizeof) будет превышать сумму размеров ее полей.
21.9. Битовые поля
Наряду с "обычными" типами, допустимыми и для "отдельных" переменных, поля структуры могут иметь особый целочисленный тип, допустимый только для них - битовые поля.
Битовые поля содержат заданное количество бит, необязательно кратное байту, но не превосходящее количество бит в типе int (в С++ Builder'е - 32). Они могут быть знаковыми (по умолчанию - signed) либо беззнаковыми (unsigned) , причем слово signed обычно опускается. В знаковых полях старший бит означает знак числа, аналогично всем целочисленным типам (см. выше тему "Кодирование целых чисел").
Объявление знакового битового поля имеет вид:
int a:размер;
а беззнакового битового поля:
unsigned b:размер;
где размер - количество бит в поле.
Пример:
struct T {
int a:5, b:4;
unsigned c:5;
float d;
unsigned e:2, f:5;
};
Выравнивание, рассмотренное выше, выполняется не для отдельных битовых полей, а только для совокупностей подряд идущих битовых полей (именно поэтому битовые поля применяются лишь в составе структур). Так, в приведенном примере битовые поля a, b и c располагаются в памяти подряд, занимая вместе одну двухбайтовую ячейку, как показано на схеме:
№ бит |
15 14 |
13 12 11 10 9 |
8 7 6 5 |
4 3 2 1 0 |
Поля |
|
c |
b |
a |
Как видно из рисунка, поля располагаются в ячейке от младших бит к старшим; при этом в примере последние 2 бита остались неиспользованными.
Аналогично, поля e и f занимают однобайтовую ячейку:
№ бит |
7 |
6 5 4 3 2 |
1 0 |
Поля |
|
F |
e |
Если размер объединенной ячейки превысил бы размер типа int, компилятор может разбить ее на отдельные меньшие ячейки.
Общая схема распределения памяти под структуру типа Т:
№ байт |
0 1 |
2 3 4 5 |
6 |
Поля |
a,b,c |
D |
e,f |
Заметим, что адрес отдельного битового поля получить невозможно.
Битовые поля позволяют:
уменьшить размер памяти, отводимой под переменную. В примере поля a,b,c,e,f в сумме заняли лишь 3 байта;
они упрощают доступ к отдельным битам какой-либо ячейки. Например, если структура с битовыми полями сама является полем объединения (см. ниже), такие поля дают прямой доступ к отдельным битам других полей объединения.