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

Массивы структурных переменных

Такие массивы описываются по заданному шаблону как обычный массив структур или массив указателей на структуры:

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 студентов:

  1. Иванов А. И.

Введите оценки ( 2 целых числа от 3 до 5 ): 4 5

2. Петров Т. Б.

Введите оценки ( 2 целых числа от 3 до 5 ): 4 3

  1. Сидоров Д. С.