Solo tenía una duda en mi mente. La siguiente subrutina (para buscar un elemento, en una lista, por ejemplo) tiene una declaración de retorno al final:
list *search_list(list *l, item_type x) {
if (l == NULL) return(NULL);
if (l->item == x)
return(l);
else
return( search_list(l->next, x) );
}
No puedo obtener el significado de la declaración return al final (es decir, return search_list (l-> next, x)). Sería realmente útil si alguien pudiera explicar este concepto, utilizando el modelo de pila.
return
.return
hace. De hecho, en lenguajes funcionales (y algunos mixtos, como Scala)return
no es necesario : el valor de la función recursiva es el valor de su última expresión. ¡Simplemente escribirsearch_list(l->next, x)
sinreturn
hubiera funcionado en Scala! El significado de lareturn
declaración solo es obvio para los programadores con un trasfondo imperativo.Respuestas:
Una declaración de retorno devuelve un valor al llamante inmediato del marco de llamada de la función actual. En el caso de la recursividad, este llamador inmediato puede ser otra invocación de esa misma función.
En la mayoría de los idiomas, si no usa el valor de retorno de una función que llamó (recursivamente o no), ese valor de retorno se descarta o es un error diagnosticable. Hay algunos idiomas en los que el valor de retorno de la última llamada a la función se reutiliza automáticamente como el valor de retorno de la invocación de la función actual, pero no diferencian entre llamadas a funciones normales y recursivas.
Suponiendo que los valores de retorno no utilizados se descarten silenciosamente, si hubiera escrito el código de esta manera:
entonces
search_list
solo devolvería un valor definido para una lista vacía (NULL) o si el primer elemento coincide con el valor que está buscando. Tan pronto como la función entra en la llamada recursiva, no sabe cuál será el resultado, porque el resultado de la llamada recursiva se descarta.Además, promete devolver un valor de su función, pero tiene una ruta (la recursiva) donde no especifica qué valor devolver. Dependiendo del idioma que use, esto generalmente resulta en un diagnóstico obligatorio o en un comportamiento indefinido (que es la abreviatura de: cualquier cosa puede suceder y eso puede cambiar en cualquier momento sin previo aviso. No responsabilice a nadie más que a usted mismo si se arruina) tu presentación más importante). Hay algunas situaciones en las que puede parecer que el valor de retorno faltante funciona, pero eso puede cambiar la próxima vez que ejecute el programa (con o sin recompilación).
fuente
Dos cosas; Devolver la lista completa en el caso de que encuentre la "x" que está buscando no necesariamente garantiza el uso de la recursión, pero aparte de eso, considere lo siguiente:
Suponga que está buscando un valor de X = "diciembre", y su lista es el valor numérico de los meses del año, un puntero al mes siguiente y los elementos l-> en la lista son los nombres detallados de meses. (Enero, febrero, ..., diciembre). Necesita los tres retornos para los posibles resultados. El primero, return (NULL) es necesario si la lista no contiene la X que está buscando. El segundo, (return (l)) devuelve la lista, en este caso, informándole que encontró su "x". El último es donde entra en juego el modelo de pila. Las llamadas sucesivas a la función habrían actualizado las variables locales (específicamente, l-> ítems) como esta:
fuente