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

0

Поскольку у рекурсии есть дополнительные накладные расходы на толкание и всплывающие записи активации, можно ли избежать этого, когда дело доходит до использования констант?

Например, если у меня есть функция

void foo(int x) {
   int bar = x;
   fooAux(root);
}

fooAux(Root * root) {
   // Can I somehow do something with the variable bar here?
   // {Insert recursive code}
}

Я не уверен, есть ли какой-либо способ, кроме передачи бара в рекурсивную функцию, но это кажется ненужным, поскольку я уверен, что его значение не предназначено для изменения? Может быть, переход по ссылке может облегчить дело? Мысли, пожалуйста.

  • 1
    Вероятно, не самая важная проблема производительности, о которой нужно беспокоиться.
  • 0
    Как насчет добавления другого аргумента в fooAux() ?
Показать ещё 8 комментариев
Теги:
recursion

3 ответа

1
Лучший ответ

Вопрос не очень ясен, ссылаясь на "константу" в названии, но затем в примере кода с использованием переменной.

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

Все, что вам нужно сделать, это объявить переменную static:

struct Whatever {};

void foo( int x )
{
    static int bar;

    struct Aux 
    {
        static void foo( Whatever )
        {
            (void) bar;
        }
    };

    bar = x;
    Aux::foo( Whatever() );
}

Это хорошая идея? Нет, он пахнет преждевременной оптимизацией. Прирост скорости, если таковой будет, будет незначительным, а стоимость обслуживания может быть высокой.

  • 0
    В подтверждение этого, это не очень хорошая идея: наряду с преждевременной оптимизацией пахнет отсутствием повторного входа (что делает его не потокобезопасным, как вы упомянули, а также не сигнальным).
1

Вы можете сделать это, используя глобальную переменную, например: g_bar. Однако это делает вашу функцию не реентеративной или элегантной.

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

0

Если вы правильно поняли, что вы задаете вопрос не в основном о рекурсии, но и о области охвата. Возможно, вы также можете жить с ответом: может ли функция получить доступ к переменной, которая не передается в качестве параметра (и не определена локально)

Ответ на этот вопрос "да". Существует несколько вариантов:

  • Функция может иметь доступ к глобальным переменным. Во многих случаях это анти-шаблон и не совсем то, что вы ищете.
  • Существует очень интересная концепция закрытия, которая очень близка к тому, что вы ищете. Он позволяет функции получить доступ к "environmentemnt", в котором может находиться ваша переменная bar.

Однако в C++ нет замыканий, и я не знаю ни одного элегантного способа подражания закрытиям в C++. Также закрыты, где изобретаются по семантическим причинам (это дает программистам больше энергии), а не по соображениям производительности.

  • 1
    «в C ++ нет замыканий», - это жестко в лямбдах C ++ 11. Они не являются «правильными» замыканиями, так как они не продлевают жизнь переменных, которые они захватывают (так что вы не можете, например, вернуть лямбда-захват из функции, в которой она определена, что допускают некоторые / многие языки). Но они являются своего рода закрытием.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню