Tengo algunas dudas sobre punteros en C/C++ y otras cosillas.

Iniciado por Gojira, 23 Febrero 2018, 19:55 PM

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

Gojira

A ver si alguien sabe resolvermelas.

Estoy leyendo el libro de Anaya de programación en C/C++, asi que hay como una mezcla de ambos, pero bueno.

Lo primero, en relación con los punteros. A ver si consigo entenderlos, porque la explicación me cuadra, pero luego cuando veo como se usan en ejemplos, se me descuadran.


Vale, el libro dice que los punteros son un tipo de variables que almacenan direcciones de memoria, concretamente almacenan el numero de la dirección de memoria, no la dirección en si. Asi que tenemos tres posibilidades.

Puede aparecer en el código:
*puntero = &variable; //Significaria que el puntero contiene el numero de la direccion en memoria de esa variable.
*puntero, sin mas, que se utiliza para referirse al valor de la variable cuyo numero de direccion se contiene en ese puntero.
Y por ultimo "puntero", sin mas, sin operadores, y sin asignaciones, que contiene el numero de direccion de la variable a la que apunta. Ok.

Pero luego, lo veo en la práctica y me encuentro esto.
Si no se entiende, intento subir una foto mejor.



Vale, se define el puntero p de tipo char.
Y luego, ¿se le asigna a p un contenido distinto a un numero de direccion en memoria de una variable con el "p = strtok(palabras, ",");" o contiene el numero de direccion del resultado que se obtenga de ejecutar la funcion strtok?¿Y si es asi, por que no hay un operador &? Directamente, ¿que es p, ahi, que esta haciendo, cual es su resultado? Porque luego hace un printf p, directamente, sin asterisco y sin nada que de acuerdo con lo que se explica en la definicion de puntero deberia imprimir en pantalla el numero de direccion de memoria de una variable, y no el valor de una variable. Me descoloca.



Por cierto, ¿como se hace en c++ para que la consola no se cierre de golpe al ejecutar un programa simple? Por ejemplo un printf sin mas, lo ejecuta y en un microsegundo se cierra. Lo ha ejecutado bien, pero se cierra. ¿se puede evitar? No me funciona getchar, getche y esas cosas.

Tenia varias dudas chorra mas, pero no me acuerdo.

ivancea96

Empezaré diciendo que strtok es una función bastante especial. Si quieres verla en profundidad, aquí una referencia: http://www.cplusplus.com/reference/cstring/strtok/
Esta función retorna un puntero al comienzo del próximo "token". En definitiva, un puntero a char, es decir, una cadena.
strtok retorna "char*", y p es de tipo "char*", así que se lo asignas igual que asignarías un "int" a otro "int".
Luego, se imprime en pantalla el valor y no la dirección. Eso es así porque en el primer argumento de printf se le pasa la cadena, y dentro de esta hay un "%s". %s coge un char* y lo muestra como una cadena. Para ver su fdirección de memoria, podría ponerse %d, o %x para verlo en hexadecimal.

Con respecto a lo de la consola en C++, podrías usar "cin.get();", que espera un caracter. Eso sí, si previamente has utilizado "cin >> xxx" es probable que no te funcione, y tengas que poner 2 veces "cin.get();".

Otra opción sería poner "system("pause");", que sería una llamada a "pause" en la consola.

NotHaveOne

Vos entendés bien qué hace el puntero, tu confusión viene de no saber qué es strtok. Según  cplusplus (te invito a mirar la función ahí), la función está declarada así:

char * strtok ( char * str, const char * delimiters );

Es decir que devuelve un puntero, por eso no se necesita el "&". Porque estás asignando un puntero a otro.


MAFUS

Muy buenas las explicaciones de los compañeros del foro, pero voy a añadir mi granito de arena:

Te has equivocado al decir:
Citar*puntero = &variable; //Significaria que el puntero contiene el numero de la direccion en memoria de esa variable.

Eso solo serviría en un caso que, por ahora no deberías entrar, que son punteros a punteros. Para ti esa línea debe ser:
puntero = &variable; //Significaria que el puntero contiene el numero de la direccion en memoria de esa variable.

Nótese la falta del asterisco.

Ahora varias cosas:
El operador & se usa para conseguir la dirección de variables y es lo utilizado para pasarle la dirección de una variable a un puntero.

Como bien sabes un puntero es un tipo de dato, como int, double, char, etc, y por tanto las funciones pueden devolver punteros (direcciones de memoria). Una de estas funciones es strtok, pero también hay otras como strstr, strchr, strcpy, etc. Cuando las veas imagina que a tu variable puntero le acabas de pasar la dirección de comienzo de una cadena.

Por otra parte las cadenas para tí deben ser un puntero a su primer carácter, de hecho C las trata así. scanf, por ejemplo, espera punteros a partir del segundo argumento, por ejemplo cuando consigues un número:
scanf("%i", &numero);
puedes ver que a scanf se le pasa la dirección de la variable numero así puede meter dentro de esa variable el número adquirido. Pero como ya he dicho una cadena es un puntero y en scanf para conseguir una cadena se hace así:
scanf("%s", cadena);
pues cadena ya es un puntero declarado como char *cadena.
De igual forma en printf cuando se usa %s también espera una cadena, eso es un puntero a char* y por tanto no hay que dereferenciar dicho puntero, ya lo hace internamente la función.

Es cierto que te va a costar dominar los punteros, pero cuando lo hagas te preguntarás cómo los otros lenguajes de programación pueden vivir sin estos tipos de datos tan versátiles.

Gojira

Muchas gracias, ahora si lo he entendido. No habia ni sospechado que lo que manejaban esas funciones eran punteros. Creo que la explicacion básica del libro es buena para entender el concepto de puntero en si, pero se queda corto, ya que no profundiza y no muestra las posibilidades de los punteros y los tipos de puntero que hay. Por ejemplo cuando hablais de puntero a char, puntero a puntero, o yo he visto tambien puntero a FILE. ¿Sabeis de alguna referencia buena para profundizar en el tema de los punteros? Estoy esperando a que me llegue el C++ Primer, pero quedan un par de semanas.

MAFUS

Te recomiendo esto, donde además de explicar los punteros también explica cómo hace uso de la memoria C: http://www2.elo.utfsm.cl/~lsb/elo320/clases/c3.pdf