Pour répondre à votre question spécifique: Non, du point de vue de l'apprentissage d'une langue, la récursivité n'est pas une fonctionnalité. Si votre professeur vous a vraiment marqué pour avoir utilisé une "fonction" qu'il n'avait pas encore enseignée, c'était faux.
En lisant entre les lignes, une possibilité est qu'en utilisant la récursivité, vous avez évité d'utiliser une fonctionnalité qui était censée être un résultat d'apprentissage pour son cours. Par exemple, vous n'avez peut-être pas du tout utilisé l'itération, ou peut-être n'avez-vous utilisé que des for
boucles au lieu d'utiliser à la fois for
et while
. Il est courant qu'un devoir vise à tester votre capacité à faire certaines choses, et si vous évitez de les faire, votre professeur ne peut tout simplement pas vous accorder les notes réservées à cette fonctionnalité. Cependant, si cela était vraiment la cause de vos notes perdues, le professeur devrait considérer cela comme une expérience d'apprentissage qui lui est propre - si la démonstration de certains résultats d'apprentissage est l'un des critères d'une tâche, cela devrait être clairement expliqué aux étudiants. .
Cela dit, je suis d'accord avec la plupart des autres commentaires et réponses que l'itération est un meilleur choix que la récursivité ici. Il y a plusieurs raisons, et bien que d'autres personnes les aient abordées dans une certaine mesure, je ne suis pas sûr qu'elles aient pleinement expliqué la pensée qui les sous-tend.
Dépassements de pile
Le plus évident est que vous risquez d'obtenir une erreur de débordement de pile. En réalité, il est très peu probable que la méthode que vous avez écrite en mène à une, car un utilisateur devrait donner une entrée incorrecte plusieurs fois pour déclencher un débordement de pile.
Cependant, une chose à garder à l'esprit est que non seulement la méthode elle-même, mais d'autres méthodes supérieures ou inférieures dans la chaîne d'appels seront sur la pile. Pour cette raison, engloutir avec désinvolture l'espace disponible dans la pile est une chose assez impolie pour toute méthode. Personne ne veut avoir à s'inquiéter constamment de l'espace libre dans la pile à chaque fois qu'il écrit du code en raison du risque que d'autres codes en aient inutilement utilisé une grande partie.
Cela fait partie d'un principe plus général de la conception de logiciels appelé abstraction. Essentiellement, lorsque vous appelez DoThing()
, tout ce dont vous devriez vous soucier, c'est que la chose est faite. Vous ne devriez pas avoir à vous soucier des détails de mise en œuvre de la façon dont cela est fait. Mais une utilisation gourmande de la pile rompt ce principe, car chaque bit de code doit s'inquiéter de la quantité de pile qu'il peut supposer en toute sécurité qu'il lui a laissé par le code ailleurs dans la chaîne d'appels.
Lisibilité
L'autre raison est la lisibilité. L'idéal auquel le code devrait aspirer est d'être un document lisible par l'homme, où chaque ligne décrit simplement ce qu'il fait. Adoptez ces deux approches:
private int getInput() {
int input;
do {
input = promptForInput();
} while (!inputIsValid(input))
return input;
}
contre
private int getInput() {
int input = promptForInput();
if(inputIsValid(input)) {
return input;
}
return getInput();
}
Oui, ces deux méthodes fonctionnent, et oui, elles sont toutes les deux assez faciles à comprendre. Mais comment les deux approches pourraient-elles être décrites en anglais? Je pense que ce serait quelque chose comme:
Je vais demander une entrée jusqu'à ce que l'entrée soit valide, puis la retourner
contre
Je vais demander une entrée, puis si l'entrée est valide, je la retournerai, sinon j'obtiens l'entrée et je renvoie le résultat à la place
Peut-être pouvez-vous penser à un libellé un peu moins maladroit pour ce dernier, mais je pense que vous constaterez toujours que le premier sera une description plus précise, conceptuellement, de ce que vous essayez réellement de faire. Cela ne veut pas dire que la récursivité est toujours moins lisible. Pour les situations où cela brille, comme la traversée d'arbres, vous pouvez faire le même type d'analyse côte à côte entre la récursivité et une autre approche et vous trouverez presque certainement que la récursivité donne un code qui se décrit plus clairement, ligne par ligne.
Isolés, ces deux éléments sont de petits points. Il est très peu probable que cela conduise vraiment à un débordement de pile, et le gain de lisibilité est mineur. Mais tout programme sera une collection de bon nombre de ces petites décisions, donc même si isolément elles n'ont pas beaucoup d'importance, il est important d'apprendre les principes pour les faire correctement.