- •Задание:
- •Задание:
- •Лабораторная работа 4 Переменные, типы данных и выражения
- •1. Идентификаторы
- •2. Типы данных
- •2.2 Вещественные числа
- •2.3 Преобразование типов в выражениях
- •2.4 Символьный тип
- •2.5 Символьные строки
- •2.6 Типы данных, определяемые пользователем
- •3. Вывод вещественных чисел на экран
- •4. Описания, константы и перечисления
- •4.1 Тип "Перечисление"
- •4.2 Расположение описаний констант и переменных в исходном тексте
- •5. Присваивание и выражения
- •5.1 Краткая форма записи операторов присваивания
- •5.2 Логические выражения и операторы
- •6. Сводка результатов
- •Лабораторная работа 5 Функции и процедурная абстракция
- •1. Назначение подпрограмм
- •2. Определение новых функций
- •3. Способы передачи параметров внутрь функций
- •3.1 Передача параметров по значению
- •3.2 Передача параметров по ссылке
- •4. Полиморфизм и перегрузка функций
- •5. Процедурная абстракция и "хороший" стиль программирования
- •6. Модульное программирование
- •Лабораторные работа 6 Текстовые файлы и потоки ввода/вывода
- •1. Потоки ввода/вывода
- •Создание потоков
- •1.2 Подключение и отключение потоков от файлов
- •2. Проверка ошибок выполнения файловых операций
- •3. Символьный ввод/вывод
- •3.1 Функция ввода "get(...)"
- •3.2 Функция вывода "put(...)"
- •3.3 Функция "putback(...)"
- •4. Проверка достижения конца файла при операциях ввода
- •4.1 Проверка конца файла с помощью функции "eof()"
- •5. Передача потоков функциям в качестве параметров
- •Лабораторные работа 7 Операторы ветвления и циклы
- •1. Логические значения, выражения и функции
- •2. Циклы "for", "while" и "do...While"
- •3. Множественное ветвление и оператор "switch"
- •4. Блоки и область видимости переменных
- •5. Замечание о вложенных циклах
- •6. Сводка результатов
- •Задание:
- •Лабораторные работа 8 Массивы и символьные строки
- •1. Назначение массивов
- •1.1 Объявление массивов
- •1.2 Использование элементов массивов в выражениях
- •2. Передача массивов в качестве параметров функций
- •3. Сортировка массивов
- •4. Двумерные массивы
- •5. Символьные строки
- •5.2 Объявление и инициализация символьных строк
- •5.3 Библиотечные функции для работы с символьными строками
- •5.4 Чтение символьных строк из потока ввода с помощью функции "getline(...)"
- •6. Сводка результатов
2. Передача массивов в качестве параметров функций
Чтобы у программ была понятная человеку структура, допускающая
модификацию и повторное использование исходного текста, отдельные
алгоритмы следует реализовывать в виде самостоятельных функций. Т.к.
для хранения данных часто применяются массивы, то бывают необходимы
и функции для их обработки. Этим функциям массивы можно передавать в
качестве параметров. В показанном ниже фрагменте программы 8.3
содержится определение функции, которая принимает массив типа
"Hours_array" (см. программу 8.1) и возвращает среднее количество часов,
отработанных сотрудниками группы.
float average( Hours_array hrs )
{
float total = 0;
int count;
for ( count = 0; count < NO_OF_EMPLOYEES; count++ )
total += float(hrs[count]);
return ( total/NO_OF_EMPLOYEES );
}
Фрагмент программы 8.3
Эту функцию можно сделать более универсальной, если размер
массива не фиксировать в ее определении, а передать в качестве второго
параметра:
float average( int list[], int length )
{
float total = 0;
int count;
for ( count = 0 ; count < length; count++ )
total += float(list[count]);
return ( total/length );
}
В этом примере показан очень распространенный способ
оформления функций, работающих с массивами: в одном параметре
передается длина массива, а в другом –сам массив, причем в описании
параметра-массива не указывается длина массива (например, "int list[]").
Параметры-массивы всегда передаются по ссылке (а не по
значению), хотя при их описании в заголовке функции символ "&" не
указывается. Правило "массивы всегда передаются по ссылке" введено для
того, чтобы функции не делали собственных внутренних копий переданных
им массивов – для больших массивов это могло бы привести к
нерациональным затратам памяти. Следовательно, как и параметры по
ссылке, рассматривавшиеся в 3-ей лекции, все изменения элементов
параметров-массивов внутри функций будут видны и в вызывающей
функции.
Далее показана функция (фрагмент программы 8.4), принимающая в
качестве параметров три массива. После ее вызова каждый элемент
третьего массива будет равен сумме двух соответствующих элементов
первого и второго массивов.
void add_lists( int first[], int second[], int total[],
int length )
{
int count;
for ( count = 0; count < length; count++ )
total[count] = first[count] + second[count];
}
Фрагмент программы 8.4
В целях безопасности, для защиты от случайного изменения
элементов массива, в описание первых двух параметров функции добавим
модификатор типа "const":
void add_lists( const int fst[], const int snd[], int tot[],
int len )
{
int count;
for ( count = 0; count < len; count++ )
tot[count] = fst[count] + snd[count];
}
Теперь компилятор не будет обрабатывать ни один оператор в
определении функции, который пытается модифицировать элементы
константных массивов "fst" или "snd". Фактически, ограничение,
накладываемое модификатором "const" в данном контексте, в некоторых
ситуациях оказывается слишком строгим. Например, компилятор выдаст
ошибку при обработке следующих двух функций:
void no_effect( const int list[] )
{
do_nothing( list );
}
void do_nothing( int list[] )
{
;
}
Фрагмент программы 8.5
Ошибка компиляции программы 8.5 объясняется тем, что, хотя
фактически функция "do_nothing(...)" не выполняет никаких действий, но в ее
заголовке отсутствует модификатор "const". Когда компилятор в теле
функции "no_effect(...)" встретит вызов функции "do_nothing(...)", то он обратится
только к заголовку функции "do_nothing(...)", и выдаст ошибку о невозможности
передачи константного массива в эту функцию.