Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология Образование Политология Производство Психология Стандартизация Технологии |
Общий формат объявления структуры выглядит так.
struct имя_типа_структуры { тип имя_элемента1; тип имя_элемента2; тип имя_элемента3; . . . тип имя_элементаN; } структурные_переменные; Доступ к членам структуры К отдельным членам структуры доступ осуществляется с помощью оператора " точка" . Например, при выполнении следующего кода значение 10.39 будет присвоено полю cost структурной переменной inv_var, которая была объявлена выше. inv_var.cost = 10.39; Чтобы обратиться к члену структуры, нужно перед его именем поставить имя структурной переменной и оператор " точка" . Так осуществляется доступ ко всем элементам структуры. Общий формат доступа записывается так. имя_структурной_переменной.имя_члена Оператор " точка" (.) позволяет получить доступ к любому члену любой структуры. Следовательно, чтобы вывести значение поля cost на экран, необходимо выполнить следующую инструкцию. cout < < inv_var.cost; Аналогичным способом можно использовать символьный массив inv_var.item в вызове функции gets(). gets(inv_var.item); Здесь функции gets() будет передан символьный указатель на начало области памяти, отведенной элементу item. Если вам нужно получить доступ к отдельным элементам массива inv_var.item, используйте индексацию. Например, с помощью этого кода можно посимвольно вывести на экран содержимое массива inv_var.item. int t; for(t=0; inv_var.itern[t]; t++) cout < < inv_var.item[t]; Массивы структур Структуры могут быть элементами массивов. И в самом деле, массивы структур используются довольно часто. Чтобы объявить массив структур, необходимо сначала определить структуру, а затем объявить массив элементов этого структурного типа. Например, чтобы объявить 100-элементный массив структур типа inv_type (который определен выше), достаточно записать следующее. inv_type invtry[100]; Чтобы получить доступ к конкретной структуре в массиве структур, необходимо индексировать имя структуры. Например, чтобы отобразить на экране содержимое члена on_hand третьей структуры, используйте такую инструкцию. cout < < invtry[2].on_hand; Подобно всем переменным массивов, у массивов структур индексирование начинается с нуля. Простой пример инвентаризации склада Чтобы продемонстрировать применение структур, разработаем простую программу управления складом, в которой для хранения информации о товарах, размещенных на складе компании, используется массив структур типа inv_type. Различные функции, определенные в этой программе, взаимодействуют со структурой и ее элементами по-разному. Инвентарная ведомость будет храниться в структурах типа inv_type, организованных в массиве invtry. const int SIZE = 100; struct inv_type { char item[40]; // наименование товара double cost; // стоимость double retail; // розничная цена int on_hand; // имеющееся в наличии количество int lead_time; // число дней до пополнения запасов } invtry[SIZE]; Размер массива выбран произвольно. При желании его можно легко изменить. Обратите внимание на то, что размерность массива задана с использованием const-переменной. А поскольку размер массива во всей программе используется несколько раз, применение const-переменной для этой цели весьма оправданно. Чтобы изменить размер массива, достаточно изменить значение константной переменной SIZE, а затем перекомпилировать программу. Использование const-переменной для определения " магического числа" , которое часто употребляется в программе, — обычная практика в профессиональном С++-коде. Разрабатываемая программа должна обеспечить выполнение следующих действий: ■ ввод информации о товарах, хранимых на складе; ■ отображение инвентарной ведомости; ■ модификация заданного элемента. Прежде всего напишем функцию main(), которая должна иметь примерно такой вид. Int main() { char choice; init_list(); for(;; ) { choice = menu(); switch(choice) { case 'e': enter(); break; case 'd': display(); break; case 'u': update(); break; case 'q': return 0; } } } Функция main() начинается с вызова функции init_list(), которая инициализирует массив структур. Затем организован цикл, который отображает меню и обрабатывает команду, выбранную пользователем. Приведем код функции init_list(). // Инициализация массива структур. void init_list() { int t; // Имя нулевой длины означает пустое имя. for(t=0; t< SIZE; t++) *invtry[t].item = '0'; } Функция init_list() подготавливает массив структур для использования, помещая в первый байт поля item нулевой символ. Предполагается, что если поле item пустое, то структура, в которой оно содержится, попросту не используется. Функция menu_select() отображает команды меню и принимает вариант, выбранный пользователем. // Получение команды меню, выбранной пользователем. Int menu() { char ch; cout < < ''; do { cout < < " (E)nter"; // Ввести новый элемент. cout < < " (D)isplay"; // Отобразить всю ведомость. cout < < " (U)pdate"; // Изменить элемент. cout < < " (Q)uit"; // Выйти из программы. cout < < " Выберите команду: "; cin > > ch; }while(! strchr(" eduq", tolower(ch))); return tolower(ch); } Пользователь выбирает из предложенного меню команду, вводя нужную букву. Например, чтобы отобразить всю инвентарную ведомость, нажмите букву " D" . Функция menu() вызывает библиотечную функцию C++ strchr(), которая имеет такой прототип. char *strchr(const char *str, int ch); Эта функция просматривает строку, адресуемую указателем str, на предмет вхождения в нее символа, который хранится в младшем байте переменной ch. Если такой символ обнаружится, функция возвратит указатель на него. И в этом случае значение, возвращаемое функцией, по определению будет истинным. Но если совпадения символов не произойдет, функция возвратит нулевой указатель, который по определению представляет собой значение ЛОЖЬ. Так здесь организована проверка того, являются ли значения, вводимые пользователем, допустимыми командами меню. Функция enter() предваряет вызов функции input(), которая " подсказывает" пользователю порядок ввода данных и принимает их. Рассмотрим код обеих функций. // Ввод элементов в инвентарную ведомость. Void enter() { int i; // Находим первую свободную структуру. for(i=0; i< SIZE; i++) if(! *invtry[i].item) break; // Если массив полон, значение i будет равно SIZE. if(i==SIZE) { cout < < " Список полон."; return; } input (i); } // Ввод информации. Void input(int i) { cout < < " Товар: "; cin > > invtry[i].item; cout < < " Стоимость: "; cin > > invtry[i].cost; cout < < " Розничная цена: "; cin > > invtry[i].retail; cout < < " В наличии: "; cin > > invtry[i].on_hand; cout < < " Время до пополнения запасов (в днях): "; cin > > invtry[i].lead_time; } Функция enter() сначала находит пустую структуру. Для этого проверяется поле item каждого (по очереди) элемента массива invtry, начиная с первого. Если поле item оказывается пустым, то предполагается, что структура, к которой оно относится, еще ничем не занята. Если не отыщется ни одной свободной структуры при проверке всего массива структур, управляющая переменная цикла i станет равной его размеру. Это говорит о том, что массив полон, и в него уже нельзя ничего добавить. Если же в массиве найдется свободный элемент, будет вызвана функция input() для получения информации о товаре, вводимой пользователем. Если вас интересует, почему код ввода данных о новом товаре не является частью функции enter(), то ответ таков: функция input() используется также и функцией update(), о которой речь впереди. Поскольку информация о товарах на складе может меняться, программа ведения инвентарной ведомости должна позволять вносить изменения в ее отдельные элементы. Это реализуется путем вызова функции update(). // Модификация существующего элемента. Void update() { int i; char name[80]; cout < < " Введите наименование товара: "; cin > > name; for(i=0; i< SIZE; i++) if(! strcmp(name, invtry[i].item)) break; if(i==SIZE) { cout < < " Товар не найден."; return; } cout < < " Введите новую информацию."; input(i); } Эта функция предлагает пользователю ввести наименование товара, информацию о котором ему нужно изменить. Затем она просматривает весь список существующих элементов, и если указанный товар в нем имеется, то вызывается функция input(), которая обеспечивает прием от пользователя новой информации. Нам осталось рассмотреть функцию display(). Она выводит на экран инвентарную ведомость в полном объеме. Код функции display() выглядит так. // Отображение на экране инвентарной ведомости. Void display() { int t; for(t=0; t< SIZE; t++ ) { if(*invtry[t].item) { cout < < invtry[t].item < < ''; cout < < " Стоимость: $" < < invtry[t].cost; cout < < " розницу: $"; cout < < invtry[t].retail < < ''; cout < < " В наличии: " < < invtry[t].on_hand; cout < < " До пополнения осталось: "; cout < < invtry[t].lead_time < < " дней"; } } } Ниже приведена законченная программа ведения инвентарной ведомости. Вам следует ввести эту программу в свой компьютер и исследовать ее работу. Внесите некоторые изменения и понаблюдайте, как они отразятся на ее выполнении. Попробуйте также расширить программу, добавив функции поиска в списке заданного товара, удаления уже ненужного элемента или полной очистки инвентарной ведомости. /* Простая программа ведения инвентарной ведомости, в которой используется массив структур. */ #include < iostream> #include < cctype> #include < cstring> #include < cstdlib> using namespace std; const int SIZE = 100; struct inv_type { char item[40]; // наименование товара double cost; // стоимость double retail; // розничная цена int on_hand; // имеющееся в наличии количество int lead_time; // число дней до пополнения запасов } invtry[SIZE]; void enter(), init_list(), display(); void update(), input(int i); int menu(); Int main() { char choice; init_list(); fоr (;; ) { choice = menu(); switch(choice) { case 'e': enter(); break; case 'd': display(); break; case 'u': update(); break; case 'q': return 0; } } } // Инициализация массива структур. void init_list() { int t; // Имя нулевой длины означает пустое имя. for(t=0; t< SIZE; t++ ) *invtry[t].item = '0'; } //Получение команды меню, выбранной пользователем. Int menu() { char ch; cout < < ''; do { cout < < " (E)nter"; // Ввести новый элемент. cout < < " (D)isplay"; // Отобразить всю ведомость. cout < < " (U) pdate"; // Изменить элемент. cout < < " (Q) uit"; // Выйти из программы. cout < < " Выберите команду: "; cin > > ch; }while(! strchr(" eduq", tolower(ch))); return tolower(ch); } //Ввод элементов в инвентарную ведомость. Void enter() { int i; // Находим первую свободную структуру. for(i=0; i< SIZE; i++) if(! *invtry[i].item) break; // Если массив полон, значение i будет равно SIZE. if(i==SIZE) { cout < < " Список полон."; return; } input(i); } // Ввод информации. Void input(int i) { cout < < " Товар: "; cin > > invtry[i].item; cout < < " Стоимость: "; cin > > invtry[i].cost; cout < < " Розничная цена: "; cin > > invtry[i].retail; cout < < " В наличии: "; cin > > invtry[i].on_hand; cout < < " Время до пополнения запасов (в днях): "; cin > > invtry[i].lead_time; } // Модификация существующего элемента. Void update() { int i; char name[80]; cout < < " Введите наименование товара: "; cin > > name; for(i=0; i< SIZE; i++) if(! strcmp(name, invtry[i].item)) break; if(i==SIZE) { cout < < " Товар не найден."; return; } cout < < " Введите новую информацию."; input (i); } // Отображение на экране инвентарной ведомости. Void display() { int t; for(t=0; t< SIZE; t++) { if(*invtry[t].item) { cout < < invtry[t].item < < ''; cout < < " Стоимость: $" < < invtry[t].cost; cout < < " розницу: $"; cout < < invtry[t].retail < < ''; cout < < " В наличии: " < < invtry[t].on_hand; cout < < " До пополнения осталось: "; cout < < invtry[t].lead_time < < " дней"; } } } Передача структур функциям При передаче функции структуры в качестве аргумента используется механизм передачи параметров по значению. Это означает, что любые изменения, внесенные в содержимое структуры в теле функции, которой она передана, не влияют на структуру, используемую в качестве аргумента. Однако следует иметь в виду, что передача больших структур требует значительных затрат системных ресурсов. (Как правило, чем больше данных передается функции, тем больше расходуется системных ресурсов.) Используя структуру в качестве параметра, помните, что тип аргумента должен соответствовать типу параметра. Например, в следующей программе сначала объявляется структура sample, а затем функция f1() принимает параметр типа sample. // Передача функции структуры в качестве аргумента. #include < iostream> using namespace std; // Определяем тип структуры. struct sample { int a; char ch; }; void f1(sample parm); Int main() { struct sample arg; // Объявляем переменную arg типа sample. arg.a = 1000; arg.ch = 'x'; f1(arg); return 0; } Void f1(sample parm) { cout < < parm.a < < " " < < parm.ch < < " "; } Здесь как аргумент arg в функции main(), так и параметр parm в функции f1() имеют одинаковый тип. Поэтому аргумент arg можно передать функции f1(). Если бы типы этих структур были различны, при компиляции программы было бы выдано сообщение об ошибке. Присваивание структур Содержимое одной структуры можно присвоить другой, если обе эти структуры имеют одинаковый тип. Например, следующая программа присваивает значение структурной переменной svar1 переменной svar2. // Демонстрация присваивания значений структур. #include < iostream> using namespace std; struct stype { int a, b; }; Int main() { stype svar1, svar2; svar1.a = svar1.b = 10; svar2.a = svar2.b = 20; cout < < " Структуры до присваивания."; cout < < " svar1: " < < svar1.a < < ' ' < < svar1.b; cout < < ''; cout < < " svar2: " < < svar2.a < < ' ' < < svar2.b; cout < < " "; svar2 = svar1; // присваивание структур cout < < " Структуры после присваивания."; cout < < " svar1: " < < svar1.a < < ' ' < < svar1.b; cout < < ''; cout < < " svar2: " < < svar2.a < < ' ' < < svar2.b; return 0; } Популярное:
|
Последнее изменение этой страницы: 2016-03-17; Просмотров: 1212; Нарушение авторского права страницы