За последние 24 часа нас посетил 20201 программист и 1078 роботов. Сейчас ищут 800 программистов ...

Механизм работы рекурсии

Тема в разделе "PHP для новичков", создана пользователем Donotstoptry, 10 июл 2016.

  1. Donotstoptry

    Donotstoptry Новичок

    С нами с:
    10 июл 2016
    Сообщения:
    6
    Симпатии:
    0
    Привет!
    Начал изучать php недавно. В одном из заданий курса нужно было написать функцию возведения числа в степень вида function($number, $power) используя рекурсию. В исходных материалах было похожее задание, только с факториалом. Механизм оттуда, но не совсем понимаю как это работает.
    Код (Text):
    1.  
    2. <?php
    3.                                 $num = 10;
    4.                                 $inv = 4;
    5.                                 function involve($num, $inv)
    6.                                 {
    7.                                     if($num === 0 && $$inv === 0)
    8.                                         return 'Недопустимое значение основания и показателя степени';
    9.                                     elseif ($inv === 1)
    10.                                         return $num;
    11.                                     else
    12.                                         return $num * involve($num, $inv - 1);
    13.                                 }
    14. ?>
    Непонятно, что происходит когда $inv становится равной нулю (и не понятно становится ли). Что заставляет функцию прекращать выполнение и возвращать конечный результат? Интересен сам механизм работы интерпретатора.
     
  2. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.230
    Симпатии:
    1.715
    Адрес:
    Молдова, г.Кишинёв
    Механизм такой: чтобы выход произошёл ты вместо запуска функции должен вернуть результат, тогда по цепочке вверх будет возвращён результат и дойдёт до верха и ты получишь данные которые вернула функция. Запусти отладку любой функции с рекурсией и посмотри в какой последовательности будет отрабатывать код.

    Отладка:
    https://netbeans.org/kb/docs/php/debugging_ru.html
    https://php.ru/forum/threads/howto-...i-po-shagam-i-s-kartinkami.58974/#post-474550
     
    Donotstoptry нравится это.
  3. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.548
    Симпатии:
    1.754
    Поэтому $inv нулём не станет. Но не отработан случай, когда $inv изначально 0 (т.е. надо вернуть единицу)
     
  4. Schrodinger

    Schrodinger Новичок

    С нами с:
    8 июн 2016
    Сообщения:
    40
    Симпатии:
    5
    интересный подход.
    функция глупа. думаю лучше так
    PHP:
    1. <?php
    2.  
    3.  
    4. function involve($num, $inv) {
    5.     if ( (string)$inv !== (string)(int)$inv )
    6.         return 'Недопустимое значение показателя степени';
    7.     $inv = (int)$inv;
    8.     if ( $inv < 0 )
    9.         return ($_=involve($num, -$inv))?1/$_:\INF;
    10.     if ( $inv === 0 )
    11.         return 1;
    12.     return $num * involve($num, $inv - 1);
    13. }
    14.  
    15. foreach(range(-100,100,0.1) as $num) {
    16.     foreach(range(-5,5,1) as $inv) {
    17.         $n = involve($num, $inv);
    18.         $o = pow($num, $inv);
    19.         $r = abs($n - $o);
    20.         if ( $n !== $o && $r > 0.00001 ) {
    21.             echo "$num ^ $inv ; $n need $o ! $r :: error\n";
    22.         }
    23.     }
    24. }
    http://sandbox.onlinephpfunctions.com/code/5e9e41e2f3e45f1a6766aa7bcf95191bddbd95a5
    --- Добавлено ---
    возможны ошибки
     
  5. Donotstoptry

    Donotstoptry Новичок

    С нами с:
    10 июл 2016
    Сообщения:
    6
    Симпатии:
    0
    foreach использовать не предполагается исходя из условий задачи, но все равно спасибо. Поясни пожалуйста что это: $_=involve($num, -$inv))?1/$_:\INF; в частности $_= и :\INF
     
  6. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.548
    Симпатии:
    1.754
    @Donotstoptry, $_ - это просто имя переменной, поскольку она почти не используется, автор решил не давать ей осмысленное имя. ? : - это тернарный оператор

    Конструкция основана на том, что операция = (присвоение) в php, как и в C, возвращает присвоенное значение. Получается, что конструкция
    PHP:
    1.  if ( $inv < 0 )
    2.        return ($_=involve($num, -$inv))?1/$_:\INF;
    отрабатывает возведение в отрицательную степень (x^(-n) = 1/ (x^n)). Сначала число возводится в аналогичную положительную степень involve($num, -$inv), записывается в переменную $_, и если в результате не 0 (т.е. истинное значение), то возвращается 1/$_, а если 0 - то бесконечность. Это всё симпатично, конечно, но ИМХО для учебной задачи - излишне. Вам таких условий не ставили.
     
    Donotstoptry нравится это.
  7. Donotstoptry

    Donotstoptry Новичок

    С нами с:
    10 июл 2016
    Сообщения:
    6
    Симпатии:
    0
    Спасибо! Очень доступно.
     
  8. Schrodinger

    Schrodinger Новичок

    С нами с:
    8 июн 2016
    Сообщения:
    40
    Симпатии:
    5
    нет там foreach.
    foreach там для проверки.