Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - MAFUS

#451
Yo iniciaría con un int llamado comparación a 0.
Un if comparando las alturas: si p1 es mayor 'comparación' a -1, si p2 es mayor 'comparación' a 1.
Si los dos son iguales 'comparación' seguirá a 0.
El segundo if: si 'comparación' vale 0:
Comparar el nombre. Como antes.
Si los dos nombres son iguales 'comparación' seguirá a 0.
El tercer if: si 'comparación' vale 0:
Compara los apellidos....
Supongo que ya has pillado el algoritmo pues se repite para todas las decisiones.

Al final devuelves 'comparación'.
#452
Así es, dereferencias el puntero antes de devolverlo.
Pero lo dicho. Lo recibe un puntero así que a partir de ese momento estás apuntando a la dirección 9 de la memoria.
#453
Como te han dicho no has devuelto el puntero sino el valor al que apunta. Eso ha pasado por añadir el asterisco a la variable del return. Todavía tienes ahí lío con los operadores de punteros.

Ahora cuidado porque ese valor devuelto ha sido recogido por el puntero p de main y eso quiere decir que ahora apunta a la dirección 9. El programa ha funcionado porque en printf le has pedido la dirección a la que apunta, de haber querido acceder a su contenido el S.O. te habría detenido.

Respondiendo a tu pregunta: cuando se llama a una función previamente se forma un marco de esa función en la pila dónde se encuentran los argumentos, la dirección de retorno y todas las variables locales y el puntero de pila se mueve al final de todo. Cuando una función termina se devuelve el puntero de pila al inicio de todo eso, eso es al final de la función llamante, por esa razón esa memoria que hay después ya no es accesible.

Aunque eso último es mentira. Si devuelves un puntero a una variable local sigues apuntando en esa dirección de memoria que el sistema ya no puede tocar. Es posible y se te permite trabajar allí y mientras no llames a otra función esa memoria no se va a tocar y te parecerá válido lo que hagas. En el momento que llames a otra función harás que la pila aloje datos allí perdiendo todo loque hayas hecho.

Y sí, si me pasas ese puntero a la función puede corromperse a sí misma pues tendrá un puntero que apunta a una zona indeterminada de su marco.
#454
El fred que hay en string_input es para su variable local str. Ahora subte fijas en esa misma función se dimensiona otra variable, ret_val, que no es liberada, sino que su dirección a la que apunta es pasada a str de main y por tanto ahora es main la encargada de liberar esa memoria.
#455
Es x=toupper(x), ídem con y.
#456
El segundo está mal hecho porque genera desbordamiento.
Devuelves un puntero (tipo de dato de 4 u 8 bytes, según arquitectura) sobre un char (tipo de dato de 1 byte).

Por qué funciona printf("%s",(&p)[1]);

Esta parte depende de como el compilador sitúa las variables en la memoria.
Te recomiendo que visites esto: http://www2.elo.utfsm.cl/~lsb/elo320/clases/c3.pdf

La explicación rápida es:
C ha situado ptr y p de forma contigua. Tu has hecho que ptr apunte a la cadena "hola" y mediante la función p también apuntará a "hola" (pero esa parte está mal hecha como ya te he dicho, hay desbordamiento por la diferencia de bytes entre los tipos de datos). Cuándo le das (&p)[1] a printf en verdad le estas dando ptr.

%s necesita un puntero, p es un puntero, se lo podrías así, sin florituras. Pero le has añadido [1], supongo que lo has hecho y te ha marcado error, eso es porqué lo has dereferenciado y accedido al segundo carácter. En este momento el programa ha transformado el código ascii de 'o' y se lo ha dado a printf para que busque en esa posición de memoria (la 111 en decimal) para que busque allí una cadena pero el S.O. no le ha dejado y por eso ha fallado.
Seguramente para arreglarlo habrás dicho 'pues transformo p en un puntero dándole incluyendo el operador de dirección (el &)'. Pero no has quitado el [1] y esto a generado lo siguiente:
Con & has conseguido la dirección de p, es decir su puntero, y al usar los corchetes lo has dereferenciado. Si hubieras usado (&p)[0] habrías conseguido p que se lo habrías pasado a printf y habría mostrado la cadena por p, pero al mover el offset 1 byte con el [1] (se ha movido 1 byte porqué p es un puntero a char) has apuntado a la variable ptr, que es contigua. Como se ha dereferenciado, por lo comentado antes, printf la ha aceptado y por el hecho de que apunta a la misma cadena parece que el programa ha funcionado.

En verdad lo que has tenido es mucha suerte. Por eso, y para evitarte estos errores e ir moviéndote a ciegas por el tema de los punteros léete el PDF que te he pasado.

P.D.: Siguiendo con lo que te dije el otro día sobre lo de editar los posts: Si hay respuesta de otra persona sigue en una respuesta nueva. Solo edita el mismo post si vas a añadir algo pero nadie te ha respondido.
#457
Unos pequeños cambios.

#include <stdio.h>

char* imprimir_cadena(const char *cadena2);

int main(){
    const char *ptr="hola";
    const char *p=imprimir_cadena(ptr);
    printf("%s", p); // cuando se imprimen cadenas no se usa asterisco
}

char* imprimir_cadena(const char *cadena2){ // nota que el tipo de dato devuelto es char*
    return cadena2; //el asterico * es opcional? No, no debe estar
}
#458
Bien, antes de nada y siguiendo las reglas del foro, no debe hacer publicaciones seguidas. Si no ha habido respuestas posteriores y quieres actualizar tu mensaje debes ir al botón 'editar' de tu último mensaje del hilo y allí añadir las novedades.

Respondiendo a tus preguntas:
1. Sí, se puede guardar la salida de getchar. Fíjate que aquí se hace while((c=getchar())!='\n') {

2. El título está bien

3. En el código que has apuntado es puntero doble porque guarda una lista de cadenas cuando en el último el que te he hecho solo guarda una única cadena.
#459
Este último que has puesto es una máquina de escribir. Lo que consigues por teclado lo sueltas por la pantalla. No hace nada más: no se puede guardar para usarlo después, tratarlo, modificarlo, en definitiva trabajar los datos. Tal como los consigues los sueltas.
#460
Sí, funciona como un malloc al pasarle null, pero si te fijas el realloc está en un bucle así que se necesita realojar el array. Por eso se pasa un null al principio, para que haga una primera adquisición tipo malloc pero a las siguientes trabaja como realloc. Por eso esa construcción.