Правила выравнивания структурных переменных в памяти
Может быть указано выравнивание на границе слова (1) или байта (2).
В 1-м случае все не символьные данные размещаются с чётных адресов. В представлении структуры в памяти могут появиться «зазоры». «зазоры» могут появитmся и между элементами массивы. Во 2-м случае этого не происходит.
Выравнивание задаётся в опциях кодогенерации (Option-Code Generation-Alignement: Byte/Word)
Выравнивание играет роль при передаче данных между диском и памятью, когда может быть что файл создавала программа, в которой был указан один тип выравнивания, а чтение и обращение выполняет программы с другим типом выравнивания.
Поля битов в структурах
Общий синтаксис описания такого поля:
тип[имя]: ширина;
Значение тип может быть signed/unsigned (вместо или дополнительно к signed или unsigned можно указывать int). Ширина определяет число бит, сопоставленных полю. Если имя не указано, то доступ к полю невозможен, хотя разряды всё равно выделяются.
Пример
struct EXAMPLE{ int i:2;
unsigned j:2;
int :2;
int k:2;
int dummy:8;} my_struct;
Общая ширина всех полей выравнивается до границы слова. В примере 16-бит.
При ссылке к полю в выражении соответствующие полю разряды выделяются и сдвигаются вправо так, чтобы получился тип signed или unsigned.
Пример
my_struct.dummy = 0;
my_struct.i = 3;
my_struct.j = 3;
my_struct.k = -5;
printf(“%x\n”, my_struct);
printf(“%d%u%d\n”, my_struct.i, mystruct.j, my_struct.k);
Печать: ff
-1 3 -1
При определении значений необходимо учитывать что отрицание - в дополнительном коде.
Объединения
Отличием объединений от структурных переменных является то, что все поля объединения(одного уровня) начинаются с общей границы. Длиной объединения является максимальная из длин отдельных полей шаблона. Можно создавать и массив объединений. Инициализация объединения выполняется только для первого описанного поля. Объединения могут входить также и в записи. Обратное тоже возможно.
Основное назначение – это возможность совместить различные структуры данных в пределах одного участка памяти.
Пример
struct { char *name;
int flags;
int utype;
union { int ival;
float fval;
char *pval;
} uval;
} symtab[NSYM];
Здесь совмещаемое в пределах одного участка памяти размещение переменных ival, fval, и *pval. Чтобы различать используемый тип данных в процессе выполнения программы используется флаг utype. Например можно выбрать, что:
· utype = 0, и тогда обращение к ival,
· utype = 1, и тогда обращение к fval,
· utype = 2, и тогда обращение к *pval.
Организация проверки конкретной ситуации возлагается на программиста, например следующим образом:
if (symtab[i].utype = 2)
{
symtab[i].uval.pval = (char*)malloc(STR_LENGTH);
*symtab[i].uval.pval = ‘A’;
}
В представленных выше примерах предполагается, что идентификаторы NSYM и STR_LENGTH соответствуют программным константам.
Вопросы для самоконтроля
- Как выглядит описание шаблона структур?
- Можно ли декларировать структурную переменную без указания имени шаблона?
- Как записывается в декларациях инициализация полей структур?
- Что означает запись в программе: «typedef long int MyT;»?
- Перечислите допустимые операции над структурами!
- Как формулируются правила выравнивания структурных переменных?
- Декларации полей битов в структурах, - как рассчитывается количество выделяемой памяти?
Вопросы для самостоятельного изучения
- Изучить тему «Массивы структурных переменных»!
- Можно ли инициализировать массивы структур?
Дата добавления: 2016-05-26; просмотров: 1562;