Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

Массивы структур. Как и обычные переменные, структуры могут быть элементами массивов

Читайте также:
  1. I. Структура компьютерной презентации
  2. I.2. Структура атмосферы. Основные источники ее загрязнения. Выбросы металлургического производства
  3. II. Организационные структуры управления и тенденции в их развитии
  4. II. Проявления и структура недоразвития речи
  5. II. Требования к структуре основной общеобразовательной программы дошкольного образования
  6. III. Проблема сознания, социальной структуры и насилия
  7. III. Разработка новой организационной структуры «Дормаша».

Как и обычные переменные, структуры могут быть элементами массивов. В листинге 8.2 приведен существенно измененный и упрощенный вариант предыдущего программного кода, в котором используются массивы структур.

//Листинг 8.2 Массивы структур

// demoStruct2.cpp: Defines the entry point for the console application.

//

 

#include "stdafx.h"

#include <iostream>

#include <cstdio>

#include <cstring>

#include <cstdlib>

using namespace std;

#include <conio.h>

 

struct Marks

{

char name[80];

int phys;

int chem;

int maths;

};

 

int main()

{

const int n=3;

bool state;

char s [80];

Marks students[n];

 

for (int i=0;i<n;i++)

{

cout << ("Student name: ");

gets(students[i].name);

students[i].phys=3+rand()%3;

students[i].chem=3+rand()%3;

students[i].maths=3+rand()%3;

}

 

do

{

cout<<"What is the student name? ";

gets (s);

if(!strcmp(s,"exit")) return 0;

state=true;

for(int i=0;i<n;i ++)

{

if(!strcmp(students[i].name,s))

{

state=false;

cout<<"Physiscs: "<<students [i].phys<<endl;

cout<<"Chemistry: "<<students [ i ]. chem<<endl;

cout<<"Mathematics: "<<students [i].maths<<endl;

break;

}

}

if (state) cout<<"There is no student with such name\n";

}while(true);

getch();

}

 

Пример выполнения программы может выглядеть следующим образом (жирным шрифтом выделен текст, вводимый пользователем):

Student name: Sergei Ivanov

Student name: Igor Petrov

Student name: Ivan Sidorov

What is the student name? Sergei Ivanov

Physics: 5

Chemistry: 5

Mathematics: 4

What is the student name? Ivan Sidorov

Physics: 3

Chemistry: 3

Mathematics: 4

What is the student name? Igor Petrovski

There is no student with such name

What is the student name? Igor Petrov

Physics: 4

Chemistry: 5

Mathematics: 4

What is the student name? exit

В программе командой Marks students [n] определяется массив students переменных структуры Marks из n элементов (предварительно объявлена

целочисленная константа const int n=3). Заполнение элементов массива выполняется в рамках оператора цикла. Индексная переменная i пробегает значения от 0 до n - 1 включительно. Каждый раз выводится запрос на ввод имени учащегося и это имя командой gets (students [i]. name) записывается в поле name переменной структуры students [i] - элемента массива students. Оценки по трем предметам для каждого учащегося определяются как случайные числа командами students[i].phys=3+rand()%3, students[i].chem=3+rand()%3 и students[i].maths=3+rand () %3. К базовой оценке 3 прибавляется целое случайное число в диапазоне от 0 до 2 включительно (результат команды rand () %3 — остаток от деления случайного числа на 3).

Командой char s [80] объявляется символьный массив, в который будет выполняться считывание вводимого пользователем имени учащегося для отображения его оценок. Этот массив используется в операторе цикла do{... }while (true). Причем стоит обратить внимание, что в качестве проверяемого условия указано логическое значение true, что означает, что формально цикл бесконечный. Возможность выхода из этого цикла предусмотрена в самом цикле.

В начале цикла оператора командой cout << "What is the student name?" выводится запрос на ввод имени учащегося. Введенное пользователем имя с помощью команды gets (s) считывается и записывается в массив s. После того, как имя учащегося введено, выполняется условный оператор if (! strcmp (s, "exit")) return 0. Этой командой предусмотрена возможность не только выхода из оператора цикла, но и завершения работы программы: если пользователь в качестве имени exit, работа программы завершается (инструкция return 0).

Там же командой state=true логической переменной state (переменная используется для индикации того, найдено совпадение имен или нет) присваивается значение true. После этого посредством оператора цикла выполняется последовательный перебор элементов массива students и производится сравнивание значений строк, записанных в массив s и в поле - массив students [i].name. Для сравнения строк используется функция strcmp (). Напомним, что если строки совпадают, то в качестве значения функцией возвращается 0, поэтому в условном операторе указано условие! strcmp (students [i].name, s). Если условие истинно, командой state=false меняется состояние логической переменной state, после чего выводится информация об оценках соответствующего учащегося. В конце условного оператора размещена команда break для преждевременного выхода из оператора цикла - если совпадение найдено, продолжать поиск не имеет смысла.

Если совпадения нет (т.е, введенное пользователем имя не найдено при просмотре полей элементов массива students), переменная state имеет значение true. На этот случай предусмотрена команда if (state) cout << "There is no student with such name\n".

8.3. Передача структур аргументами функций

Структуры могут передаваться в качестве аргументов функциям. В этом случае в качестве типа аргумента функции указывается название структуры, переменная которой будет передана в функцию. Листинг 6.3 содержит пример такой ситуации.

// demoStruct3.cpp: Defines the entry point for the console application.

//

// Листинг 8.3. Передача структур функции

 

#include "stdafx.h"

#include <iostream>

#include <cstdio>

#include <cstring>

#include <cstdlib>

using namespace std;

#include <conio.h>

 

struct Marks

{

char name[80];

int phys;

int chem;

int maths;

};

 

// Прототипы функций

void set_one(Marks &str);

void set_all(Marks *str,int m);

void get(Marks *str,int m);

 

int main()

{

const int n=3;

Marks students[n];

set_all(students, n);

get (students,n);

 

getch();

return 0;

}

 

// Определения (реализация) функций

void set_one(Marks &str)

{

cout << ("Student name: ");

gets(str.name);

str.phys=3+rand()%3;

str.chem=3+rand()%3;

str.maths=3+rand()%3;

}

 

void set_all(Marks *str,int m)

{

for(int i=0;i<m;i++) set_one(str[i]);

}

 

void get(Marks *str,int m)

{

bool state;

char s [80];

do

{

cout << "What is the student name? ";

gets (s);

if(!strcmp(s,"exit")) return;

state=true;

for(int i=0;i<m;i++)

{

if(!strcmp(str[i].name,s))

{

state=false;

cout<<"Physiscs: "<<str [i].phys<<endl;

cout<<"Chemistry: "<<str[i]. chem << endl;

cout<<"Mathematics: "<<str[i].maths<<endl;

break;

}

}

if (state) cout<<"There is no student with such name\n";

}while(true);

}

 

Функциональность программы не изменилась, однако основной программный код реализован в виде нескольких функций. Функция set_one() предназначена для заполнения полей структуры, переданной аргументом функции. Функция объявлена как void set_one (Marks &str). Аргумент функции указан как такой, что имеет тип Marks - тип объявленной ранее структуры. Кроме того, аргумент (переменная структуры) передается по ссылке, поэтому перед формальным именем str аргумента функции указывается оператор &. Причина передачи аргумента функции по ссылке, а не по значению (как обычно) состоит в том, что в результате выполнения функции необходимо изменить аргумент, переданный этой функции.

При выполнении кода функции выводится приглашение ввести имя учащегося и с помощью генерирования случайных чисел определяются оценки по трем предметам. Соответствующий код уже комментировался ранее.

В функции set_all () в рамках оператора цикла вызывается функция set_one () для заполнения элементов массива, указанного первым аргументом функции set_all(). Прототип этой функции имеет вид void set_all (Marks *str, int m). Первый аргумент - указатель на переменную структуры Marks. В данном случае это имя заполняемого массива. Второй аргумент - размер массива. Поскольку имя массива является ссылкой на его первый элемент, проблемы с передачей аргументов, как в предыдущем случае, не возникает - при заполнении массива будет изменяться именно тот массив, имя которого передано аргументом функции.

Функция get () с прототипом void get (Marks *str,int m) предназначена для считывания имени учащегося и вывода его оценок. Первый аргумент функции - массив, в котором выполняется поиск на предмет совпадения имен учащихся, второй аргумент - размер массива. По сравнению с соответствующим кодом в 0листинге 6.2, в данном случае использована инструкция if (! strcmp (s, "exit")) return для завершения работы функции (но не программы!). Непосредственно после инструкции return ничего не указывается, поскольку функция определена как такая, что не возвращает результат.

Как следствие использования описанных функций существенно упрощается код главного метода программы. Кроме инициализации константы, определяющей размер массива, и объявления массива с элементами-переменными структуры, основной код главного метода состоит из вызова двух функций (set_all () и get ()) и стандартной инструкции return 0.

8.4. Указатели на структуры

При объявлении указателя на структуру, как и в случае создания указателей на значения базовых типов, указывается тип структуры, а перед именем переменной-указателя ставится оператор *. Этот же оператор используется для получения доступа к переменной структуры по указателю на эту переменную. К0роме того, через указатель на структуру можно обращаться непосредственно к полям структуры, для чего используют оператор -> (стрелка, состоит из двух символов - и >). Например, если в программе определен указатель на переменную структуры, у которой есть поле, то доступ к этому полю можно получить с помощью инструкции указатель->поле. Пример использования указателей на структуры приведен в листинге 8.4.

// demoPtrStruct.cpp: Defines the entry point for the console application.

//

//Листинг 8.4. Указатели на структуру

 

#include "stdafx.h"

#include <iostream>

using namespace std;

#include <conio.h>

 

struct Numbers

{

int integer;

double real;

char symbol;

};

 

void show(Numbers x)

{

cout << "Integer: "<<x. integer << endl;

cout << "Real: "<<x. real << endl;

cout << "Symbol: " << x. symbol << endl<<endl;

}

 

int main()

{

Numbers a,b;

Numbers *p,*q;

p=&a;

q=&b;

p->integer=1;

p->real=2.5;

p->symbol= 'a';

(*q).integer=2;

(*q).real=5.1;

(*q).symbol='b';

show(a);

show(*q);

 

getch();

return 0;

}

 

В программе объявлена структура Numbers, имеющая три поля: типа int, типа double и типа char. Кроме этого, описана функция show (), аргументом которой является переменная структуры Numbers, а в результате выполнения функции выводятся значения всех полей аргумента.

В главном методе программы командой Numbers a, b объявляются переменные а и b структуры Numbers, а командой Numbers *р, *q объявлены указатели р и q на переменные структуры Numbers. Значения указателям (адреса) присваиваются командами р=&а и q=&b соответственно. При этом использован, как и в случае переменных базовых типов, оператор получения адреса &. Поля переменной а заполняются посредством команд p->integer=l, p->real=2. 5 и p->symbol='а'. В этом случае ссылка на поле реализуется через указатель р и оператор ->. Поля переменной b заполняются более консервативным способом. Для этого использова­ны команды (*q).integer=2, (*q). real=5.1 и (*q).symbol = 'b' соответственно. Здесь принято во внимание, что инструкция *q является ничем иным, как той переменной, на которую ссылается указатель q (т.е. переменная b). Аналогично при вызове функции show () ее аргументом можно указать как имя переменной (а или b) структуры Numbers, так и инструкцию вида или *q. В результате выполнения программы получим следующее:

Integer: 1

Real: 2.5

Symbol: a

Integer: 2

Real: 5.1

 


Дата добавления: 2015-08-03; просмотров: 41 | Нарушение авторских прав


<== предыдущая страница | следующая страница ==>
Лабораторная работа 8. Структуры и перечисления| Перечисления.

mybiblioteka.su - 2015-2024 год. (0.018 сек.)