Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
отчет по срсп.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
180.74 Кб
Скачать

Структуры, объединения, битовые поля

составление структуры и объединения на языке Си

Краткие теоретические сведения

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

структурный шаблон, или тип данных;

переменную структурного типа. Общее описание структурного шаблона:

struct имя шаблона

{

имя_типа1 имя_поля1;

имя_типаN имя_поля>^;

};

Общее описание переменной структурного типа:

struct имя шаблона имя переменной;

Для обращения к каждому полю переменной структурного типа перед ним ставится имя переменной с точкой.

Память под элементы структуры выделяется последовательно, элемент за элементом, слева направо, от младших адресов к старшим.

Переменная структурного типа может быть инициализирована при описании:

struct Student

{

char FIO [30]; // Совмещено объявление

char ID_Cod[9]; // структурного шаблона и

int BirthYear; // переменной

}

Petrov={"Петров П.П.\0", "96ВП301\0",1978};

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

Примеры:

struct MyStruct

{

int i; // 2 байта

char str [20]; // 20 байт

float f; // 4 байта }

S; // sizeof (MyStruct) равно 26 байт

union MyUnion

{

int i; // 2 байта

char str [20]; // 20 байт - максимум

float f; // 4 байта

}

U; // sizeof (MyUnion) равно 20 байт

Элементы структуры или объединения могут быть определены как битовые поля шириной от 1 до 16 бит, знаковые или беззнаковые. Общая форма описания битового поля:

Имя типа имя поля : ширина; Допустимые типы битовых полей - int, char, unsigned int, unsigned char.

Ширина битового поля - целое число от 0 до 16. Идентификатор поля может быть пропущен, в этом случае заданное число бит размещается в памяти, но будет недоступно. Для знаковых полей старший левый бит интерпретируется как знак. Над элементами битовых полей не может быть выполнена операция взятия адреса &.

Пример:

struct Date

{

unsigned int Day:5;

unsigned int Mon:4;

unsigned int Year:7;

}

Start ={1,9,98};

Схема размещения полей в памяти для приведенного примера соответствует рисунку 1.

Year

Mon

Day

15 114 113 112 111 110 |9~

8 |7 |6 |5 '

4 |3 |2 |1 |0

Рисунок 1

Указатели на структуры и объединения

Для доступа к элементам структурных переменных или объединений через указатель используется специальная операция ->.

Пример:

struct Student Gruppa [25];

struct Student *Ptr= &(Gruppa[5]);

printf ("\n ФИО: %-30s \n Шифр: %-9s \n Год рождения:%4d", Ptr->FIO, Ptr->ID_Cod, Ptr->BirthYear);

Обращение Ptr->FIO есть синоним (*Ptr).FIO.

Передача структур и объединений в функции и их возврат из функций

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

В современных реализациях языка Си допустимо передавать структуру в качестве аргумента функции и возвращать ее.

Пример:

struct s func (struct s arg);

Спецификатор typedef

Спецификатор typedef позволяет задавать символические имена типов данных. Описание символических имен похоже на описание переменных: сначала указывается тип, а затем его метка.

Typedef напоминает директиву препроцессора #define, но имеются следующие отличия:

typedef дает символические имена только типам данных;

typedef выполняется компилятором, а не препроцессором.

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

Примеры использования typedef:

typedef float * FPTR;

typedef unsigned char BYTE;

typedef struct

{

int x;

int y;

}

POINT;

Динамическое распределение памяти. Функции calloc, malloc, free, heapcheck

Функции данной группы предназначены для динамического распределения памяти, освобождения памяти и контроля за состоянием кучи. Описания функций находятся в файлах <stdio.h> и <alloc.h>.

Функции calloc и malloc предназначены для выделения участков динамической памяти. Отличие этих функций состоит в том, что malloc имеет один аргумент -общее количество требуемой памяти в байтах, в то время как для calloc необходимо указать размер элемента массива в байтах и количество элементов массива. В случае успеха данные функции возвращают указатели на выделенный участок памяти, в случае неуспеха - значение NULL.

Функция free производит освобождение участка динамической памяти с заданным адресом, предварительно выделенного функциями malloc или calloc.

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

Перечисленные функции применяются для работы с участками памяти, не превышающими 64 K.