- •Занятие 10 Пользовательские типы данных
- •1. Структурный тип данных
- •1.1 Определение структуры
- •Int year; //год
- •Int year; //год
- •2. Оператор typedef
- •9.3 Определение структуры безымянного типа
- •9.4 Доступ к элементам структуры
- •9.5 Операции присваивания и сравнения для структур
- •9.7 Битовые поля
- •9.8 Объединения или смеси
- •9.9 Перечисления
9.5 Операции присваивания и сравнения для структур
Сравнивая структуры с массивами, обратим внимание на различия в операции присваивания. Для массивов допустимо присваивание значений только отдельным элементам. Для того, чтобы присвоить значения одного массива другому массиву, необходимо в цикле выполнить присваивание для каждого элемента.
Пример 11. Использование имен массивов без индексации приведет к ошибке.
float x[]={1.1, 2.0, 3.3, 4.4, 5.0}, z[10];
int j;
for (j=0; j<10; j++)
z[j] = x[j]; //правильное использование
…
z=x; //ошибка
При выполнения присваивания для структур разрешается использовать имена без уточнения полей.
Разрешается следующее присваивание:
sklad1 tea, meat, broad;
tea = meat; //ошибки нет
Напротив, операции сравнения для структур как единого целого не определены, можно сравнивать лишь отдельные элементы структуры.
Например, возможны такие логические выражения:
tea.price > meat.price
meat.in_day.day != broad.in_day.day,
но ошибкой будет сравнивать структуры целиком:
meat > tea.
9.6 Определение размера структуры. Оператор sizeof.
С помощью операции sizeof можно определить размер памяти, которая необходима переменной или типу. Операция sizeof имеет следующий формат:
sizeof (выражение).
В качестве выражения может быть использован любой идентификатор объекта или имя типа, заключенное в скобки. Отметим, что не может быть использовано имя типа void, а идентификатор не может относиться к полю битов или быть именем функции.
Если в качестве выражения указано имя массива, то результатом является размер всего массива, т.е. произведение числа элементов на длину типа.
Когда sizeof() применяется к пользовательским типам данных, т.е. к имени типа структуры или объединения или к идентификатору, имеющему тип структуры или объединения, то результатом является фактический размер структуры или объединения, полученный при компиляции. Этот размер может не совпадать с размером, получаемым путем простого сложения размеров полей структуры, потому что реально объект структуры может занимать большую память из-за дополнительных участков памяти, образующихся в результате выравнивания полей структуры.
Пример 12.
int a1;
struct
{char h;
int d;
double f;
} str;
a1 = sizeof (str);
Переменная а1 получит значение, равное 16 (байт), в тоже время если сложить длины всех используемых в структуре типов, то длина структуры str будет равна 13.
Данное несоответствие наблюдается потому, что после размещения в памяти первой переменной h длиной 1 байт добавляется 3 байта для выравнивания адреса переменной d на границу слова. Кроме того, следует обратить внимание, что понятие «слово» и «двойное слово» зависят от разрядности компьютера, поэтому результат этот верен только для 32-разрядных компьютеров.
Как видно из примера, размер структуры зависит не только от образующих ее элементов, но и от самых различных факторов, в том числе и от оптимизатора, который используется при компиляции. Поэтому если необходимо точно знать размер структурного объекта, его необходимо явно вычислить с помощью операции sizeof (), которую можно применять в двух формах:
sizeof (имя_структуры).
sizeof (имя_структурного_типа).
