Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lekcija-18.pdf
Скачиваний:
17
Добавлен:
27.03.2016
Размер:
285.74 Кб
Скачать

char adres[60] //адрес владельца

};

Auto mers, volvo, alfa_r [5], *mazda, person_list [20]; //определение структурных переменных

mers.marka

доступ к полю «марка» автомобиля mers

mers

вся информация о владельце автомобиля mers

volvo.fio[0]

первая буква фамилии владельца автомобиля volvo

alfa_r [1].adres[0] первый символ адреса второго элемента массива владельцев alfa_r

person_list – информация о всех владельцах автомобилей (массив из двадцати наборов данных); person_list[i] – информация о владельце (i+1) –го автомобиля (i –ый элемент в наборе данных);

person_list[i].fio фамилия владельца (i+1) –го автомобиля; person_list[i].fio[j] j-ая буква в фамилии владельца (i+1) –го автомобиля

Расположение массива структур в памяти:

person_list

1-ый владелец:

 

2-ой владелец:

i-ый владелец:

...

 

20-ый владелец:

person_ list [0]

 

person_list [1]

 

person_list [i-1]

 

 

person_list [19]

 

 

 

 

 

 

 

 

 

nomer(4 байта)

 

nomer

nomer

 

ОООООООО

 

marka(20 байт)

 

marka

 

marka

 

 

ОООООООО

 

fio(40 байт)

 

 

 

 

fio

 

 

 

 

ОOОООООО

 

Adres Adre s

 

О

 

 

adres(60 байт)

 

adres

 

 

adres

 

 

 

 

ОООООООО

 

(всего 124 байтa)

 

 

 

 

 

 

 

 

 

ОООООООО

 

 

 

 

 

 

 

 

 

person_list [1]. fio

 

 

 

person_list [i-1].fio[j]

Массив структурных переменных можно описать и следующим образом: struct {char name[20];

char title[44]; int year; float price;

} books[25];

Тогда к полю year в i-ом элементе массива структур books можно обратиться следующим образом:

books[i].year=2007;

(*(books+i)).year=2007; (books+i)->year=2007;

Структура в качестве аргумента функции

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

Программирование – лекция 18 (лекции Стрикелевой Л.В.)

11

полей). Это приводит к дополнительным потерям времени на запись копии структурной переменной в стек, зато манипуляции с копией не влияют на исходную переменную. По той же причине возврат функцией структурной переменной возможен (return имя_структурной_переменной), но требует затрат на размещение в стеке возвращаемого значения и последующее его копирование из стека в переменную lvalue того же типа, что и возвращаемое значение функции.

Передать структуру в функцию можно также по ссылке и по указателю. Вернуть из функции можно структуру, указатель на структуру и ссылку на структуру.

Проанализируйте примеры:

void f3

(Book); //функция, получающая аргумент «структура типа Book»

void f4

(Book*); //функция, получающая аргумент

 

 

//«указатель на структуру типа Book»

void f5

(Book&); //функция, получающая аргумент

 

 

//«ссылка на структуру типа Book»

Book f();

//функция, возвращающая структуру типа Book

Book* f1();

//функция, возвращающая указатель на структуру типа Book

Book& f2(); //функция, возвращающая ссылку на структуру типа Book

При наличии спецификатора const функция не может изменять значения полей структуры.

Примеры работы со структурами

1. Определение структурного типа complex, представляющего комплексные числа, заданные в алгебраической форме, и определение структурных переменных x, y этого типа:

struct complex { float re;

//действительная часть числа

float im;

//мнимая часть числа

} x, y;

 

При этом x.re – доступ к полю действительной части комплексного числа x, y.im – доступ к полю мнимой части комплексного числа y,

Тогда функции для ввода, вывода, сложения комплексных чисел могут выглядеть

так:

struct complex { float re, im;};

//определение структурного типа

complex read ();

 

 

 

//прототип функции ввода комплексного числа

void

print (complex );

 

 

 

//прототип функции вывода комплексного числа на экран

void

add (complex, complex, complex*); //прототип функции сложения комплексных чисел

void

add1 (complex&, complex&, complex&);

int main()

 

 

 

 

{

 

 

 

 

//определение комплексных чисел

complex c1, c2, c3,c4;

 

 

 

c1 =

read();

 

 

 

//вызов функции ввода числа

c2 =

read();

 

 

 

 

add (c1, c2, &c3);

+

\t"

 

<< endl;

print(c1); cout << "\t

 

print (c2); cout << "

=

"

<< endl;

print (c3);

 

 

 

 

cout

<< endl;

 

 

 

 

Программирование – лекция 18 (лекции Стрикелевой Л.В.)

12

add1 (c1, c3, c4);

+

\t"

<< endl;

print(c1); cout << "\t

print (c3); cout << "

=

"

<< endl;

print (c4);

 

 

 

 

_getch();

 

 

 

 

return 0;

 

 

 

 

}

 

 

 

 

complex read()

 

 

 

{

 

 

 

 

complex c;

im:"<< endl;

 

 

cout << "re,

 

 

cin >> c.re

>> c.im;

 

 

 

return c;

 

 

 

 

}

 

 

 

 

void print (complex c)

{

cout << c.re << " + i*" << c.im << endl; return;

}

void add (complex c1, complex c2, complex *c3)

{

c3->re = c1.re +c2.re; //или (*c3).re = c1.re + c2.re; c3->im= c1.im +c2.im;

return;

}

void add1 (complex &c1, complex &c2, complex &c3)

{

c3.re = c1.re +c2.re; c3.im= c1.im +c2.im; return;

}

2. Определение структурного типа racion, представляющего понятие «рациональное число» и набор функций для сокращения, печати, деления рациональных чисел:

struct racion {int chis, znam;}; //определение структуры

void put (racion); //прототипы функций racion sokr (racion A);

void div (racion A, racion B, racion *C);

int main()

{

racion A, B, C;

puts ("racion1, racion2 : ?");

scanf ("%d%d%d%d", &A.chis, &A.znam, &B.chis, &B.znam); //ввод чисел div(A, B, &C); //вызов функции деления чисел printf (":"); put(A);

printf ("\tna\t"); put(B);

printf ("\n="); put(C);

//вывод результата

_getch();

 

return 0;

 

}

 

void put (racion A)

//функция выводит на экран «рациональное число»

{if (A.chis * A.znam <0) printf ("-");

Программирование – лекция 18 (лекции Стрикелевой Л.В.)

13

//функция выполняет сокращение «рационального числа» min= abs(A.znam);

A.chis = abs(A.chis); A.znam = abs(A.znam);

printf( "%d / %d", A.chis, A.znam);

}

void div (racion A, racion B, racion *C) //функция делит 2 рациональных числа

{

A=sokr(A); B= sokr (B);

C->chis = A.chis*B.znam;

C->znam = A.znam*B.chis; *C= sokr (*C);

}

racion sokr (racion A)

{

int i, min;

if (abs(A.chis) > abs(A.znam)) else min = abs(A.chis);

for (i=min; i>1; i--)

if(A.chis % i ==0 && A.znam % i ==0) break; A.chis /=i;

A.znam /=i; return A;

}

3. Рассмотрим программу, позволяющую по паре чисел (год, порядковый номер дня) получить название и число месяца.

struct date {

int d, m, y; //день, месяц, год char *mname; //название месяца

} md;

//двумерный массив с количеством дней в месяце для високосного и невисокосного года static int dofm[2][12]={{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},

{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};

//массив строк с названием месяца

static char *name[ ]={"janvar", "fevral", "mart", "aprel", "maj", "ijun", "ijul", "avgust", "sentjabr", "oktjabr", "nojabr", "decabr"};

void monthd(date *, int); //прототип функции пересчета

int main()

//порядковый номер дня года

{int yd;

"god, den ?";

cout <<

//заполнение поля структуры «год» и ввод переменной yd

cin >> md.y >> yd;

monthd (&md, yd);

//вызов функции и передача ей адреса структуры

md.mname = name[md.m];

//присваивание названия месяцу

cout <<

md.d <<" " << md.mname<< endl;

_getch();

 

return

0;

 

}

 

 

void monthd(date *md, int yd) {int i, v;

v=

(!(md->y%4) && (md->y%100) || !(md->y%400)); //проверка года на високосность

if

(yd > 365+v)

"neverno nomer"; exit(1);}

//проверка значения дня года

 

{cout <<

md->d = yd;

//подготовка начального значения для поля md->d

Программирование – лекция 18 (лекции Стрикелевой Л.В.)

14

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]