
- •Общие методические указания по выполнению лабораторных работ
- •Работа со структурами данных (struct)
- •Описание структур и структурных переменных
- •Вложенные структуры
- •Обращение к полям структуры
- •Например, для переменных, описанных шаблоном
- •Массивы структурных переменных
- •Объявление типов в языке Си
- •Введите оценки ( 2 целых числа от 3 до 5 ): 5 5
- •Использование структур в функциях
- •Использование глобальных данных
- •Обработка вложенных структур
- •Толстой л.Н. Война и мир 1995 6 Структуры и поразрядные операции
- •Поразрядные операции
- •Сдвиговые поразрядные операции
- •Операнд сдвиг число_битов
- •Структуры с битовыми полями
- •Работа с объединениями (union)
- •Работа с перечислениями (enum)
- •Работа с файлами Понятие файла и потока ввода-вывода данных в компьютере
- •Открытие и закрытие файла
- •Потоки стандартного ввода-вывода
- •Повторное открытие файла
- •Позиционирование указателя записи-чтения
- •Int fseek (указатель_потока, (long) смещение, начало_отсчета),
- •Начало_отсчета может принимать следующие значения:
- •Функции файлового ввода-вывода
- •Посимвольный ввод-вывод
- •Вывод символов из файла:
- •Построчный ввод-вывод Пусть описан символьный массив
- •Форматированный ввод-вывод данных
- •Блоковый ввод-вывод
- •Работа с динамическими структурами данных Динамическое распределение памяти
- •Очередь
- •Рекурсивные функции
- •Деревья
Массивы структурных переменных
Такие массивы описываются по заданному шаблону как обычный массив структур или массив указателей на структуры:
struct student { char name [30]; float sb;
} group [20], /* массив структур */
*pgroup [20], /* массив указателей на структуры */
*pgr=group; /* указатель на массив group */
Доступ к элементам массива может выполняться либо с использованием индекса, либо через указатель-константу (имя массива), либо через указатель-переменную, инициализированную адресом первого элемента массива (именем массива):
group[i].sb=0; /* доступ с использованием индексного выражения */
(*(group+i)).sb=0; /* доступ с использованием адресного выражения */
(group+i)->sb=0; /* использование указателя-константы */
(pgr+i)->sb=0; /* использование указателя-переменной */
pgroup [i] = group+i; /* запись адреса структуры в массив указателей */
Продвижение указателя операцией ++ или – – (например, pgr++; pgr– –;) увеличивает или уменьшает его на размер структуры, например, sizeof (struct student), то есть устанавливает на следующий или предыдущий элемент массива. Это удобно при последовательном доступе к элементам массива в цикле.
Объявление типов в языке Си
Для упрощения описания структурных переменных и данных других конструируемых типов, а также для задания более коротких имен существующим типам, используется оператор описания типа вида
typedef описание_типа имя_типа; /* символ конца ‘;’ */,
где typedef (описание типа) – ключевое слово;
имя_типа – идентификатор, возможно в сочетании с модификаторами (* – указатель, [ ] – массив, ( ) – функция), который становиться синонимом описания_типа и может использоваться как спецификатор типа при объявлении или описании переменных.
Пример. Объявление и использование имен новых типов.
typedef unsigned int UNINT; /* сокращенное имя стандартного типа */
typedef struct { /* описание шаблона структуры */
char name [30];
DATA born; /* использование описанного ниже типа DATA */
} student; /* имя нового типа */
typedef struct { /* описание шаблона структуры */
UNINT day; /* использование имени типа UNINT */
UNINT month; UNINT year; /* поля структуры */
} DATA; /* имя нового типа */
Описание структурных переменных с помощью нового типа структуры:
STUDENT group[20], stud;
Замечание. В примере показано, что при использовании синонимов типов структур (а также объединений и перечислений) не требуется задавать ключевые слова struct (union, enum). Введено короткое имя UNINT для длинного спецификатора типа. Синоним типа DATA использован раньше, чем описан его шаблон структуры, поскольку описания типов видимы в пределах файла.
Рассмотрим возможности программных средств для обработки структур данных на примерах решения одной задачи разными способами.
Задача. Ввести исходные данные об успеваемости в сессию студентов группы в список в виде массива структур. Отсортировать список студентов по убыванию среднего балла в сессию и вывести упорядоченный список.
Пример1. Выполнить ввод данных и обработку массива структур без использования указателей.
Программа:
#include<stdio.h>
#include<conio.h>
#define kstud 3 /* максимальное количество студентов в группе */
#define kball 5 /* максимальное количество баллов в сессию */
void main()
{ struct STUDENT{ char name [31]; /* фамилия И.О. студента */
int ball [kball]; /* оценки в сессию */
float sb; /* средний балл */
} st, gr[kstud]; /* структурная переменная и массив */
int i, j, k, kst, kb; /* рабочие переменные */
float sum; /* сумматор */
clrscr(); /* очистка экрана */
printf (”Введите количество студентов в группе: ”);
scanf (”%d”, &kst);
printf (”Введите количество баллов в сессию: ”);
scanf (”%d”, &kb);
printf (”Ввод данных группы из %d студентов:\n”, kst );
for (i=0; i< kst; i++) /* цикл по студентам */
{ printf (”%2d. ”, i+1); /* ввод номера студента */
fflush (stdin); /* очистка буфера ввода */
gets (gr[i].name); /* ввод фамилии И. О. */
printf (”Введите оценки (%d целых числа от 3 до 5): ”, kb);
for (j=0; j<kb; j++) /* цикл по баллам */
scanf (”%d”, &gr[i].ball[j]); /* ввод оценок */
} /* конец ввода исходных данных */
for (i=0; i< kst; i++) /* цикл по студентам */
{ sum = 0; /* очистка сумматора */
for (j=0; j<kb; j++) /* цикл по баллам */
sum += gr[i].ball[j]; /* вычисление суммы оценок */
gr[i].sb = sum / kb; /* вычисление среднего балла */
}
puts (”Сортировка студентов по среднему балу.”);
for (i=0; i < kst -1; i++) /* цикл по студентам */
{ k=i; /* начальное значение индекса k */
for (j=i+1; j<kst; j++) /* цикл поиска max среднего балла */
if (gr[j].sb > gr[k].sb) k=j; /* индекс max среднего балла */
if ( k != i) /* если индекс k изменился, то */
{ st = gr[i]; /* перестановка данных студентов */
gr[i] = gr[k]; /* в массиве структур через */
gr[k] = st; /* структурную переменную st */
}
}
puts(”Студент: Средний балл:”);
for (i=0; i < kst; i++) /* цикл по студентам */
printf(” %d. %-20s %6.3f\n ”, i+1, gr[i].name, gr[i].sb);
getch(); /* задержка экрана результатов */
} /* конец программы */
Результаты программы:
Введите количество студентов в группе: 3
Введите количество баллов с сессию: 2
Ввод данных группы из 3 студентов:
Иванов А. И.
Введите оценки ( 2 целых числа от 3 до 5 ): 4 5
2. Петров Т. Б.
Введите оценки ( 2 целых числа от 3 до 5 ): 4 3
Сидоров Д. С.