Массив указателей на функции - C (СИ) (70275)
Формулировка задачи:
Здравствуйте! Подскажите пожалуйста, где ошибка в программе. Не могу разобраться с массивом указателей на функции.
В строчках " x0=Newton(a, b, maxIteration, h, mas[funcNum], *Derivative, *secondDerivative); " показывает ошибку.
#include <stdio.h>
#include <cmath>
#include <conio.h>
#include <stdlib.h>
int i;
int getch (); //Объявление прототипов функций
double Derivative(double, double, double(*func)(double x) ) ;
double secondDerivative(double x, double h, double(*Derivative)(double x) ) ;
double Newton(double, double, int, double, double (*func)(double x), double (*Derivative)(double, double, double(*func)(double x)), double (*secondDerivative)(double, double, double (*Derivative)(double, double, double(*func)(double x))));
double func1(double), func2(double), func3(double), func4(double), func5(double), func6(double), func7(double), func8(double);
void func()
{
int maxIteration, i, funcNum;
double x0,xn;// вычисляемые приближения для корня
double a, b, c, h, eps, func;// границы отрезка и необходимая точность
//Объявление массива ссылок на функции
double (*mas[8])(double) = {func1, func2, func3, func4, func5, func6, func7, func8};
printf( " Vvedite h " );
scanf( "%lf", &h ); // вводим шаг
printf( " Vvedite eps " );
scanf( "%lf", &eps ); // вводим нужную точность вычислений
printf( " Vvedite maximum number of iteration: " );
scanf( "%lf", &maxIteration );// вводим кол-во итераций
for(funcNum = 0; funcNum < 8; funcNum++)
{
printf("%d\n", funcNum);
if (mas[funcNum](a)*secondDerivative(a,h,mas[funcNum])>0) x0 = a; // для выбора начальной точки проверяем f(x0)*p2f(x0)>0 ?
else x0 = b;
c=(a+b)/2;
if (mas[funcNum](c)*mas[funcNum](a)<0)
b=c;
if (mas[funcNum](c)*mas[funcNum](b)<0)
a=c;
x0=Newton(a, b, maxIteration, h, mas[funcNum], *Derivative, *secondDerivative);
xn = x0-mas[funcNum](x0)/Derivative(x0, h, mas[funcNum]); // считаем первое приближение
while (fabs(x0-xn)>eps)
{
x0=Newton(a, b, maxIteration, h, mas[funcNum], *Derivative, *secondDerivative);
x0=xn;
xn = x0-mas[funcNum](x0)/Derivative(x0,h,mas[funcNum]); // непосредственно формула Ньютона
}
while( xn < 0 ) // пока не достигнем необходимой точности, будет продолжать вычислять
{
x0=Newton(a, b, maxIteration, h, mas[funcNum], *Derivative, *secondDerivative);
x0+=h;
xn = x0-mas[funcNum](x0)/Derivative(x0,h,mas[funcNum]); // непосредственно формула Ньютона
while (fabs(x0-xn)>eps)
{
x0=Newton(a, b, maxIteration, h, mas[funcNum], *Derivative, *secondDerivative);
x0=xn;
xn = x0-mas[funcNum](x0)/Derivative(x0,h,mas[funcNum]); // непосредственно формула Ньютона
}
printf("xn = %.9f\n",xn);
printf("f(x0) = %.9f\n",mas[funcNum](x0));
printf("Number of iteration = %d\n\n",i);
}
printf( " Exit?=> " );
scanf( "%lf", &exit );
}
getch();
}
//Функции-уравнения, решаемые в задаче
double func1(double x) { return exp(-x) + pow(x, 2) + 2; }
double func2(double x) { return -pow((x-2), 2); }
double func3(double x) { return exp(x)-2*x-2; }
double func4(double x) { return sin(x) + x - 1; }
double func5(double x) { return exp(-pow(x,2));}
double func6(double x) { return 2*exp(-3*x) - x +1; }
double func7(double x) { return log(x) - x + 1; }
double func8(double x) { return log(x) - pow((x-1), 2); }
//Первая производная функции
double Derivative(double x, double h, double(*func)(double x))
{
double Derivative = ((func(x + h) - func(x - h))/(2*h));
return Derivative;
}
//Вторая производная функции
double secondDerivative(double x, double h, double(*Derivative)(double x) )
{
double secondDerivative = ((Derivative(x + h) - Derivative(x - h))/(2*h));
return secondDerivative;
}Решение задачи: «Массив указателей на функции»
textual
Листинг программы
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
typedef double(*func_t)(double);
int i;
double derivative(double, double, func_t) ;
double second_derivative(double, double, func_t f) ;
double newton(double, double, func_t);
double func1(double), func2(double), func3(double), func4(double), func5(double), func6(double), func7(double), func8(double);
int main(void)
{
int maxIteration, i, funcNum;
double x0,xn;// вычисляемые приближения для корня
double a, b, c, h, eps, func;// границы отрезка и необходимая точность
//Объявление массива ссылок на функции
double (*mas[8])(double) = {func1, func2, func3, func4, func5, func6, func7, func8};
printf( " Vvedite h " );
scanf( "%lf", &h ); // вводим шаг
printf( " Vvedite eps " );
scanf( "%lf", &eps ); // вводим нужную точность вычислений
printf( " Vvedite maximum number of iteration: " );
scanf( "%lf", &maxIteration );// вводим кол-во итераций
for(funcNum = 0; funcNum < 8; funcNum++) {
printf("funcNum: %d\n", funcNum);
if (mas[funcNum](a)*second_derivative(x0, h, mas[funcNum]) > 0)
x0 = a; // для выбора начальной точки проверяем f(x0)*p2f(x0)>0 ?
else
x0 = b;
c = (a + b) / 2;
if (mas[funcNum](c)*mas[funcNum](a) < 0)
b=c;
if (mas[funcNum](c)*mas[funcNum](b) < 0)
a = c;
xn = newton(x0, h, mas[funcNum]);
while (fabs(x0-xn) > eps) {
x0 = xn;
xn = newton(x0, h, mas[funcNum]);
}
while( xn < 0 ) {// пока не достигнем необходимой точности, будет продолжать вычислять
x0+=h;
xn = newton(x0, h, mas[funcNum]);
while (fabs(x0-xn) > eps) {
x0 = xn;
xn = newton(x0, h, mas[funcNum]);
}
printf("xn = %.9f\n",xn);
printf("f(x0) = %.9f\n",mas[funcNum](x0));
printf("Number of iteration = %d\n\n",i);
}
printf( " Exit?=> " );
scanf( "%lf", &exit );
}
getchar();
}
//Функции-уравнения, решаемые в задаче
double func1(double x) { return exp(-x) + pow(x, 2) + 2; }
double func2(double x) { return -pow((x-2), 2); }
double func3(double x) { return exp(x)-2*x-2; }
double func4(double x) { return sin(x) + x - 1; }
double func5(double x) { return exp(-pow(x,2));}
double func6(double x) { return 2*exp(-3*x) - x +1; }
double func7(double x) { return log(x) - x + 1; }
double func8(double x) { return log(x) - pow((x-1), 2); }
//Первая производная функции
double derivative(double x, double h, func_t f)
{
return (f(x + h) - f(x - h)/(2*h));
}
//Вторая производная функции
double second_derivative(double x, double h, func_t f)
{
return (derivative(x, h, f) - derivative(x, h, f)/(2*h));
}
double newton(double x, double h, func_t f)
{
return (x - f(x)/derivative(x, h, f));
}
Объяснение кода листинга программы
- Объявлен массив из 8 ссылок на функции типа double(*mas[8])(double).
- Ввод начальных значений: шаг (h), точность (eps), максимальное число итераций (maxIteration).
- Проверка, является ли точка x0, определенная как a, корнем: если f(x0)*second_derivative(x0, h, mas[funcNum]) > 0, то x0 = a, иначе x0 = b.
- Вычисление значения c, среднего арифметического a и b.
- Проверка, является ли точка c корнем: если f(c)*masfuncNum < 0, то b = c, иначе a = c.
- Вычисление приближенного значения корня xn с помощью функции newton(x0, h, mas[funcNum]).
- Начало цикла: пока разница между текущим и предыдущим приближениями x0 и xn больше заданной точности eps, вычисляется новое приближение xn с помощью функции newton(x0, h, mas[funcNum]).
- Если полученное значение xn меньше нуля, то выполняется вложенный цикл: пока разница между текущим и предыдущим приближениями x0 и xn больше заданной точности eps, вычисляется новое приближение xn с помощью функции newton(x0, h, mas[funcNum]).
- Вывод информации о найденном корне xn, значении функции f(x0) и количестве итераций.
- Завершение работы программы.