2016-06-15 4 views
-1

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

int main() { 
    printf("Hello world") ; 
    main ; 
} 

отпечатки компилятора «Hello World», , но когда у меня есть основной() вместо основной, он печатает неоднократно «Привет мир».

+2

@JoulinRouge Этот о-так-умный комментарий не объясняет _difference_ между двумя способами использования идентификатора 'main', который, кажется, является реальным вопросом здесь. –

+1

Например, это может помочь с правильными правильными ответами ниже: C позволяет утверждению быть простым выражением - то, что оценивается, но не имеет никакого влияния на состояние. Современные компиляторы обычно выдают предупреждение. – Tommy

+0

@underscore_d только что отправил сообщение «вы имели в виду: рекурсия». разница уже объяснена. Вы хотите, чтобы я удалил его? – JoulinRouge

ответ

2

main(); вызовет функцию рекурсивно (и, в конечном счете, выйдет из-за переполнения стека, если ваш компилятор не усовершенствовал рекурсию в цикле).

main является выражение со значением, равным адресу функции main(). Это не-op, но, тем не менее, синтаксически корректно.

(Обратите внимание, что поведение вызова main из себя в C++ не определено, но действует в С. Опуская возвращаемое значение из main также хорошо определены в C: 0 предполагается).

+0

Опускание возвращаемого значения 'main' приводит к тому, что' 0' также предполагается в C++, так как он принимает это (как различные, но не _all_, другие вещи) из C99. Я не понял, что они отличались по позициям в рекурсии в 'main()' ... не то, что я когда-либо захочу использовать это в любом случае! –

5
int main() { 
    printf("Hello world") ; 
    main ; 
} 

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

int main() { 
    printf("Hello world") ; 
    main() ; 
} 

В этом коде используется «основная рекурсия». Функция main() вызывается внутри main(). Этот рекурсивный вызов будет продолжаться бесконечно, и он может упасть где-нибудь, когда стек закончится, или он может идти до тех пор, пока вы не остановитесь с помощью Ctrl + C или что-то еще, если компилятор достаточно умен, чтобы преобразовать эту хвостовую рекурсию в простой цикл.

+0

Я бы добавил, что достойный компилятор должен предупредить в первом случае: _warning: оператор без эффекта_ – LPs

+2

@LPs: для этого потребуется включить предупреждения. Что-то новичок, как правило, избегают, потому что они «получают слишком много раздражающих сообщений» ...: - ((- Честно говоря, я получил именно такое объяснение от ученика! – Olaf

+0

@Olaf Трудно поверить, правильно? Я отмечаю, когда моя программа генерирует никаких предупреждений. Вернее, когда единственным предупреждением, которое он генерирует, является то, что один неверный диагноз из-за ошибки 'g ++' ... –

1

Это потому, что:

main() 

является вызов метода. Вы рекурсивно вызываете основную функцию повторно. Это будет выполняться до тех пор, пока не будет переполнен стек вызовов.

main 

Является указателем на функцию, поэтому вы не очень много делаете на этой линии. Функция выходит после печати «Hello World» один раз.

0

main является указателем на функцию, тогда как main() является вызовом функции.

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

Смежные вопросы