Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> как происходит рекурсивный вызов 
V
    Опции темы
Pawl
Дата 4.1.2012, 11:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 649
Регистрация: 22.4.2008
Где: Витебск

Репутация: 7
Всего: 28



Доброго времени суток. Когда "помогал" своему товарищу делать к зачету программки по теме рекурсия, понял, что сам в этом деле не все понимаю. Так, например, есть код, который с помощью рекурсии выводит на экран сначала +, потом - элементы массива. При элементе, равном 0, вывод заканчивается. Код этот я нашел на делфи и из спортивного интереса переделал его на яву. Привожу обе программки:
Код

program ex;

{$APPTYPE CONSOLE}

uses
  SysUtils;

Type mas = array[1..10] of real;

var x : mas;
    i : integer;

Procedure print(var x : mas; i : integer);
begin
    if x[i] = 0 then
      Writeln('***')
    else
    begin
      if x[i] > 0 then
        writeln('[', i : 1, '] ' , x[i]:2:1);
      print(x, i + 1);
      if x[i] < 0 then
        writeln('[', i : 1, '] ' , x[i]:2:1);
    end;
end;

begin
  i := 0;
  repeat
    inc(i);
    read(x[i]);
  until x[i] = 0;
  print(x, 1);
  readln;
  readln;
end.

Код

public class Ex {
    public static int[] x = {-1, -2, 3, 4, -5, -9, 0};
    public static int i, o, p;

    public static void printing(int []x, int i) {
        if (x[i] == 0) {
            System.out.println("***");
        } else {
         if (x[i] < 0) {
                System.out.println("[" + i + "] " + x[i]);
         }
            
            printing(x, i + 1);
            
            if (x[i] > 0) {
                System.out.println("[" + i + "] " + x[i]);
            }            
        }
    }

    public static void main (String...args) {
        printing(x, 0);
    }
}

Так все работает прекрасно, но когда я в коде на делфи заменил рекурсивную строку print(x, i + 1); на print(x, inc(i)); на этапе компиляции у меня появилась ошибка
Код

[DCC Error] Project1.dpr(21): E2010 Incompatible types: 'Integer' and 'procedure, untyped pointer or untyped parameter'

Ну ладно, возможно при замене операции i + 1 на операцию inc(i) действительно может возникнуть несоответствие типов. В ява инкремент встроен, поэтому там возникла другая ошибка: при замене в рекурсии i + 1 на i++, сначала много раз вывелся 0-вой элемент массива, а затем произошло переполнение стека:
Код

Exception in thread "main" java.lang.StackOverflowError

Конечно, при вставке в рекурсивный вызов i++ вместо i + 1, изменяется само значение i, и, скорее всего, в этом все дело, но если заменить i++ на ++i, программа опять таки заработает нормально. Я понимаю разницу между i++ и ++i, но не совсем понимаю, как это работает в рекурсии. Буду очень благодарен, если кто-нибудь мне доходчиво объяснит.
Спасибо!


--------------------
В действительности всё совсем не так, как на самом деле
PM MAIL   Вверх
FewG
Дата 4.1.2012, 13:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 23.11.2010

Репутация: нет
Всего: нет



Цитата(Pawl @ 4.1.2012,  11:35)
Конечно, при вставке в рекурсивный вызов i++ вместо i + 1, изменяется само значение i, и, скорее всего, в этом все дело, но если заменить i++ на ++i, программа опять таки заработает нормально. Я понимаю разницу между i++ и ++i, но не совсем понимаю, как это работает в рекурсии. Буду очень благодарен, если кто-нибудь мне доходчиво объяснит.
Спасибо!

Здесь как раз дело в разнице между i++ (постинкремент) и ++i (преинкремент). С i++ код работает не верно, ведь при вызове

Код
printing(x, i++)

Методу передается 0, ибо int i не был еще инкрементирован -> значит для следующего вызова 

Код
printing(x, i++)


i будет всё ещё равен 0 и так далее пока стек не будет переполнен.

С преинкрементом другое дело, перед тем как передать значение int i, оно будет увеличенно на 1.
PM MAIL   Вверх
Pawl
Дата 4.1.2012, 14:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 649
Регистрация: 22.4.2008
Где: Витебск

Репутация: 7
Всего: 28



Цитата

Здесь как раз дело в разнице между i++ (постинкремент) и ++i (преинкремент)

Спасибо, я, в принципе, так и думал.

Добавлено через 26 секунд
Тема закрыта


--------------------
В действительности всё совсем не так, как на самом деле
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.2102 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.