Указатели на структуры
Любая структурная переменная занимает в памяти определенное положение, характеризующееся конкретным адресом. Для работы с адресами структурных переменных (как и для простых переменных) можно использовать указатели. Указатели на структурные переменные определяются точно так же, как и для обычных переменных:
t_Student * p_Stud; //Переменнаяp_Stud указатель на тип данных t_Student
p_Stud = & St1; //Переменнойp_Studприсвоен адрес переменной St1
Разыменование указателя (обращение к данным по адресу, хранящемуся в указателе) осуществляется обычным образом:
St2 = * p_Stud; //Данные по адресуp_Studскопированы в переменнуюSt2
Через указатели можно работать с отдельными полями структур. Для доступа к полю структуры через указатель используется оператор “стрелка”, а не “точка”:
grade = St1.Grade; //Доступ к полю Grade через обычную структурную переменную с помощью оператора “точка”
grade = p_Stud -> Grade; //Доступ к полю Grade через указатель на структурную переменную с помощью оператора “ стрелка”
p_Stud -> Grade = 3.75; //Полю Grade через указатель на структурную переменную присвоено новое значение
Структурные параметры функций
Структуры можно использовать в качестве параметров функций, как и обычные переменные. Для структур поддерживаются все три механизма передачи данных – по значению, через указатели и по ссылке.
Напишем три варианта функции, выводящей на экран данные студента.
Вариант 1. Передача данных по значению:
Void WriteStudent ( t_Student S )
{
cout << setw(14) << "Фамилия: " << S.Fam << endl;
cout << setw(14) << "Имя: " << S.Name << endl;
cout << setw(14) << "Год рождения: " << S.Year << endl;
If ( S.Sex )
cout << setw(14) << "Пол: " << "М\n";
Else
cout << setw(14) << "Пол: " << "Ж\n";
cout << setw(14) << "Средний балл: " << S.Grade << endl;
}
В этом варианте функции используется передача данных структуры по значению. Вызов этой функции WriteStudent ( St1 );сопровождается дополнительным расходом памяти для создания локальной переменной Sи дополнительными затратами времени на физическое копирование данных из аргумента St1в параметр S. Учитывая то, что объем структур может быть очень большим, то эти дополнительные затраты вычислительных ресурсов могут быть чрезмерными. Поэтому передачу структур в функции по значению необходимо использовать аккуратно.
Вариант 2. Передача данных через указатель:
void WriteStudent ( t_Student *S )
{
cout << setw(14) << "Фамилия: " << S -> Fam << endl;
cout << setw(14) << "Имя: " << S -> Name << endl;
cout << setw(14) << "Год рождения: " << S -> Year << endl;
if ( S -> Sex )
cout << setw(14) << "Пол: " << "М\n";
Else
cout << setw(14) << "Пол: " << "Ж\n";
cout << setw(14) << "Средний балл: " << S -> Grade << endl;
}
Вызов этой функции: WriteStudent ( &St1 );
В этом варианте фактической передачи данных студента в функцию не осуществляется. Дополнительные затраты памяти для создания локальной переменной небольшие – это адрес памяти (4 байта, независимо от размера самой структуры). Вызов такой функции будет осуществляться быстрее, а расход памяти существенно меньше, чем в первом варианте.
Здесь следует обратить внимание на то, что обращение к полям записи должно осуществляться с помощью оператора “стрелка”.
Вариант 3. Передача данных по ссылке:
void WriteStudent ( t_Student &S )
{
cout << setw(14) << "Фамилия: " << S.Fam << endl;
cout << setw(14) << "Имя: " << S.Name << endl;
cout << setw(14) << "Год рождения: " << S.Year << endl;
If ( S.Sex )
cout << setw(14) << "Пол: " << "М\n";
Else
cout << setw(14) << "Пол: " << "Ж\n";
cout << setw(14) << "Средний балл: " << S.Grade << endl;
}
Вызов этой функции: WriteStudent ( St1 );
По своей эффективности этот вариант эквивалентен варианту передачи данных через указатель. Однако, поскольку при передаче данных по ссылке все адресные преобразования берет на себя компилятор, существенно упрощается программирование действий со структурами.
Важным здесь является то, что при использовании ссылочных параметров структурных типов доступ к членам структуры осуществляется обычным способом – с помощью оператора “точка”.
Таким образом, передача структурных данных по адресу (через указатели или по ссылке) является предпочтительной. Недостатком этих способов является то, что случайные изменения значений полей структуры внутри функции отразятся на значении аргумента после окончания работы функции. Если необходимо предотвратить изменения переданных по адресу аргументов, можно при определении соответствующего параметра объявить его константой (использовать спецификатор const). Например, так:
void WriteStudent ( const t_Student &S )
{
………..
}
Дата добавления: 2019-02-07; просмотров: 298;