- •Конспект лекций Часть 2 Оглавление
- •Часть 2 1
- •8. Указатели
- •8.1. Указатели Понятие указателя
- •Работа с указателями
- •Арифметика указателей
- •Ошибки при работе с указателями
- •If (p1) // Если указатель не равен 0, то все в порядке
- •8.2. Указатели и массивы
- •9. Функции и структура программы
- •9.1. Создание и использование функций Процедурный подход к разработке программ
- •Определение функций в программе
- •Завершение работы функции (инструкция return)
- •If ( Ошибка )
- •Список параметров функций
- •Обращение к функциям в программе
- •Передача данных по значению
- •Передача данных с помощью указателей
- •Передача данных по ссылке
- •Перегружаемые функции
- •Параметры по умолчанию
- •Функции с переменным числом параметров
- •Рекурсивное использование функций
- •Передача функций в качестве параметров
- •Встраиваемые функции (inline - функции)
- •Прототипы функций
- •9.2. Структура программы. Глобальные и локальные данные (области видимости и время жизни) Структура программы
- •Глобальные и локальные данные
- •Классы памяти
- •Доступ к полям структур
- •Указатели на структуры
- •Структурные параметры функций
- •Битовые поля структур
- •10.2. Объединения Обычные объединения
- •Анонимные объединения
- •10.3. Перечисления
- •Void WriteColor (тип_Спектр c )
- •11. Организация ввода/вывода и работа с файлами
- •11.1. Потоки для работы с файлами Общие сведения
- •Пример работы с файлом
- •Создание потока, открытие и закрытие файла
- •Запись и чтение данных в текстовых файлах
- •Запись и чтение данных в двоичном режиме
- •If ( !File ) // Проверили удалось ли открыть файл
- •Как обнаружить конец файла?
- •Прямой доступ при работе с файлами
- •If ( !File ) // Проверили удалось ли открыть файл
- •Статус потоков ввода-вывода
- •Некоторые другие функции управления потоками ввода-вывода
- •Примеры по работе с файлами
- •12. Работа с динамической памятью Распределение памяти при работе программы
- •Динамическое выделение и освобождение памяти в стиле c
- •Возможные ошибки при работе с динамической памятью
- •Динамические массивы
- •Продолжение следует …
Структурные параметры функций
Структуры можно использовать в качестве параметров функций, как и обычные переменные. Для структур поддерживаются все три механизма передачи данных – по значению, через указатели и по ссылке.
Напишем три варианта функции, выводящей на экран данные студента.
Вариант 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 )
{
………..
}