Когда будут бесконечные циклы и рекурсивные функции без условий остановки, в конце концов остановятся? - PullRequest
3 голосов
/ 31 июля 2011

Я слышал миф о том, что бесконечный цикл или рекурсивная функция без условия остановки остановится, когда «переполнение стека». Это правильно?

Например:

void call()
{
call(); 
} 

или

for(;;){;}

Действительно ли они остановятся, когда стек переполнится?

Обновление : Если оно действительно останавливается, могу ли я определить, через сколько рекурсивных вызовов?

Ответы [ 4 ]

5 голосов
/ 31 июля 2011

Ваш первый пример - рекурсивный вызов метода - каждый вызов call (в большинстве языков и сред) создаст новый фрейм стека, и в итоге вы выйдете из стека (вы получите условие переполнения стека) ).

Ваш второй пример не предусматривает рекурсивного вызова метода - это просто цикл. Не требуется создавать кадры стека, и стек не будет переполнен.

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

4 голосов
/ 31 июля 2011

Это действительно зависит от выбора языка.

В некоторых языках ваша бесконечная рекурсивная функция останавливается из-за переполнения стека в зависимости от условий системы или языка. Причина этого заключается в том, что многие реализации вызова и возврата функции выделяют новое пространство для каждого вызова функции, и, когда пространство исчерпано, программа завершится ошибкой. Однако на других языках (схема и различные уровни оптимизации gcc) эта программа будет работать вечно, потому что они достаточно умны, чтобы понимать, что могут повторно использовать пространство для каждого вызова.

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

Другими словами, это действительно зависит. На этот вопрос нет быстрых ответов.

Надеюсь, это поможет!

0 голосов
/ 01 августа 2011

«Обновление: если оно действительно останавливается, могу ли я определить, через сколько рекурсивных вызовов?»

Вы, безусловно, можете:

call(int n){
    print(n)
    call (n+1)
}

Тогда просто позвоните:

call(1)

Когда происходит переполнение стека, посмотрите на последний напечатанный номер. Это было количество вызовов методов, которые у вас были.

Надеюсь, это поможет!
* 1012 N.S. *

0 голосов
/ 31 июля 2011

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

p.s. Это не миф. Вы действительно можете попробовать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...