Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Konspekt_S__Chast_2.doc
Скачиваний:
31
Добавлен:
09.02.2015
Размер:
1 Mб
Скачать

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

Любая структурная переменная занимает в памяти определенное положение, характеризующееся конкретным адресом. Для работы с адресами структурных переменных (как и для простых переменных) можно использовать указатели. Указатели на структурные переменные определяются точно так же, как и для обычных переменных:

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 )

{

………..

}

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