- •Общие методические указания по выполнению лабораторных работ
- •Работа со структурами данных (struct)
- •Описание структур и структурных переменных
- •Вложенные структуры
- •Обращение к полям структуры
- •Например, для переменных, описанных шаблоном
- •Массивы структурных переменных
- •Объявление типов в языке Си
- •Введите оценки ( 2 целых числа от 3 до 5 ): 5 5
- •Использование структур в функциях
- •Использование глобальных данных
- •Обработка вложенных структур
- •Толстой л.Н. Война и мир 1995 6 Структуры и поразрядные операции
- •Поразрядные операции
- •Сдвиговые поразрядные операции
- •Операнд сдвиг число_битов
- •Структуры с битовыми полями
- •Работа с объединениями (union)
- •Работа с перечислениями (enum)
- •Работа с файлами Понятие файла и потока ввода-вывода данных в компьютере
- •Открытие и закрытие файла
- •Потоки стандартного ввода-вывода
- •Повторное открытие файла
- •Позиционирование указателя записи-чтения
- •Int fseek (указатель_потока, (long) смещение, начало_отсчета),
- •Начало_отсчета может принимать следующие значения:
- •Функции файлового ввода-вывода
- •Посимвольный ввод-вывод
- •Вывод символов из файла:
- •Построчный ввод-вывод Пусть описан символьный массив
- •Форматированный ввод-вывод данных
- •Блоковый ввод-вывод
- •Работа с динамическими структурами данных Динамическое распределение памяти
- •Очередь
- •Рекурсивные функции
- •Деревья
Вложенные структуры
Одним из полей структуры (внешней) может быть другая структура (внутренняя, вложенная). При этом возможны два способа описания шаблона.
Способ 1. Совместное описание структур (внешней и вложенной):
struct STUDENT { char name [30]; /* поле внешней структуры */
struct { int day ; /* шаблон вложенной структуры */
int month ;
int year ;
} born ; /* поле вложенной структуры */
} ;
Такое описание шаблонов выглядит громоздким.
Способ 2. Раздельное описание шаблонов:
struct DATA { int day; int month ; int year ; } ; /* шаблон структуры */
struct STUDENT { char name [30] ; /* поле внешней структуры */ struct DATA born ; /* поле вложенной структуры */ } ;
Глубина вложения структур неограниченна. Единственное ограничение – структура не может вкладываться сама в себя, то есть некорректно следующее описание:
struct STUDENT{ char name [30] ;
struct STUDENT my_own ; /* ОШИБКА !*/
};
Однако разрешается использовать в описываемом шаблоне поле-указатель (ссылку) на описываемую структуру, например, корректно такое описание:
struct STUDENT { char name [30] ;
struct STUDENT *my_own; /* допустимый указатель на собственную структуру */
};
Обращение к полям структуры
Для доступа к отдельным полям структурной переменной (не указателя) используется операция ‘’ (точка), формирующая ссылку на поле по схеме:
переменная поле
Например, для переменных, описанных шаблоном
struct STUDENT { char name [30] ; int ball [4] ; float sb ;
} st1, st2, gr [20] , *pst ;
допустимы следующие ссылки на поле структуры:
st1.name – указатель-константа на первый элемент массива name,
st2.ball [1] – ссылку на элемент с индексом 1 массива ball,
&st1.sb – адрес первого байта поля sb,
а также возможны ссылки вида gr [i].ball [4], gr [i+1].ball[k +1] и т.д.
Ссылка на поле структурной переменой обладает всеми свойствами обычной переменной. Корректны следующие выражения:
scanf (“%s”, st1.name) ; /* ввод Фамилии И.О. */
st.sb = 0 ; /* обнуление поля структуры */
gr [i].sb = st1.sb ; /* копирование поля структуры */
strcpy (gr [i].name, st1.name) ; /* вызов библиотечной функции */
Если структурные переменные описаны одним и тем же шаблоном, допускается операция присваивания таких структурных переменных, например,
st2 = st1; /* переменная st1 предварительно должна быть определена */
gr[i] = st1;
Операция присваивания структурных переменных приводит к пересылке (копированию) в памяти всех байтов одной переменной другой переменной.
Для доступа к полям структурной переменной через указатель используется операция ‘->’ (стрелка) по схеме:
указатель -> поле_структуры .
Ссылка на поле структурной переменной через указатель может участвовать в выражениях и операторах аналогично простой переменной, например,
pst1 = &st1; /* запись адреса структуры в указатель */
pst1 -> name = ”Иванов А.С. ”; /* запись литерала в поле name */
scanf (“%f”, &pst ->sb); /* запись числа в поле sb */
Вообще говоря, ссылка на поле структурной переменной через указатель – это синоним ссылки на данное поле через операцию ‘.’, например ссылка pst ->sb может быть записана, как (*pst).sb.
Ссылка на поле вложенной структуры формируется в виде цепочки имен переменной и полей структур по схеме (для не указателя):
переменная . имя_внешней_структуры . поле_внутренней_структуры
Например, для описания структур и структурных переменных:
struct data { int day; int month; int year;}; /* шаблон структуры */
struct STUDENT { char name[30];
struct DATA born; /* вложенная структура */
} st, *pst=&st ; /*переменная и указатель на структуру*/
возможны выражения:
st.born.day = 15;
st.born.month = 2;
st.born.year = 1979;
В общем случае доступ к полям вложенных структур подчиняется правилу : если в цепочке переменных и полей есть указатель, то доступ через него осуществляется по операции ‘->’, а если не указатель – по операции ‘.’, например,
pst->born.day = 20;.
Используя указатель на структурную переменную, можно создать ссылку на поле любого типа, в том числе, на указатель. При этом указатель на структуру можно использовать раньше объявления шаблона структуры, так компилятору не требуется информация о размере структуры, а размер самого указателя известен.
Например, предыдущее описание структур можно изменить:
struct STUDENT { struct DATA *pborn; /* struct DATA описана ниже */
char name [30];
};
struct DATA { int day; int month; int year; /* шаблон структуры */
} ;
struct student st, *pst=&st; /* переменная и указатель на структуру */
Доступ к полям в операторах с указателями:
pst -> pborn -> day = 25; /* запись числа в поле day */
scanf (“%d”, &pst -> pborn -> month); /* ввод числа в поле month */
