Щоб відповісти на ваше конкретне питання: Ні, з точки зору вивчення мови, рекурсія не є особливістю. Якщо ваш професор справді закрепив вам позначки за використання "функції", яку він ще не вчив, це було неправильно.
Читаючи між рядками, одна з можливостей полягає в тому, що, використовуючи рекурсію, ви уникали коли-небудь використовувати функцію, яка повинна була бути результатом навчання для його курсу. Наприклад, можливо, ви взагалі не використовували ітерацію, або, можливо, ви використовували лише for
петлі замість обох for
і while
. Загальним є те, що завдання має на меті перевірити вашу здатність робити певні речі, і якщо ви уникаєте їх робити, ваш професор просто не може надати вам знаки, відведені для цієї функції. Однак якщо це справді було причиною ваших втрачених оцінок, професор повинен сприймати це як власний досвід навчання - якщо демонстрація певних результатів навчання є одним із критеріїв завдання, що має бути чітко пояснено студентам .
Сказавши це, я погоджуюся з більшістю інших коментарів та відповідей, що ітерація - це кращий вибір, ніж рекурсія тут. Є кілька причин, і хоча інші люди певною мірою торкалися їх, я не впевнений, що вони повністю пояснили думку, що стоїть за ними.
Стек переповнення
Більш очевидним є те, що ви ризикуєте отримати помилку переповнення стека. Реально, написаний вами метод є малоймовірним, що він фактично призведе до цього, оскільки користувачеві доведеться багато разів вводити неправильний вклад, щоб насправді викликати переповнення стека.
Однак слід пам’ятати про те, що не лише сам метод, а й інші методи, що знаходяться вище або нижче в ланцюзі викликів, будуть знаходитись у стеку. З-за цього випадкове поглинання наявного простору стеку - це досить нечесна річ для будь-якого методу. Ніхто не хоче постійно турбуватися про вільний простір стеків кожного разу, коли вони пишуть код через ризик того, що інший код міг би без потреби використовувати його багато.
Це частина більш загального принципу в розробці програмного забезпечення, що називається абстракцією. По суті, коли ви телефонуєте DoThing()
, все, що вам потрібно буде подбати, - це те, що робиться. Вам не доведеться турбуватися про деталі впровадження того, як це робиться. Але жадібне використання стека порушує цей принцип, тому що кожен біт коду повинен турбуватися про те, скільки стека можна сміливо припускати, що він залишив його за кодом в інших місцях ланцюжка викликів.
Читабельність
Інша причина - читабельність. Ідеал, до якого повинен прагнути код, - це читати людський документ, де кожен рядок просто описує, що він робить. Скористайтеся цими двома підходами:
private int getInput() {
int input;
do {
input = promptForInput();
} while (!inputIsValid(input))
return input;
}
проти
private int getInput() {
int input = promptForInput();
if(inputIsValid(input)) {
return input;
}
return getInput();
}
Так, це обоє працюють, і так, вони обоє досить легко зрозуміти. Але як можна описати два підходи англійською мовою? Я думаю, це було б щось на зразок:
Я запрошую ввести, поки введений не буде дійсним, а потім поверну його
проти
Я підкажу про введення, тоді, якщо введення дійсне, я поверну його, інакше я отримаю вклад і поверну результат замість цього
Можливо, ви можете придумати дещо менш незграбне формулювання для останнього, але я думаю, ви завжди знайдете, що перше - це більш точний опис, в принципі, того, що ви насправді намагаєтеся зробити. Це не означає, що рекурсія завжди менш читабельна. У ситуаціях, коли він світить, як, наприклад, обхід дерева, ви могли б робити такий самий вид паралельного аналізу між рекурсією та іншим підходом, і ви майже напевно знайдете, що рекурсія дає код, який чіткіше самоописується, рядок за рядком.
Окремо це обидві точки. Це дуже малоймовірно, що це дійсно призведе до переповнення стека, а посилення читабельності незначне. Але будь-яка програма буде сукупністю багатьох цих невеликих рішень, тому навіть якщо вони відокремлені, вони не мають великого значення, важливо вивчити принципи їх правильності.