Для иллюстрации использования структур и массивов структур рассмотрим простую программу инвентаризации, использующую массив структур для хранения инвентарной информации. Функции данной программы работают со структурами и их членами различными способами. В данном примере сохраняемая информация содержит:
- имя элемента
- стоимость
- количество имеющегося товара
Можно определить базовую структуру данных inv для хранения информации:
#define МАХ 100
struct inv {
char item[30];
float cost;
int on_hand;
} inv_info [MAX];
В структуре inv для хранения имени элемента используется item. Член cost содержит стоимость элемента, a on_hand содержит число имеющихся элементов. Первая необходимая для программы функция - это main():
int main(void)
{
char choice;
init_list(); /* инициализация массива структур */
for (;;) {
choice = menu_select();
switch (choice) {
case 1: enter();
break;
case 2: del();
break;
case 3: list();
break;
case 4: return 0;
}
}
}
В main() вызов init_list() подготавливает для использования массив структур путем помещения нулевых символов в первый байт каждого поля item. Программа предполагает, что структура не используется, если поле item пустое, функция init_list() определяется следующим образом:
/* Инициализация массива структур. */
void init_list(void)
{
register int t;
for(t=0; t<MAX; ++t) inv_inf о [ t ].item[0] = '\ 0';
}
функция menu_select() выводит меню и возвращает выбор пользователя:
/* Ввод выбора пользователя. */
int menu_select(void)
{
char s[80];
int c;
printf ("\n");
printf("1. Enter an item\n");
printf ("2. Remove an item\n");
printf ("3. List the inventory\n");
printf ("4. Quit\n");
do {
printf ("\nEnter your choice: ");
gets (s);
с = atoi(s);
} while (c<0 || c>4);
return c;
}
Функция enter() подсказывает пользователю при вводе и размещает вводимую информацию в следующей пустой структуре. Если массив заполнен, выводится сообщение «List Full». Функция find_tiree() ищет в массиве структур неиспользуемый элемент.
/* Ввод инвентарной информации. */
void enter(void)
{
int slot;
slot = find_free();
if (slot == -1) {
printf("\nList Full");
return;
}
printf("Enter item: ");
gets(inv_info[slot].item);
printf("Enter cost: ");
scanf{"%f", &inv_info[slot].cost);
printf("Enter number on hand: ");
scanf("%d%*c",&inv_info[slot].on_hand);
}
/* возврат индекса первого неиспользуемого участка массива или -1, если свободных участков нет */
int find_free(void)
register int t;
tox(t=0; inv_info[t].item[0] && t<MAX; ++t);
if(t == MAX) return -1; /* no slots free */
return t;
}
Следует обратить внимание, что find_free() возвращает -1, если все структуры массива используются. Это «безопасное» число, поскольку элемент массива inv_info не может быть равен -1.
Функция del() требует, чтобы пользователь определил число элементов, которые необходимо удалить. Затем функция помещает нулевой символ в начало поля item.
/* Удаление элемента из списка. */
void del(void)
{
register int slot;
char s[80];
printf ("enter record #: ");
gets (s); ' 1;
slot = atoi(s);
if (slot >=0 && slot < MAX) inv_info [slot].item [0] = '\0';
}
Последняя функция программы - это list(). Она выводит весь инвентарный список на экран.
/* Вывод списка на экран. */
void list (void)
{
register int t;
for (t=0; t<MAX; ++t) {
if(inv_info[t].item[0]) {
printf("Item: %s\n", inv_info[t].item);
printf("Cost: %f\n", inv_info[t].cost);
printf ("On hand: %d\n\n", inv_info[t].n_hand);
}
}
printf("\n\n");
}
Ниже приведено полное описание программы инвентаризации. Если нет уверенности в понимании работы данных структур, следует ввести данную программу в компьютер и изучить ее выполнение, внося изменения и наблюдая за эффектами.
/* простая программа инвентаризации, использующая массивы структур */
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
struct inv {
char Item[30];
float cost;
int on hand;
} inv_info[MAX];
void init_list(void), list(void), del(void);
void enter(void);
int menu_select(void), find_free(void);
int main(void)
{
char choice;
init list(); /* инициализация массива структур */
for(;;) {
choice = menu_select();
switch(choice) {
case 1: enter();
break;
case 2: del();
break;
case 3: list();
break;
case 4: return 0;
}
}
}
/* инициализация массива структур */
void init_list (void)
{
register int t;
for(t=0; t<MAX; ++t) inv_info[t].item[0] = '\0';
}
/* ввод выбора пользователя */
int menu_select(void)
{
char s[80];
int c;
printf("\n");
printf("1. Enter an item\n");
printf("2. Remove an item\n");
printf("3. List the inventory\n");
printf("4. Quit\n");
do {
printf("\nEnter your choice: ");
gets(s);
с = atoi(s);
} while (c<0 || c>4);
return c;
}
/* ввод инвентарной информации */
void enter(void)
{
int slot;
slot = find_free();
if ( slot == -1) {
printf("\nList Full");
return;
}
printf("Enter item: ");
gets (inv_info[slot].item);
printf("Enter cost: ");
scanf("%f", &inv_info[slot].cost);
printf("Enter number on hand: ");
scanf ("%d%*c", &inv_infо[slot].on_hand);
}
/* возврат индекса первого неиспользуемого участка массива или -1 если свободных участков нет */
int find_free(void)
{
register int t;
for (t=0; inv_info [t].item[0] && t<MAX; ++t);
if (t == MAX) return -1; /* no slots free */
return t;
}
/* удаление элемента из списка */
void del(void)
{
register int slot;
char s[80];
printf("enter record #: ");
gets(s);
slot = atoi (s);
if (slot >= 0 && slot < MAX) inv_info[slot].item[0] = '\0';
}
/* вывод списка на экран */
void list(void)
{
register int t;
for(t=0; t<MAX; ++t) {
if(inv_info[t].item[0]) {
printf("Item: %s\n", inv_info[t].item);
printf("Cost: %f\n", inv_info[t].cost);
printf("On hand: %d\n\n", inv_info[t].on_hand);
}
}
printf ("\n\n");
}