Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lektsii_po_si.doc
Скачиваний:
13
Добавлен:
12.11.2018
Размер:
11.78 Mб
Скачать

Выделение памяти для структур.

Выделение памяти для структур. Мы уже договорились, что определение структурного типа не связано с выделением памяти, а при каждом определении структуры (объекта) ей выделяется память в таком количестве, чтобы могли разместиться данные всех элементов. На рис. 6.1 приведены условные схемы распределения памяти для одного из объектов (структур) типа goods. На первой схеме элементы структуры размещены подряд без пропусков между ними. Однако никаких гарантий о таком непрерывном размещении элементов структур стандарт языка Си не дает. Причиной появления неиспользованных участков памяти ("дыр") могут явиться требования выравнивания данных по границам участков адресного пространства. Эти требования зависят от реализации, от аппаратных возможностей системы и иногда от режимов (опций) работы компилятора. На рис. 6.1 условно изображен и второй вариант с пропуском участка памяти между элементами float percent и int vol. Пропуск ("дыра") может быть и после последнего элемента структуры. В этом случае память для следующего объекта, определенного в программе, будет выделена не сразу после структуры, а с промежутком, оставляемым для выравнивания по принятой границе участка адресного пространства.

Необходимость в выравнивании данных зависит от конкретной задачи. Например, доступ к целым значениям выполняется быстрее, если они имеют четные адреса, т.е. выравнены по границам машинных слов. Противоположное требование состоит в плотной "упаковке" информации, когда идет борьба за уменьшение объема, занимаемого в памяти структурой или массивом структур. Влиять на размещение структур можно с помощью препроцессорной директивы #pragma (см. гл. 3).

Определение структурного типа:

struct goods { char* name; long price; float percent;

int vol;chardate[9]

};

Размещение элементов с выравниванием данных

Рис. 6.1. Размещение структуры типа goods в памяти (размеры в байтах для разных реализаций могут быть другими)

В зависимости от наличия "пропусков" между элементами изменяется общий объем памяти, выделяемый для структуры. Реальный размер памяти в байтах, выделяемый для структуры, можно определить с помощью операции

sizeof (имя_структуры)

sizeof (имя_структурного_типа)

Для нашего примера одинаковые результаты дадут операции:

В последнем выражении имя структуры coat только для разнообразия помещено без скобок. Напомним, что операция определения размера имеет две формы:

sizeof (имя_типа_данных)

sizeof выражение

В случае операнда-выражения его не обязательно заключать в скобки и его значение не вычисляется. Для него определяется тип и оценивается его размер (в байтах).

Инициализация и присваивание структур.

Инициализация и присваивание структур. Инициализация структур похожа на инициализацию массивов. Непосредственно в определении конкретной структуры после ее имени и знака '=' в фигурных скобках размещается список начальных значений элементов. Например:

Сравнивая структуры с массивами, нужно обратить внимание на одну особенность, связанную с операцией присваивания. Если определены два массива одного и того же типа и одинаковых размеров, то присвоить элементам одного массива значения элементов другого массива можно только с помощью явного перебора элементов, например, в цикле

Попытка использовать имена массивов без индексов в операции присваивания будет обречена на провал (ведь имя массива есть неизменяемый указатель):

В то же время стандарт языка Си разрешает присваивание структур. Если не обращать внимание на смысл имен введенных выше структур типа struct goods (tea - чай; coat - пиджак), то допустимо следующее присваивание:

Определив структуру типа complex, можно выполнить, например, такое присваивание (структура sigma того же типа определена и инициализирована выше):

Отметим, что для структур не определены операции сравнения даже на равенство. И сравнивать структуры нужно только поэлементно.