Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Пример 7.1. Передача в функцию параметров стандартных типов






Написать программу вывода таблицы значений функции Ch x (гиперболический ко­синус) для аргумента, изменяющегося в заданных пределах с заданным шагом. Зна­чения функции вычислять с помощью разложения в ряд Тейлора с точностью r.

Алгоритм работы про­граммы: для каждого из серии значений аргумента вы­числяется и затем выводится на экран значение функции. Очевидно, что подсчет суммы ряда для одного значения аргумента логично оформить в виде отдельной функции.

Разработка любой функции ведется в том же порядке, что и разработка программы в целом. Сначала определяется интерфейс функции, то есть какие значения подаются ей на вход и что должно получиться в результате. Затем продумываются структуры данных, в которых будут храниться эти и промежуточные значения; затем составляется алгоритм, программа и тестовые примеры.

Нашей функции подсчета суммы ряда требуется получить извне значение аргу­мента и точность. Пусть эти величины, а также результат имеют тип double. Следо­вательно, заголовок функции может выглядеть так:

 

double cosh(double x, double eps);

 

Для вычисления суммы ряда понадобят­ся две промежуточные переменные - для хранения очередного члена ряда и его номера. Эти переменные должны быть описаны внутри функции, поскольку вне ее они не нужны.

 

include < stdio.h>

#include < math.h>

double cosh(double x, double eps); //прототип ф-ции

int main()

{

double Xn, Xk, dX, Eps;

printf(" Enter Xn, Xk, dX, eps \n");

scanf(" %lf%lf%lf%lf.& Xn, & Xk, & dX, & eps);

printf (................................ \n");

printf(| X | Y |\n");

printf(.............................\n");

for (double x = Xn; x < = Xk; x += dX)

printf(“|%9.2]f |%14.6g |\n”\ x. cosh(x. eps));

printf("...............................\n);

return 0;

}

double cosh(double x. double eps)

{

const int Maxlter - 500; /* максимальное количество итераций */

double ch = 1. у = ch; /* первый член ряда и нач. значение суммы */

for (Int n = 0; fabs(ch) > eps; n++)

{

ch *- x * x /((2 * n + 1)*(2 * n + 2)); // член ряда

у += ch; // добавление члена ряда к сумме

if (n > Maxlter)

{

puts(“ Ряд расходится! \n");

return 0;

}

}

return у;

}

 

За счет использования функции программа получилась более ясной и компактной, потому что задача была разделена на две: вычисление функции и пе­чать таблицы. Кроме того, написанную нами функцию можно при необходимости без изменений перенести в другую программу или поместить в библиотеку.

Если определение функции размещается после ее вызова, то перед функцией, в которой он выполняется, размещают прототип (заголовок). Обычно заголовки всех используемых в программе функций размещают в самом начале файла или в отдельном заголовочном файле. Заголовок нужен для того, чтобы компилятор мог проверить правильность вызова функции. Стандартные заголовочные файлы, ко­торые мы подключаем к программам, содержат прототипы функций библиотеки именно с этой целью.

В этой программе для ввода-вывода мы применили не классы, а функции, унасле­дованные из библиотеки языка С, поскольку с их помощью форма­тированный вывод записывается более компактно. Специ­фикация формата применяется для вывода вещественных чисел в широком диапазоне значений. Первое число модификатора (14) задает, как и для других спецификаций, ширину отводимого под число поля, а второе (6) - не точность, как в формате f, а количество значащих цифр. При этом число выводится либо в формате f, либо в формате е (с порядком) в зависимости от того, какой из них получится короче.

При написании нашей функции возникает проблема, как сигнализировать о том, что ряд расходится. Рассмотрим существующие способы решения проблемы получения из подпрограммы признака ее аварийного завершения. Каждый из них имеет свои плюсы и минусы.

Во-первых, можно поступить так, как сделано в приведенной выше программе: вывести текстовое сообщение, сформировать какое-либо определенное значение функции (чаще всего это 0) и выйти из функции. Недостаток этого способа - пе­чать диагностического сообщения внутри функции. Это нежелательно, а порой (например, когда функция входит в состав библиотеки) и вовсе недопустимо. По­пробуйте задать в качестве исходных данных большие значения аргумента и высо­кую точность. Вы увидите, что 500 итераций для ее достижения недостаточно, и таб­лицу результатов «портит» сообщение о том, что ряд расходится.

Более грамотное решение - сформировать в функции и передать наружу признак успешного завершения подсчета суммы, который должен анализироваться в вы­зывающей программе. Такой подход часто применяется в стандартных функциях. В качестве признака используется либо возвращаемое значение, которое не вхо­дит в множество допустимых (например, отрицательное число при поиске номера элемента в массиве или ноль для указателя), либо отдельный параметр ошибки.

Обычно параметр ошибки представляет собой целую величину, ненулевые значе­ния которой сигнализируют о различных ошибках в функции. Если ошибка мо­жет произойти всего одна, параметру можно назначить тип boo!. Параметр переда­ется в вызывающую программу и там анализируется. Для нашей задачи это решение выглядит так:

 






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.