Есть ли способ ссылки на функцию, в которой вы находитесь в C? - PullRequest
5 голосов
/ 18 августа 2011

Я пишу функцию, которая просто ищет значения внутри таблицы. Можно ли вызвать эту функцию внутри себя? Я видел вещи о this и self и не совсем понимаю.

Ответы [ 4 ]

12 голосов
/ 18 августа 2011

Да, вы можете.Это называется рекурсия.

void foo(){
   foo(); //This is legal.
}

Конечно, вам нужно вернуться из нее, чтобы избежать бесконечных рекурсивных вызовов.Невозможность возврата приведет к переполнению стека.Вот лучший пример:

void foo(int n){
    if (n == 0)
        return;
    foo(--n);
}
5 голосов
/ 18 августа 2011

См. Рекурсия (информатика) (Википедия).

Пример вызова функции внутри функции:

# include<stdio.h>

int factorial(unsigned int number)
{
    if (number <= 1)
        return 1;
    return number * factorial(number - 1);
}

void main()
{
    int x = 5;
    printf("factorial of %d is %d",x,factorial(x));
}
2 голосов
/ 18 августа 2011

Другие ответили на ваш вопрос, но, поскольку он вам не чужд, вы можете прочитать о рекурсии и рекурсивных функциях.Есть некоторые ошибки, которые могут вас поймать, если вы не в курсе.

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

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

ДжошЛивз сказал, что рекурсия быстрее, но часто это происходит не из-за необходимости выделять стек роста и настраивать регистры.Если ваша функция выполняет два или более вызовов самой себя для вычисления своего результата, то итеративное решение всегда быстрее.

1 голос
/ 18 августа 2011

Обновление

Хорошо, я думал, что это «получение каждого значения функции».Как говорили другие авторы, это называется рекурсией.Несколько замечаний:

Рекурсия быстрее, чем итерация (у меня нет результатов тестов, но я провел их год назад на Intel Core i5 ).

//Iteration
function do_stuff(i)
{
    //BLABLAH
}

for (i = 0; i <5; i++) {
    do_stuff();
}

//Recursion
function do_stuff(int i)
{
    //BLABLAH
    if (i < 5) {
        do_stuff(i + 1);
    }
}
  • Вы можете выполнять рекурсию несколько раз, но вам нужно найти способ остановить рекурсию или ...
  • Если ваша рекурсия заходит слишком далеко (подумайте «Начало», еслимиллион ...), вы рискуете переполнить доступную память стека, просто введя ту же функцию в миллионный раз.
...