О выводе последовательности чисел через рекурсию

Не могу понять как работает эта функция в коде ниже. Как так получается что - при (n-1), где, например, n=5, - программа выводит 0,1,2,3,4,5 , а не 5,4,3,2,1 что было бы логичнее?
Даже var_dump() не помогло понять.

<?php
//Функция, которая будет выводить на экран целые числа от 0 до переданного значения.

function numbers(int $x) {
    if ($x == 0) {
        echo $x;
        return;
    }
    var_dump($x);
    numbers($x - 1);
    echo ', ' . $x;
    var_dump($x);
}
numbers(5);

//int(5) int(4) int(3) int(2) int(1) 0, 1int(1) , 2int(2) , 3int(3) , 4int(4) , 5int(5)

Alex-neo 21.05.2020 в 22:50

Ответы (1)


Здравствуйте! Вставлю свои пять копеек.
Когда Вы вызываете функцию внутри самой себя (рекурсия),

function numbers(int $x) {
    if ($x == 0) {
        echo $x;
        return;
    }
    numbers($x - 1);//функция вызывает саму себя (рекурсия)
    echo ', ' . $x;
}

то код в вызываемой функции будет выполняться только до следующего вызова функции.
Т.е. вызванная функция будет выполнять следующие действия:

  1. Проверка на равенство аргумента нулю
    if ($x == 0) {
    echo $x;
    return;
    }
  2. Вычисление нового аргумента ($x - 1).
  3. Переход к пункту 1.

При этом после каждой рекурсии происходит сохранение результата, а именно ($x - 1)
Когда выполнится условие окончания рекурсий,

if ($x == 0) { // условие верно
    echo $x;
    return;
}

тогда выводится,

if ($x == 0) {
    echo $x;// отработает эта инструкция
    return;
}

далее срабатывает

if ($x == 0) {
    echo $x;
    return; // отработает эта инструкция
}

И потом из памяти машина начинает выгружать результат каждой рекурсии (т.е результат этого выражения ($x - 1)), начиная с последней рекурсии.
И далее выполнять код, который идет после вызова функции.

echo ', ' . $x;

Отсюда вывод результата:
Отрабатывает это:

if ($x == 0) {
    echo $x;// отработает эта инструкция. Результат 0
    return;
}

алее выгрузка результатов каждой рекурсии и выполнение кода, который идет после вызова функции самой себя:

echo ', ' . $x;// получае после каждой выгрузки 1,2,3,4,5

Отсюда правило (гуру могут поправить):

  • при рекурсии (вызов функцией себя внутри себя) вызываемая функция будет выполнять код, который идет до ее вызова.
  • при выполнении условия для вывода результат - функция выводит результат каждой рекурсии, начиная с последней.
d.solodov 24.05.2020 в 09:55

Добавить новый ответ