Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: передача с возвратом параметра по указателю в рекурсивную функцию  (Прочитано 9279 раз)
0 Пользователей и 3 Гостей смотрят эту тему.
eugrita
Помогающий

ru
Offline Offline

« : 05-12-2009 13:54 » 

Классический способ передачи параметров по указателю
void display_values(int *a, int *b) {
*a=1000; *b=1                                                          
                                                      }
void main() {
int a= 2002, b = 0;
display_values(&a, &b);
pruntf(“%i %i”,a,b);  //стало a=1000; b=1;

почему-то не работает в условиях рекурсивного вызова:

void iter(double a, double b,double x0,double x1,int N,int i,double *X,double *sum)
{ //восходящая рекурсия
   double x2;
   x2=a*x1+b*x0;
   if (i==N){
   *X=x2;//здесь *X получает ненулевое значение
          // а проверяя значение 6 параметра (*X) после вызова вижу что он=0?!!!

    return;
            }
   else      {
     x0=x1;x1=x2 ;
     iter(a,b,x0,x1,N,i+1,&X, &sum);
       // (*sum)+=*X; //а здесь вообще ошибка выполнения
             };
}
« Последнее редактирование: 06-12-2009 16:34 от eugrita » Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #1 : 05-12-2009 14:35 » 

eugrita,  iter(a,b,x0,x1,N,i+1,&X, &sum); Ошибка тут. Зачем давать ссылку на указатель?
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
eugrita
Помогающий

ru
Offline Offline

« Ответ #2 : 05-12-2009 15:23 » new

Так вот и хочу понять. Вроде, способ передачи параметра по ссылке есть (см. мой пример выше)
Т.е. хотите сказать, что в моем случае надо было iter(a,b,x0,x1,N,i+1,&X, sum); или даже
iter(a,b,x0,x1,N,i+1,&X, *sum) ?
Правда, я выкинул еще и дурацкий параметр double *X, переделав его в возвращаемое значение.
Теперь выглядит так:
double iter(double a, double b,double x0,double x1,int N,int i,double *sum)
{ //âîñõîäÿùàÿ ðåêóðñèÿ
 double x2;
 x2=a*x1+b*x0;
 if (i==N)
       return x2;
 x0=x1;x1=x2 ;
 x2=iter(a,b,x0,x1,N,i+1, &sum);
  return x2;//не поставишь здесь return - будет неверно !!!
}

При этом, если в конце не стоит  return x2 (вроде, по логике, хватает return в блоке  if (i==N){... то вернется не то.
Видимо, потому что при рекурсивном вызове return через  if (i==N){. лишь самый внутренний,
а за ним идет ряд возвратов из вышестоящих уровней!!!
« Последнее редактирование: 07-12-2009 07:53 от Sel » Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #3 : 05-12-2009 17:00 » 

Код:
void iter(double a, double b,double x0,double x1,int N,int i,double *X,double *sum)
{ //восходящая рекурсия
   double x2;
   x2=a*x1+b*x0;
   if (i==N){
      *X=x2;//здесь *X получает ненулевое значение
          // а проверяя значение 6 параметра (*X) после вызова вижу что он=0?!!!
      return;
   }
   else      {
     x0=x1;x1=x2 ;
     iter(a,b,x0,x1,N,i+1, X, sum);
     (*sum)+=(*X); //а здесь вообще ошибка выполнения
   }
}
Читай более внимательно правила работы с указателями. У тебя переменная X и sum уже являются указателем. Зачем к ним применять какие то действия, чтобы они стали указателем?
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
eugrita
Помогающий

ru
Offline Offline

« Ответ #4 : 06-12-2009 20:16 » 

Итог исследования
1)не получился никакой вариант рекурсивного вычисления одновременно в одной функции и члена последовательности и суммы. (ниже один из неверных вариантов)
Код:
double iter(double a, double b,double x0,double x1,int N,int i,double *X)
{ //восходящая рекурсия
  double x2,sum;
  x2=a*x1+b*x0;
  if (i==N){
     *X=x2;
     sum+=x2;
     return sum;
           }
   else {
     x0=x1;x1=x2 ;
     [b]sum+=iter(a,b,x0,x1,N,i+1,X);[/b]
     //sum+=*X;
     return sum;
        };
}

2)правильный вариант получился с разбиением вычисления элемента и суммы на 2 функции (наполовину взаимная рекурсия)  ниже
=====================================================
Код:
void iterX(double a, double b,double x0,double x1,int N,int i,double *X)
{ //восходящая рекурсия
  double x2=a*x1+b*x0;
  if (i==N)
    {*X=x2; return;}
   else {
     x0=x1;x1=x2 ;
    [b] iterX(a,b,x0,x1,N,i+1,X);[/b]
        };
}

 [b]void iterS(double a, double b,double x0,double x1,int N,int i,double *sum)[/b]
{ //восходящая рекурсия
  double x,x2=a*x1+b*x0;
  if (i==N)
   {*sum+=x2; return;}
   else {
    [b] iterX(a,b,x0,x1,N,i,&x);[/b]
     (*sum)+=x;
    [b] iterS(a,b,x0,x1,N,i+1,sum);[/b]
        };
}

//вызов
iterX(a,b,x0,x1,n,2,&x);
printf("x[%i]=%f\n\n",n,x);
Sum=0;
iterS(a,b,x0,x1,n,2,&Sum);
Sum+=x0+x1;
printf("S[%i]=%f\n\n",n,Sum);
« Последнее редактирование: 06-12-2009 20:24 от Finch » Записан
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #5 : 28-12-2009 12:14 » 

Есть штука такая... ссылка называется (типа указателя, но не указатель Улыбаюсь ), рекомендую ознакомиться

рекурсией запросто можно реализовать то, что тебе нужно.
Кстати вообще не понял зачем в iterS передавать X? Какой смысл? Вот так будет достаточно (по идее, не запускал)

Код:
double iter(double a, double b, double x0, double x1, int N, int i)
{ //восходящая рекурсия
  double sum = 0;
  double x2 = a * x1 + b * x0;
  if (i == N)
     sum += x2;
  else
     sum += iter(a, b, x1, x2, N, i+1, X);

  return sum;
}
Записан

С уважением Lapulya
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines