учусь работать с функциями.задачка

 
0
 
C++
ava
lisica198808 | 15.04.2013, 11:47
необходимо найти точки перегиба функции, выбирая одну из трех заданных функций на нужном интервале.
математически как решается - понимаю,в ручную прорешивала, алгоритм как записать тоже понимаю, но у меня проблема с функциями.. вроде понимаю, но плохо ориентируюсь как их правильно передавать.особенно на строках 60,61,62, где компилятор выдает ошибку  cannot convert `float (*)(float)' to `float' in argument passing .

#include<stdio.h>
#include<stdlib.h>
#include<math.h>

float f1(float x)/*vira*enie 1*/
{return (x*cos(x))/(1+ pow(x,2));}

float f2 (float x) /*vira*enie 2*/
{return(exp(x)/x);}

float f3 (float x)/*vira*enie 3*/
{return (1/(3+2*cos(x)));}

float proizv1(float *f(float),float x)
/* pervaja proizvodnaja iz klassi4eskogo opredelenija eto f'(x)=(f(x0)-f(x))/(x-x0) */
/* opredelim proizvodnyjy s tochnost'jy h=x-x0=0.001 */
/* znachit x0=x-h */
/*polychaem znachenie dlja proizvodnoj (f(x-h)-f(x)/h */
{ float h;
h=0.001;
return((f(x-h)-f(x))/h);      
}


float proizv2(float *proizv1(float),float x)
/*vtoraja proizvodnaja iz klassi4eskogo opredelenija*/
/* f''(x)=(f'(x))' proizvodnaja ot proizvodnoj*/
{ float h;
h=0.001;
return((proizv1(x-h)-proizv1(x))/h);      
}

float tochki(float *proizv2(float),float xn,float xk,float dx)
{float x1,y; int i;
printf("____________________________\n");
printf("|___i____|___x___|_____y___|\n");
i=0;
  for (x1=xn;x1<=xk;x1+=dx)
   {proizv2(x1);
    i++;
    printf("|___%d____|_%.1f_|_%.5f_|\n",i,x1,proizv2(x1));
   }
    for (x1=xn;x1<=xk;x1+=dx)
     {proizv2(x1);
      if (proizv2(x1)==0) printf("tochka peregiba=%.1f\n",x1);
      /*yslovie syshestvovanija tochki peregiba*/
      else printf("net tochek peregiba");
     }
}

float vibor( float(*tochki)(float),float xn,float xk,float dx )
{int n;
printf("S kakoj fynkciej bydem rabotat'?\n");
printf("1.  x*cos(x))/(1+ pow(x,2)\n");
printf("2. exp(x)/x\n");
printf("3. 1/(3+2*cos(x))\n");
printf("0. Vihod\n"); 
  scanf("%d",&n);
   switch(n)
            {case 1: tochki(f1,-4,4,0.5); break;//dlja pervoj fynkcii na intervale -4 4
             case 2: tochki(f2,-6,1,0.5); break;//dlja vtoroj fynkcii na intervale -6 1
             case 3: tochki(f3,0,4,0.5); break;//dlja tret'ej fynkcii na intervale 0 4
             case 0: break;    
             default:printf("Nevernij re*im");  
             }
}          
int main()
  { vibor( );  // vibor( float(*tochki)(float),float xn,float xk,float dx); - bydet li pravil'nim takoj vizov???pri nem pojavljajytsa novie oshibki//
   system("pause");
   return 0;
   }


У меня в самой функции vibor неразбериха. Функция tochki возвращает результат через имя, а у меня самостоятельный оператор..Значит нужно передавать функцию присваиванием новому оператору-аргументу или как поступить чтоб передать правильно??

Запуталась в том как правильно функцию tochki передать в switch case.Очень сильно запуталась smile  smile  smile 

И как функцию vibor правильно вызвать в основной функции программы,немного путаюсь уже.Если я понимаю правильно ,основная функция у меня - похожа больше на описание а не на вызов, но возможный как по моему вызов я написала в коментах рядом,хотя при нем много новых ошибок возникает.
Подскажите пожалуйста, как исправить эти ошибки.
Comments (4)
ava
Guinness | 15.04.2013, 11:25 #
Я так понял, Вы не понимаете, что такое указатель на функцию. Рекомендую погуглить данный раздел.
И напишите, пожалуйста, в текстовом виде(на русском языке) алгоритм программы (последовательность действий). Т.к., есть у меня подозрение, Вы не понимаете, что вы хотите добиться от вызова каждой конкретной функции.
Пример:
1) Вывести пользователю меню с возможностью выбора функции, у которой он хочет найти точку перегиба.
2) Предложить пользователю ввести доп. параметры (xn, xk, dx)
3) Далее алгоритм (подробный, т.е. каждое свое действие) вычисления
....
n) Вывод результата
n+1) goto 1)
ava
xvr | 15.04.2013, 12:26 #
  • Уберите все аргументы из описания функции vibor. Она у вас вообще никаких параметров не принимает.
  • Исправьте описание указателей на функциии в параметрах функций proizv1, proizv2 и tochki. (У вас прототип был правильно написан только в функции vibor, т.е. именно там, где он вообще не был нужен)
ava
lisica198808 | 16.04.2013, 00:17 #
ну вот алгоритм для начала:
1) вывести пользователю меню для возможности выбора функции,для которой будем искать точки перегиба на определенном для нее промежутке:
данные  функции      1) x*cos(x))/(1+ pow(x,2) промежуток от -4 до 4 с шагом 0.5
                                      2)exp(x)/x  промежуток от -6 до 1 с шагом 0.5
                                      3)1/(3+2*cos(x))  промежуток от 0 до 4 с шагом 0.5

2) найдем первую производную от выбранной функции
3) найдем вторую производную от выбранной функции как f''(x)=(f'(x))'  производная от производной
4)Выведем все значения выбранной функции для ее заданного промежутка с шагом в виде таблицы.
5)Ищем точку перегиба.Точка перегиба существует когда вторая производная f''(x)=0 или =бесконечности, но мне необходимо рассматривать только для 0.Ставим данное условие, и ищем данные точки в выбранной функции, выводим на экран значение из заданного промежутка, при котором f''(x)=0.Если таких точек нет выводим об этом сообщение  


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

#include<stdio.h>
#include<stdlib.h>
#include<math.h>

float f1(float x)/*vira*enie 1*/
{return (x*cos(x))/(1+ pow(x,2));}

float f2 (float x) /*vira*enie 2*/
{return(exp(x)/x);}

float f3 (float x)/*vira*enie 3*/
{return (1/(3+2*cos(x)));}

/* pervaja proizvodnaja iz klassi4eskogo opredelenija eto f'(x)=(f(x0)-f(x))/(x-x0) */
/* opredelim proizvodnyjy s tochnost'jy h=x-x0=0.001 */
/* znachit x0=x-h */
/*polychaem znachenie dlja proizvodnoj (f(x-h)-f(x)/h */
float proizv1(float (*f)(float),float x)
{ float h;
h=0.001;
return(( (*f)(x-h)-(*f)(x))/h);      //dlja pervoj proizvodnoj: proizv1(f1) proizv1(f2) proizv1(f3)
}


/*vtoraja proizvodnaja iz klassi4eskogo opredelenija*/
/* f''(x)=(f'(x))' proizvodnaja ot proizvodnoj*/
float proizv2(float (*proizv1)(float),float x)
{ float h;
  h=0.001;
//mo*no vizvat' pervyjy proizvodnyjy: ff=proizv1(f1);ff=proizv1(f2);ff=proizv1(f3);//
return(( (*proizv1)(x-h)-(*proizv1)(x))/h);  //dlja vtoroj proizvodnoj ili return(( (proizv1)(x-h)-(proizv1)(x))/h); 
}


float tochki(float (*t)(float),float xn,float xk,float dx)    //vizov bydet tochki(proizv2,xn,xk,dx)
{float x1,y; int i;
printf("____________________________\n");
printf("|___i____|___x___|_____y___|\n");
i=0;
  for (x1=xn;x1<=xk;x1+=dx)




дальше не дописывала, потому что незнаю  теперь как правильно в tochki функцию proizv2 записать,так чтоб можно было расчитать ее значения.....критика,подсказки приветствуются...
ava
Guinness | 16.04.2013, 08:33 #
Вычисление второй производной и передача указателя на функцию как аргумент функции:
http://liveworkspace.org/code/1Dax1y$18

Имхо, я бы использовал:
1) разностную схему для производной второго порядка, а не брал производную от производной. Но тут видимо условия задания такие;
2) double вместо float, ибо при вычислении второй производной x^2, у меня получались отклонения уже в 3-ем знаке;
3) массив функций (если с++ - функторов) всех математических функций используемых у Вас в программе, но это у Вас вряд ли так уж необходимо, только если для собственного развития.

В общем, если Вам понятно как использовать указатели на функцию, то, по идее, Вы легко напишите оставшуюся часть программы.
Please register or login to write.
Firm of day
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Contributors
advanced
Submit