- •Лабораторная работа 3 Функции
- •Примеры вызовов функций
- •Демонстрация функции без аргументов и не возвращающей значения
- •Демонстрация функции, определенной перед ее вызовом
- •Демонстрация функции с аргументами и не возвращающей значения
- •Демонстрация использования глобальных переменных при обмене данными между функциями
- •Демонстрация использования в функции локальных статических переменных
- •Передача в функцию в качестве параметра переменных разных типов Функция вычисления минимального расстояния между точками плоскости
- •Функция вычисления факториала
- •Функция вычисления хn через умножение
- •Функция определения максимального и минимального из двух чисел
- •Функция с параметром перечисляемого типа
- •Функция, выделяющая целую и дробную части вещественного числа
- •Функция, возвращающая ссылку как результат своей работы
- •Демонстрация inline-функций
- •Демонстрация функции с параметрами по умолчанию
- •Перегрузка функций
- •Перегрузка функций с равным числом аргументов
- •Перегрузка функций с разным числом аргументов
- •Шаблоны семейства функций
- •Рекурсивные функции
- •Рекурсивная функция вычисления факториала
- •Рекурсивная функция вывода на печать символов строки в обратном порядке
- •Рекурсивная функция печати числа в виде строки символов
- •Вычисление нод через итерации и через рекурсивную функцию
- •Вычисление интеграла по методу правых прямоугольников
- •Использование одинаковых вызовов функции для вычисления интеграла разными методами и для разных функций
- •Использование при вычислении интеграла многофайловой компиляции
- •Вычисление корня нелинейного уравнения
- •Правила оформления и вызова функций
- •Элементы оптимизации работы с функциями
Вычисление корня нелинейного уравнения
Рассмотрим еще один пример, требующий передачи в качестве параметра функции.
Для заданной функции f(x), используя метод половинного деления, вычислить корень уравнения на отрезке [a; b] с точностью = 10–6, а также количество итераций цикла для получения корня с заданной точностью. f(x) = ; a = 0; b = 2; s[2,8; 3,2]; s = 0,1;
typedef double (*fun_pointer)(double,double);
double fun1(double x, double s);
void otdel_korn(fun_pointer fun, double a=0, double b=2, double eps = 1e-6, double s1=1.0, double s2 =1.0, double ds=0.1);
void solve(fun_pointer fun, double A, double B, double eps, double i, int *iter, double *kor);
int main()
{
double a,b,eps,s1,s2,ds;
otdel_korn(fun1);
cout << "Enter a, b and eps!" << endl;
cin >> a >> b >> eps;
otdel_korn(fun1,a,b,eps);
cout <<"Enter s1, s2 and ds:" << endl;
cin >> s1 >> s2 >> ds;
otdel_korn(fun1,a,b,eps,s1,s2,ds);
_getch();
return 0;
}
double fun1(double x, double s)
{
return(cos(3.14*x)-pow(x,s));
}
void otdel_korn(fun_pointer fun, double a, double b, double eps, double s1, double s2, double ds)
{ int iter=0;
double shag=fabs(a-b)/100;
double nashalo=a, koneс=b+shag/2;
double x1,x2,s,koren=0;
for(s=s1; s<=s2; s+=ds) //цикл изменения значений параметра
{
while(nashalo < koneс)//цикл «движения» по отрезку
{
x1=fun(nashalo,s); //вызов функции с параметром s в т.nashalo
x2=fun(nashalo+shag,s);
cout << "s=" << s << " " << nashalo <<endl;
if (x1*x2>0) //если корня на отрезке нет
cout << "Function don't across OX for set interval" << endl;
if (!x1) {koren=a; //если корень в т. а
cout <<"koren x="<< koren <<" Kol-vo iterasij="<< iter << endl; }
if (!x2) {koren=b; //если корень в т.b
cout <<"koren x="<<koren <<" Kol-vo iterasij="<< iter << endl; }
if(x1*x2<=0)
{if (x1<0) //если корень на отрезке есть и х1<0
solve(fun,nashalo,nashalo+shag, eps, s, &iter, &koren);
else
solve(fun,nashalo+shag,nashalo, eps, s, &iter, &koren);
cout << "koren x="<< koren <<
" Kol-vo iterasij=" << iter << endl;
}
nashalo=nashalo+shag; //переход к след.точке
}//end цикла while
}//end цикла for
return;
}
void solve(fun_pointer fun, double A, double B, double eps,
double i, int *iter, double *kor)
{ double X_average;
*iter=0;
do
{(*iter)++;
X_average=(A+B)/2;
if (fun(A,i)*fun(X_average,i) <0.) B = X_average;
else A = X_average;
}
while(fabs(B-A)>eps);
*kor=(B+A)/2;
return;
}
Следующая программа вычисляет корень уравнения с использованием рекурсивной функции:
#include<stdlib.h>
typedef double (*fun_pointer)(double,double);
void otdel_korn(fun_pointer fun, double a=-2, double b=2, double eps = 1e-6, double s1=1.0, double s2 =2.0, double ds=0.5);
int solve_rec(fun_pointer fun, double fA, double fB, double fE, double s, int *iter, double *koren);
double function_1(double x, double s);
int main ()
{ double a, b, eps, s1, s2, ds;
otdel_korn(function_1);
cout << "Enter a, b and eps!" << endl;
cin >> a >> b >> eps;
otdel_korn(function_1, a, b, eps);
cout <<"Enter s1, s2 and ds:" << endl;
cin >> s1 >> s2 >> ds;
otdel_korn(function_1, a, b, eps, s1, s2, ds);
_getch();
return 0;
}
double function_1(double x, double s)
{
return(cos(3.14*x)-pow(x,s));
}
void otdel_korn(fun_pointer fun, double a, double b, double eps, double s1,double s2, double ds)
{ int iter=0;
double shag=fabs(b-a)/10;
double nashalo=a, koneс=b+shag/2;
double x1,x2, s, koren;
if (!fun)
{cout << "Function trouble" << endl; exit(0); } //если не задана функция
for(s=s1;s<=s2;s+=ds) //цикл изменения значений параметра
{nashalo=a;
while(nashalo < koneс)//цикл «движения» по отрезку
{
x1=fun(nashalo,s); //вызов функции с параметром s в т.nashalo
x2=fun(nashalo+shag,s);
cout << "s=" << s << " " << nashalo <<endl;
if (x1*x2>0) //если корня на отрезке нет
cout << "Function don't across OX for set interval" << endl;
if (!x1) {koren=a; //если корень в т. а
cout <<"koren x="<< koren <<" Kol-vo iterasij="<< iter << endl; }
if (!x2) {koren=b; //если корень в т.b
cout <<"koren x="<<koren <<" Kol-vo iterasij="<< iter << endl; }
if(x1*x2<=0)
{if (x1<0) //если корень на отрезке есть и х1<0
solve_rec(fun,nashalo,nashalo+shag, eps, s, &iter, &koren);
else
solve_rec(fun,nashalo+shag,nashalo, eps, s, &iter, &koren);
cout << "koren x="<< koren <<
" Kol-vo iterasij=" << iter << endl;
}
nashalo=nashalo+shag; //переход к следующей точке
} //end цикла while
} //end цикла for
return;
}
int solve_rec(fun_pointer fun,double fA, double fB, double fE, double s, int *iter, double *koren)
{ ( *iter)++;
if (fabs(fA-fB)<fE)
{*koren = (fA+fB)/2; //условие завершения
return 0;
}
double fMiddle = (fA+fB)/2;
double fRes = fun(fMiddle, s);
if (fabs(fRes-0.0)< fE)
{*koren = fMiddle; //условие завершения
return 0;
}
if (fRes<0)
return solve_rec(fun,fMiddle,fB,fE,s,iter,koren);
else
return solve_rec(fun,fA,fMiddle,fE,s,iter,koren);
}