
- •Структура простой программы на языке Си
- •Краткие теоретические сведения
- •Операции языка Си
- •Краткие теоретические сведения
- •Работа с текстовой информацией и с массивами
- •Краткие теоретические сведения
- •Функции в языке Си
- •Краткие теоретические сведения
- •Структуры, объединения, битовые поля
- •Краткие теоретические сведения
- •Управление файлами в языке Си
- •Краткие теоретические сведения
Структуры, объединения, битовые поля
составление структуры и объединения на языке Си
Краткие теоретические сведения
Структура представляет собой сборную конструкцию, включающую в себя данные различных типов, или поля. При употреблении термина "структура" следует различать:
структурный шаблон, или тип данных;
переменную структурного типа. Общее описание структурного шаблона:
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.