Скачать 1.94 Mb.
|
Программа 2.1. Программа 2.1, конечно, допускает запись в более сжатой форме, но в данном виде она служит хорошей иллюстрацией некоторых свойств функций Си++:
Внутри функции может быть несколько операторов возврата "return". Функция завершается после выполнения любого оператора "return". Например: double absolute_value(double number) { if (number >= 0) return number; else return -number; 32 3. Способы передачи параметров внутрь функций Во всех рассмотренных до сих пор примерах параметры функций передавались по значению. При вызове из функции "main () " вызываемой функции передаются копии указанных переменных. Например, в программе 2.1 функции "area (...)" передаются текущие значения переменных "this_length" и "this_width". Затем функция "area (...)" сохраняет переданные значения в собственных локальных переменных, и именно эти переменные участвуют в последующих вычислениях внутри функции. 3.1 Передача параметров по значению Функции, принимающие параметры по значению, "безопасны" в том смысле, что они не могут случайно изменить переменные вызывающей функции (т.е. у функций нет скрытых побочных эффектов). Большинство функций проектируются именно таким образом. Программа 3.1 поясняет, почему важно гарантировать "сохранность" переменных вызывающей функции. Эта программа должна выводить на экран факториал и корень из числа, введенного пользователем: Введите положительное число: 4 Факториал 4! равен 24, а квадратный корень из 4 равен 2. Для извлечения квадратного корня применяется библиотечная функция "sqrt(...)". Библиотечной функции для вычисления факториала нет, поэтому придется написать собственную функцию (вычисляющую для любого положительного целого числа n значение n! = (1*2*3*. . .*n)). #include #include int factorial(int number); // ГЛАВНАЯ ФУНКЦИЯ: int main() { int whole number; cout << "Введите положительное число:\n"; cin » whole number; cout << "Факториал " << whole number << "! равен "; cout « factorial(whole_number); cout « ", а квадратный корень из " « whole_number; cout « " равен " « sqrt(whole_number) « ".\n"; return 0; } // КОНЕЦ ГЛАВНОЙ ФУНКЦИИ // ФУНКЦИЯ ДЛЯ ВЫЧИСЛЕНИЯ ФАКТОРИАЛА: int factorial(int number) { int product =1; for ( ; number > 0 ; number--) product *= number; 33 return product; } // КОНЕЦ ФУНКЦИИ Программа 3.1. Если бы функция "factorial (...)" изменяла переменную вызывающей функции, то программа 3.1 выдавала бы следующий ответ (формально правильный, но по смыслу задачи некорректный): Введите положительное число: 4 Факториал 4! равен 24, а квадратный корень из 0 равен 0. 3.2 Передача параметров по ссылке Все-таки иногда бывает необходимо, чтобы функция изменила значение переданного ей параметра. Рассмотрим программу 2.1. С 10-й по 14-ю строку в ней выполняется запрос размеров прямоугольника, а затем вычисляется его площадь. При структурном программировании независимые по смыслу части программы принято оформлять в виде отдельных функций. Для получения данных от пользователя создадим функцию "get_dimensions". В данном случае необходимо, чтобы эта функция изменяла значения переменных "this_length" и "this_width" (переданных ей в качестве параметров) - помещала в них значения, введенные пользователем с клавиатуры. Изменение параметров функции возможно при передаче параметров по ссылке. У таких параметров в заголовке функции после имени типа указывается сим- вол "&". #include int area ( int length, int width ); void get_dimensions( int& length, int& width ); // ГЛАВНАЯ ФУНКЦИЯ: int main () { int this_length, this_width; get_dimensions( this_length, this_width ); cout « "Площадь прямоугольника с размерами "; cout « this_length « "x" « this_width; cout « " равна " « area( this_length, this_width ) « "\n"; return 0; } // КОНЕЦ ГЛАВНОЙ ФУНКЦИИ // ФУНКЦИЯ ВВОДА РАЗМЕРОВ ПРЯМОУГОЛЬНИКА: void get_dimensions( int& length, int& width ) { cout « "Введите длину: "; cin » length; cout « "Введите ширину: "; cin » width; cout « "\n"; 34 // КОНЕЦ ФУНКЦИИ // ФУНКЦИЯ ВЫЧИСЛЕНИЯ ПЛОЩАДИ: int area( int length, int width ) { return length*width; } // КОНЕЦ ФУНКЦИИ Программа 3.2. Функция "get_dimensions" изменяет значения параметров "this_length" и "this_width", но не возвращает никакого значения (т.е. не является "функцией" в математическом смысле). Этот факт отражается и в прототипе, и в определении функции - в качестве возвращаемого значения указан тип "void" ("пустой" тип). 4. Полиморфизм и перегрузка функций Одним из характерных свойств объектно-ориентированного языка, в том числе и Си++, является полиморфизм — использование одного имени для выполнения различных действий над различными объектами. Применительно к функциям это называется перегрузкой. Для основных операций Си++ перегрузка уже встроена в язык: например, у сложения существует только одно имя, "+", но его можно применять для сложения как целых, так и вещественных значений. Эта идея расширяется на обработку операций, определенных пользователем, т.е., функций. Перегруженные функции имеют одинаковые имена, но разные списки параметров и возвращаемые значения (см. программу 4.1). #include int average( int first_number, int second_number, int third_number ); int average( int first_number, int second_number ); // ГЛАВНАЯ ФУНКЦИЯ: int main () { int number_A = 5, number_B = 3, number_C = 10; cout « "Целочисленное среднее чисел " « number_A « " и "; cout « number_B « " равно "; cout « average(number_A, number_B) « ".\n\n"; cout « "Целочисленное среднее чисел " « number_A « ", "; cout « number_B « " и " « number_C « " равно "; cout « average(number_A, number_B, number_C) « ".\n"; return 0; } // КОНЕЦ ГЛАВНОЙ ФУНКЦИИ // ФУНКЦИЯ ДЛЯ ВЫЧИСЛЕНИЯ ЦЕЛОЧИСЛЕННОГО СРЕДНЕГО // ЗНАЧЕНИЯ 3-Х ЦЕЛЫХ ЧИСЕЛ: int average( int first_number, int second_number, int third number ) 35 return ((first_number + second_number + third_number)/3); // КОНЕЦ ФУНКЦИИ // ФУНКЦИЯ ДЛЯ ВЫЧИСЛЕНИЯ ЦЕЛОЧИСЛЕННОГО СРЕДНЕГО // ЗНАЧЕНИЯ 2-Х ЦЕЛЫХ ЧИСЕЛ: int average( int first_number, int second_number ) return ((first_number + second_number)/2); // КОНЕЦ ФУНКЦИИ Программа 4.1. Программа 4.1. выводит на экран сообщения: Целочисленное среднее чисел 5 и 3 равно 4. Целочисленное среднее чисел 5, 3 и 10 равно 6. 5. Процедурная абстракция и "хороший" стиль программирования Функции помогают применять для разработки программ структурный метод проектирования "сверху вниз". При этом решаемая задача делится на подзадачи (и затем на под-подзадачи и т.д.). Для решения каждой подзадачи программист реализует отдельную функцию, при этом ему не нужно знать детали реализации остальных функций. Чтобы функцией мог воспользоваться другой программист, она должна иметь осмысленное имя и комментарий с описанием назначения функции, ее параметров и возможных возвращаемых значений. Опытные программисты на начальных этапах разработки часто применяют пустые функции (заглушки), которые содержат только оператор возврата значения соответствующего типа. Эти функций облегчают отладку главной функции или просто функции более высокого уровня. Выделение в решаемой задаче функций методом "сверху вниз" часто называется функциональной или процедурной абстракцией. При проектировании независимых друг от друга функций широко применяется передача параметров по значению и локальные переменные внутри функций. После реализации программист может рассматривать подобные функции как "черные ящики". Для их использования знать детали реализации не обязательно. 6. Модульное программирование Помимо метода "сверху вниз", вторым важным методом структурного проектирования является метод модульного программирования. Он предполагает разделение текста программы на несколько файлов, в каждом из которых сосредоточены независимые части программы (сгруппированные по смыслу функции). В программах на Си++ часто применяются библиотечные функции (например, "sqrt (...)"). Для использования большинства функций, в том числе и библиотечных, необходимы два файла (в скобках примеры даны для "sqrt (...)"): • Заголовочный файл ("math.h") с прототипом функции ("sqrt (...)" и многих других математических функций). Поэтому в программах, вызывающих 36 "sqrt(...)", есть строка "#include ", а не явное объявление этой функции. • Файл реализации (для пользовательских функций это файлы с исходным текстом на Си++, а библиотечные функции обычно хранятся в скомпилированном виде в специальных библиотечных файлах, например, "libcmtd.lib"). Файлы реализации пользовательских функций (обычно с расширением ". cpp") содержат определения этих функций. Разделение исходного текста на заголовочные файлы и файлы реализации показано в программе 6.1, которая выполняет те же действия, что и программа 4.1. Теперь программа состоит из трех файлов: главного файла, заголовочного файла с описаниями двух функций расчета среднего значения, и соответствующего файла реализации. В главном файле содержится следующий текст: #include #include "averages.h" int main () { int number_A = 5, number_B = 3, number_C = 10; cout << "Целочисленное среднее чисел " << number A << " и "; cout « number_B « " равно "; cout « average(number_A, number_B) « ".\n\n"; cout « "Целочисленное среднее чисел " « number_A « ", "; cout « number_B « " и " « number_C « " равно "; cout « average(number_A, number_B, number_C) « ".\n"; return 0; } Главный файл программы 6.1. Обратите внимание, что имя файла стандартной библиотеки "iostream.h" в директиве препроцессора "include" заключено в угловые скобки ("<>"). Файлы с именами в угловых скобках препроцессор ищет в библиотечных каталогах, указанных в настройках компилятора. Имена пользовательских заголовочных файлов обычно заключаются в двойные кавычки, и препроцессор ищет их в текущем каталоге программы. Далее приведено содержимое файла "averages.h". В нем есть идентификатор препроцессора "averages_h" и служебные слова препроцессора "ifndef" ("если не определено"), "define" ("определить") и "endif" ("конец директивы if"). Идентификатор "averages_h" является глобальным символическим именем заголовочного файла. Первые две строки файла служат защитой от повторной обработки текста заголовочного файла препроцессором, на случай, если в исходном тексте программы строка "#include "averages .h"" встречается несколько раз. В заголовочных файлах, кроме прототипов функций, часто размещаются описания глобальных констант и пользовательских типов. Подробнее об этом говорится в курсе объектно-ориентированного программирования. #ifndef AVERAGES_H # define AVERAGES_H 37 // (Определения констант и пользовательских типов) // ПРОТОТИП ФУНКЦИИ ДЛЯ ВЫЧИСЛЕНИЯ ЦЕЛОЧИСЛЕННОГО СРЕДНЕГО // ЗНАЧЕНИЯ 3-Х ЦЕЛЫХ ЧИСЕЛ: int average( int first_number, int second_number, int third_number ); // ПРОТОТИП ФУНКЦИИ ДЛЯ ВЫЧИСЛЕНИЯ ЦЕЛОЧИСЛЕННОГО СРЕДНЕГО // ЗНАЧЕНИЯ 2-Х ЦЕЛЫХ ЧИСЕЛ: int average( int first_number, int second_number ); #endif Заголовочный файл averages.h. Ниже показано содержимое файла "averages . cpp" с исходным текстом пользовательских функций: #include #include "averages.h" // ФУНКЦИЯ ДЛЯ ВЫЧИСЛЕНИЯ ЦЕЛОЧИСЛЕННОГО СРЕДНЕГО // ЗНАЧЕНИЯ 3-Х ЦЕЛЫХ ЧИСЕЛ: int average( int first_number, int second_number, int third number ) { return ((first number + second number + third number)/3); // ФУНКЦИЯ ДЛЯ ВЫЧИСЛЕНИЯ ЦЕЛОЧИСЛЕННОГО СРЕДНЕГО // ЗНАЧЕНИЯ 2-Х ЦЕЛЫХ ЧИСЕЛ: int average( int first_number, int second_number ) { return ((first_number + second_number)/2); } Файл реализации averages.cpp. Программа 6.1 демонстрирует основное достоинство модульного подхода: при изменении деталей реализации в файле "averages . cpp" не обязательно вносить изменения в файл "averages . h" или в главный файл программы. 7. Сводка результатов В данной лекции описано, как в Си++ можно создавать новые функции. Есть два способа передачи параметров внутрь функции: по значению и по ссылке. Функции облегчают применение процедурной абстракции при разработке программ методом "сверху вниз". При модульном подходе описание и реализация функций размещаются в отдельных файлах, в таком случае для вызова функции необходимо включать в текст программы заголовочный файл. 38 8. Упражнения Упражнение 1 В программе из упражнения 2 лекции 2 (файл ex2_2.cpp) выделите 6 функций, имена и назначение которых перечислены ниже: fahrenheit of Возвращает значение температуры по шкале Фаренгейта для переданного значения по шкале Цельсия. absolute_value_of Возвращает значение температуры в абсолютной шкале для переданного значения по шкале Цельсия. print preliminary message Печать сообщения, поясняющего назначение программы. input_table_specifications Запрос параметров таблицы с клавиатуры. print_message_echoing_input Повторное отображение параметров, введенных пользователем. print_table Печать таблицы температур. Проверьте свою программу для различных исходных данных. В качестве контрольного примера можете использовать следующие выходные данные: Эта программа печатает значения температур в разных шкалах. Введите минимальное (целое) значение температуры по Цельсию, которое будет в первой строке таблицы: 0 Введите максимальное значение температуры: 100 Введите разницу температур между соседними строками таблицы: 20 Преобразование значений температуры от 0 градусов Цельсия до 100 градусов Цельсия, с шагом 2 0 градусов: Цельсий Фаренгейт Абсолютная температура 0 32.00 273.15 20 68.00 293.15 40 104.00 313.15 100 212.00 485.15 Упражнение 2 Разделите программу из упражнения 1 на три файла:
f ahrenheit_of (...) И absolute_value_of (...) "; 3) файл реализации с определением этих двух функций. Снова проверьте свою программу для различных исходных данных. 39 |
Лекция основы Си++ 9 Б73 Основы программирования на языке Си++: Для студентов физико-математических факультетов педагогических институтов. – Коломна:... |
Лекция I и проблема языка и сознания лекция II 31 слово и его семантическое... Монография представляет собой изложение курса лекций, про* читанных автором на факультете психологии Московского государственного... |
||
Лекция психосексуальное развитие. Возрастная динамика взаимоотношения полов 15 Основы семейной психопедагогики (курс лекций) / В. И. Короткий. — Архангельск: М'арт, 2003. — 178 с |
Лекция Архитектура 32-разрядных ос windows 7 Б73 Основы программирования на языке Си++: Для студентов физико-математических факультетов педагогических институтов. – Коломна:... |
||
Лекция Основные понятия ооп 7 Б73 Основы программирования на языке Си++: Для студентов физико-математических факультетов педагогических институтов. – Коломна:... |
Лекция №1. Введение. Элементы дифференциальной геометрии. 2 Лекция №5. Множества Жюлиа, множество Мандельброта и их компьютерное представление. 18 |
||
Лекция на тему: «Современные подходы к содержанию дополнительного образования детей» ... |
Лекция в Дорнахе 22 мая 1920 года Канта и протестантизма. Эта лекция вызвала негодование среди членов Лиги, культивировавших и признававших под названием монизма вообще... |
||
Курс лекций Лекция Введение в философскую суицидологию. Лекция Общая... Открыть, в чём состоит суть суицида, наука не в состоянии (по собственной ограниченной природе) и потому должна обращаться за объяснениями... |
Лекция для слушателей курса «Основы религий» Я не могу всего этого понять, потому что некоторые пытливые учителя, помню, меня просто одолевали вопросами, где найти, например,... |
Поиск на сайте Главная страница Литература Доклады Рефераты Курсовая работа Лекции |