- •Лекция 18 Структуры. Объединения. Поля битов в структурах
- •Структура как пользовательский тип и совокупность данных Определение шаблона структуры и структурной переменной
- •Расположение структурных переменных в памяти
- •Инициализация структурных переменных
- •Вложенные структуры
- •Операции над структурными переменными
- •Массив структур
- •Структура в качестве аргумента функции
- •Примеры работы со структурами
- •Объединение как пользовательский тип и совокупность данных Определение объединения и переменной объединяющего типа
- •Примеры использования объединений Получение внутреннего представления вещественного числа
- •Использование перечислимого типа для обращения к полям объединения
- •Битовые поля структур и объединений Определение битовых полей
- •Примеры использования битовых полей Вывод значений битовых полей
- •Формирование кода символа с помощью битовых полей объединения
- •Формирование байта и вывод на экран его двоичного представления
Расположение структурных переменных в памяти
Изучая структуры, имеет смысл обращать внимание на их представление в памяти компьютера. Порядок описания полей в определении структурного типа задаёт порядок их расположения в памяти.
Рассмотрим структуру:
struct {
long L;
int i1, i2;
char c[4];
} STR1;
В памяти каждый элемент имеет свое место, и размещаются они последовательно:
f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
long L int i1 int i2 char c[4]
Компилятор выделяет под структурную переменную STR1 число байтов памяти, достаточное для хранения всех ее полей. Однако выделенное количество байт не всегда равно сумме длин отдельных полей из-за влияния дополнительного фактора внутреннего представления структурных переменных, называемого выравниванием.
При выравнивании на границе байта отдельные поля структурной переменной в памяти располагаются без зазоров, с любого четного или нечетного адреса; размер занимаемой структурной переменной памяти равен сумме размеров полей шаблона структуры.
Выравнивание на границе байта устанавливает директива препроцессора #pragma pack(push,n); аргумент n задает выравнивание данных в структурах на n байт ( n=(1,2,4,8,16) ). Отмена директивы: #pragma pack(pop). Директива #pragma pack(show) выводит в качестве warning значение выравнивания по умолчанию, например: value of pragma pack(show) == 8.
При выравнивании на границе слова компилятор при размещении структурной переменной в памяти может вставлять между полями пустые байты для того, чтобы соблюдались следующие правила:
отдельная структурная переменная (элемент массива структурных переменных) начинается на границе слова;
любое поле, тип которого не совпадает с типом char, будет начинаться на границе слова;
при необходимости в конце структурной переменной добавляются байты.
Расположение в памяти структурной переменной STR2 при наличии выравнивания на границе слова:
struct {
long L;
char c[3];
int i1, i2;
} STR2;
f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
long L char c[3] int i1 int i2
Сумма размеров элементов структуры (4+3+4+4=15) меньше, чем отведено структуре в целом (16) из-за того, что размер массива char c[3]; не кратен длине слова компьютера и перед элементом int i1 для выравнивания вставлен пустой байт.
Выделенное число байт возвращает операция sizeof .
