Переменная структурного типа, указатель на структуру и ссылка на структуру могут быть формальными параметрами и возвращаемым значением функции.
Вызов функции с передачей по значению копии структурной переменной (или ее отдельных полей) приводит к дополнительным потерям времени на запись копии структурной переменной в стек, зато манипуляции с копией не влияют на исходную переменную. По той же причине возврат функцией структурной переменной возможен (return имя_структурной_переменной), но требует затрат на размещение в стеке возвращаемого значения и последующего его копирования из стека в переменную lvalue того же типа, что и возвращаемое значение функции.
Проанализируйте примеры:
void f3 (Book); //функция, получающая аргумент «структура типа Book»
void f4 (Book*); //функция, получающая аргумент //«указатель на структуру типа Book»
void f5 (Book&); //функция, получающая аргумент //«ссылка на структуру типа Book»
Book f(); //функция возвращает структуру типа Book
Book* f1(); //функция возвращает указатель на структуру типа Book
Book& f2(); //функция возвращает ссылку на структуру типа Book
Примеры работы со структурами
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*); //прототип функции сложения комплексных чисел
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 ("-");
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)) min= 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;
//двумерный массив с количеством дней в месяце для високосного и невисокосного года