Как и для обычных переменных язык Си поддерживает вызов функции как с передачей копии всей структурной переменной или отдельных ее полей (передача данных по значению), так и с передачей указателя (передача данных по адресу). Кроме того возможна обработка структурных переменных в функциях как внешних (глобальных) объектов, описанных вне функций. Сама функция может возвращать как структурную переменную, так и указатель на нее.
Вызов функции с передачей всей структурной переменной связан с дополнительными потерями времени и места на запись ее копии в стек. Зато при этом все изменения копии не влияют на исходную структуру. По той же причине возврат функцией структурной переменной требует затрат на размещение возвращаемого значения.
Пример: Рассмотрим выполнение программы с передачей и возвратом копии всей структурной переменной.
Функция example () использует полную копию структурной переменной first, помещаемую в стек. Для этого компилятор использует специальную процедуру. Возвращаемая структурная переменная также помещается в стек специальной процедурой. Затраты на эти операции увеличивают и объем программы, и время ее выполнения. Фактически функция example () вызывается для того, чтобы заполнить поля структурной переменной ret.
|
|
Программа:
#include <stdio.h>
#include <conio.h>
#include <string.h> /* для функции strcpy */
typedef struct { /* внешний шаблон видим всюду в файле */
char name [20]; /* автор */
char title [44]; /* название книги */
int year; /* год издания */
float price; /* цена */
} books; /* имя нового типа */
BOOKS example (BOOKS); /* прототип функции типа BOOKS */
void main() /* главная функция */
{ BOOKS first = {"Митчелл М., “Унесенные ветром ", 1991, 35.50},
ret; /*структурные переменные */
clrscr(); /* очистка экрана */
ret = example (first); /* передача копии структуры в функцию*/
puts ("Вывод переданной структурной переменной first:");
printf ("%-20s%-20s Год изд. %d. Цена -%5. 2f/n",
first. name, first.title, first.year, first. price);
puts ("Вывод возвращенной структурной переменной ret:");
printf ("%-20s%-20s Год изд. %d. Цена - %5. 2f\n",
ret. name, ret.title, ret.year, ret. price);
}
BOOKS example (BOOKS first) /* функция с передачей по значению */
{ strcpy (first.name, "Толстой Л.Н."); /* изменение автора */
strcpy (first.title, "Война и мир"); /* изменение названия книги */
first.year=1995; /* изменение года издания */
first.price=50.75; /* изменение цены */
return first; /* возврат структуры */
}
Результаты программы:
Вывод переданной структурной переменной first:
Митчелл М. Унесенные ветром Год изд. 1991. Цена - 35.50
Вывод возвращенной структурной переменной ret:
Толстой Л.Н. Война и мир Год изд. 1995. Цена - 50.75
Пример. Рассмотрим выполнение программы с передачей указателя на структурную переменную. В функцию example () передается указатель (адрес) на структурную переменную ret, тем самым все действия по изменению полей выполняются со структурной переменной ret.
|
|
Программа:
# include <stdio.h>
# include <conio.h>
# include <string.h> /* для функции strcpy */
typedef struct { /* внешний шаблон видим всюду в файле */
char name [20]; /* автор */
char title[44]; /* название книги */
int year; /* год издания */
float price; /* цена */
} BOOKS; /* имя нового типа */
void example (books*); /* прототип функции */
void main() /* главная функция */
{ BOOKS ret; /* структурная переменная */
clrscr(); /* очистка экрана */
example (&ret); /* передача адреса структуры в функцию */
puts (“Вывод возвращенной структурной переменной ret:”);
printf ("%-20s%-20s Год изд. %d. Цена - %5. 2f\n",
ret.name, ret.title, ret.year, ret. price);
}
void example (BOOKS *first) /* функция с передачей по адресу */
{ strcpy (first ->name, "Толстой Л.Н."); /* изменение автора */
strcpy (first->title, "Война и мир"); /* изменение названия книги */
first->year=1995; /* изменение года издания */
first->price=50.75; /* изменение цены */
}
Результаты программы:
Вывод возвращенной структурной переменной ret:
Толстой Л.Н. Война и мир Год изд. 1995. Цена - 50.75