Calcular longitud de cadena C++ (punteros)

Iniciado por Bob1098, 15 Septiembre 2014, 16:51 PM

0 Miembros y 1 Visitante están viendo este tema.

Bob1098

Cita de: do-while en 17 Septiembre 2014, 20:54 PM
¡Buenas!

Esta función es muy sencilla también:

int longitud(char *s)
{
    if(!(*s))
        return 0;

    return 1 + longitud(s + 1);
}


¡Saludos!

PD: o con un cuerpo de una sola línea: XD

int longitud(char *s)
{
    return (*s) ? 1 + longitud(s + 1) : 0;
}


Impresionante, ahora me entero que puedes devolver la función en si jaja. Eso si que es optimizar un código.

Gracias, y un saludo.

eferion

Cita de: Bob1098 en 18 Septiembre 2014, 16:40 PM
Eso si que es optimizar un código.

Depende del baremo en que te bases a la hora de definir una optimización:

* Si para ti optimizar es reducir el código de la función, perfecto, esta función es más óptima.
* Si optimizar es sinónimo de velocidad, has de saber que una función recursiva es más lenta que un bucle. Además la recursividad, a diferencia de los bucles, tiene un límite dado por la pila... si te pasas el programa casca.

Con esto no intento desmerecer el ejemplo de do-while, el cual funciona perfectamente, sino comentarte los riesgos de aplicar recursividad a todo.

Además, ten en cuenta que este ejemplo no usa aritmética de punteros.

do-while

#12
¡Buenas!

Cierto lo que ha dicho eferion. Cuando utilizas una función, y dentro de esta haces una llamada a la misma función estas utilizando recursividad. La recursividad la puedes aplicar cuando tienes un problema del que conoces una solución básica y en el que si no te encuentras en esos "casos base", puedes realizar una llamada a la misma función con unos parámetros que ofrecen una solución más sencilla en cada llamada. Por ejemplo en este caso sé cuando una cadena tiene tamaño cero. Así que si no tengo una cadena sin caracteres, hago una llamada con la cadena que tenía en un principio, pero empezando desde el segundo caracter, y al valor devuelto le tendré que sumar uno por el caracter que he eliminado.

Lo malo de esto es que, como ya te han dicho, puedes llenar la pila del programa. La pila es una parte de la memoria del programa donde se guardan las llamadas a las funciones. Si mal no recuerdo, cuando tu llamas a una función lo primero que haces en la pila es reservar espacio para el valor que devuelve la función. Luego se almacena la dirección de memoria en la que está la siguiente instrucción a la llamada, se reserva espacio para las variables locales de la función y por último se incluye el código de la propia función. Cuando aplicas recursividad, si ésta tiene muchos niveles (muchas llamadas sucesivas a la propia función sin que haya un retorno), puedes llegar a llenar la pila, ya que el proceso descrito se lleva a cabo con cada llamada, y tu programa se detendrá o recibirás algún mensaje de error del sistema o vete tu a saber lo que puede pasar.

¡Saludos!
- Doctor, confundo los números y los colores.
- Vaya marrón.
- ¿Marrón? ¡Por el culo te la hinco!

Bob1098

Cita de: do-while en 17 Septiembre 2014, 20:54 PM
¡Buenas!

Esta función es muy sencilla también:

int longitud(char *s)
{
    if(!(*s))
        return 0;

    return 1 + longitud(s + 1);
}


¡Saludos!

PD: o con un cuerpo de una sola línea: XD

int longitud(char *s)
{
    return (*s) ? 1 + longitud(s + 1) : 0;
}


Me puse a revisar antiguos mensajes y me di cuenta de que no había leído tu respuesta (una lástima por que me parece la función más sencilla y efectiva de todas). Dicho esto, no comprendo muy bien como funciona, solo se que utiliza la recursividad y el if "simplificado". Podrías explicarme un poquito que es lo que hace exactamente?

Bob1098

Acabo de comprenderlo, impresionante optimización =D