Рекурсия
Напишите метод с именем down, который принимает один int с именем n. Если n равен 0 или меньше, остановитесь голым return;. Иначе напишите n, затем вызовите down(n - 1) изнутри того же метода. Из Main вызовите down(3);. Экран должен показать три строки: 3, затем 2, затем 1. Метод продолжает вызывать себя с меньшим числом, пока стоп не завершит цепочку. Именно этот самовызов со стопом — то, чему учит эта страница. Оставьте публичный класс с именем Pine.
Метод, который вызывает сам себя
На странице области видимости mark выполнился один раз и закончился. Здесь down выполняется, затем запускает ещё один down с новым аргументом, пока первый вызов ещё не полностью завершён. У каждого вызова свой n. Цепочка заканчивается только когда вызов попадает в стоп.
Откройте файл Pine. Имя класса остаётся Pine. Эта страница не переименовывает тип. Удалите любой остаток демо mark, если такая форма — всё, что ещё есть в Main. Удалите любой остаток paint. Удалите любую строку ReadLine. В файле, который вы оставляете, нет ожидания ввода.
Вне Main, но всё ещё внутри фигурных скобок класса, напишите static void down(int n). На этой странице оставьте void: каждый шаг пишет, и через типизированный return ничего возвращать не нужно. Стоп использует return; без значения — он лишь завершает этот вызов. Сохраните файл перед запуском. Полная первая программа — в следующем блоке.
Файл, который вы оставляете
Это версия, которую вы запускаете первой. Main держит один вызов. down держит стоп, строку записи и самовызов.
using System;
public class Pine
{
public static void Main()
{
down(3);
}
static void down(int n)
{
if (n <= 0)
{
return;
}
Console.WriteLine(n);
down(n - 1);
}
}
Читайте сверху. using System; готовит короткие имена. public class Pine называет тип. public static void Main() — место, где среда выполнения начинает работу. Вызов down(3) входит с n, равным 3. Это больше 0, поэтому метод пишет 3, затем вызывает down(2). Второй вызов пишет 2, затем вызывает down(1). Третий вызов пишет 1, затем вызывает down(0). Вызов с 0 попадает в n <= 0 и возвращается без записи. Цепочка заканчивается. Три строки на экране: 3, затем 2, затем 1.
Запустите через dotnet run. Программа пишет три строки и останавливается. Она не ждёт, пока вы что-то наберёте. Если dotnet run ждёт, в файле всё ещё есть ReadLine. Удалите эту строку и оставьте down(3); плюс метод down выше. Экран показывает 3, затем 2, затем 1. Если экран показывает только 4, всё ещё выполняется остаточный вызов mark(4). Если экран показывает буквы down, в строке записи есть кавычки: Console.WriteLine("down");. Не переустанавливайте .NET SDK из‑за экрана с неверными строками.
Пройдите один полный запуск по порядку. C# начинает с Main. Вызов down(3) входит с n, равным 3. Это больше 0, поэтому метод пишет 3, затем вызывает down(2). Второй вызов пишет 2, затем вызывает down(1). Третий вызов пишет 1, затем вызывает down(0). Вызов с 0 попадает в n <= 0 и возвращается без записи. Цепочка заканчивается. Экран сохраняет три написанные строки.
Каждый из этих вызовов — отдельный проход через тот же текст метода. У первого прохода ещё есть работа после того, как он запустил down(2) — а именно завершение после возврата внутреннего вызова. Вы не пишете четыре разных имени метода. Вы пишете один метод и позволяете меньшему аргументу нести прогресс к стопу.
Если сменить старт на down(2);, экран должен показать 2, затем 1. Тело метода остаётся тем же; меняется только первый аргумент, поэтому цепочка короче. Старт с down(4); должен показать четыре строки: 4, 3, 2, 1. Снова тело не меняется; только Main выбирает первое значение.
Поставьте стоп первым
Стоп нужно проверять до строки записи и до самовызова. Если писать сначала и никогда не проверять n, или всегда вызывать down(n) с тем же значением, программа не завершится. На этой начальной форме держите блок if (n <= 0) вверху метода.
using System;
public class Pine
{
public static void Main()
{
down(2);
}
static void down(int n)
{
if (n <= 0)
{
return;
}
Console.WriteLine(n);
down(n - 1);
}
}
Это второй файл. Он учит тому же телу с более коротким стартом. Запустите dotnet run. Экран показывает 2, затем 1. Стоп по‑прежнему завершает цепочку, когда n достигает 0. Написание down(n) вместо down(n - 1) снова и снова отправляет то же число. Тогда программа может работать, пока система её не остановит. Меньший аргумент — часть идеи: каждый вызов должен двигаться к стопу.
Думайте о стопе как о двери выхода. Строка записи — работа на этом шаге. Самовызов — следующий шаг. Если двери нет, каждый шаг открывает ещё один шаг без конца. Если следующий шаг использует тот же n, вы никогда не идёте к двери. Обе ошибки выглядят по‑разному в исходнике, но обе отказываются чисто завершиться на этой начальной форме. После того как увидели 2, затем 1, верните сохранённый файл с down(3), если это форма, которую хотите оставить.
Цепочка вызовов рядом с экраном
Прочитайте один стартовый вызов рядом со строками, которые он даёт. Каждая строка таблицы — один визит к down, который ещё пишет.
📊 down call chain for down(3)
| Call | Value of n | Screen line |
|---|---|---|
first down(3) |
3 |
3 |
then down(2) |
2 |
2 |
then down(1) |
1 |
1 |
then down(0) |
0 |
(no line — stop) |
Частая путаница — оставить стоп без внимания. Тогда каждый вызов пишет и снова вызывает себя вечно. Другая путаница — писать после рекурсивного вызова вместо того, чтобы писать до него. На этой странице строка записи идёт первой, поэтому экран считает вниз. Если перенести Console.WriteLine ниже down(n - 1), порядок строк меняется — для обратного отсчёта, показанного здесь, держите строку записи выше самовызова.
Область видимости с предыдущей страницы всё ещё важна в малом: n каждого вызова — параметр именно этого вызова. n внешнего вызова не переписывает сам себя, когда работает внутренний. У внутреннего вызова отдельный n. Когда внутренний возвращается, внешний продолжается со строки после самовызова — и на этой странице это просто конец метода.
Остаток демо mark может сидеть в том же файле и путать экран, если Main всё ещё вызывает mark. Очистите Main до down(3); или down(2);, пока учите эту страницу. Не вкладывайте down внутрь фигурных скобок Main. Методы сидят внутри класса, рядом с Main.
Написание Console.WriteLine("down"); в Main пишет слово down. Оно не запускает цепочку. Держите down(3);, когда нужны три строки обратного отсчёта.
Ещё одна форма: стоп ничего не пишет
Вы уже видели, что вызов с 0 тихо возвращается. Можно также потренировать стартовое значение 1. Экран должен показать одну строку: 1. Затем следующий вызов — down(0), который останавливается.
using System;
public class Pine
{
public static void Main()
{
down(1);
}
static void down(int n)
{
if (n <= 0)
{
return;
}
Console.WriteLine(n);
down(n - 1);
}
}
Это третий файл. Запустите dotnet run. Экран показывает одну строку: 1. То же тело метода покрывает down(3), down(2) и down(1). Меняется только первый аргумент в Main. Для этой начальной страницы этого достаточно. Более глубокие идеи вроде возврата суммы из рекурсии ждут следующих курсов; здесь цель — самовызов, меньший аргумент и стоп.
Если экран вообще ничего не показывает, проверьте, не вызывает ли Main всё ещё что‑то другое, или не неверен ли тест стопа — например if (n >= 0) остановится до любой записи, когда вы стартуете с положительным n. Держите n <= 0 как тихий выход и положительный старт в Main, чтобы хотя бы одна строка могла появиться.
Вы можете написать down(int n), остановиться когда n равен 0 или меньше, написать n, затем вызвать down(n - 1). Из Main один вызов запускает всю цепочку. Экран показывает строки обратного отсчёта. Метод, который никогда не движется к стопу, не завершается. Следующая страница — classes, где вы начинаете строить типы с полями за пределами этих страниц о static-методах.
Экран держит обратный отсчёт
Файл, который вы оставляете, пишет 3, затем 2, затем 1, когда Main вызывает down(3);. Самовызов внутри down, и буквы down не на экране как печатная метка, если вы не взяли их в кавычки. Вложение down внутрь Main — не та форма, которую строит этот урок.
🧠 Проверьте Свои Знания
Проверьте Свои Знания
Бросьте себе вызов с помощью этой интерактивной викторины и узнайте, насколько хорошо вы понимаете тему
📝 Инструкции
- Внимательно прочитайте каждый вопрос
- Выберите лучший ответ на каждый вопрос
- Вы можете пересдавать тест столько раз, сколько захотите
- Ваш прогресс будет показан вверху