Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: snake_linux en 25 Agosto 2015, 14:07 pm



Título: Ayuda con punteros en C
Publicado por: snake_linux en 25 Agosto 2015, 14:07 pm
Hola a tod@s, como sabeis estoy aprendiendo C, ya se lo básico pero me he puesto a aprender punteros y estoy hecho un lio, no son pocas las veces que he intentado aprender punteros en C y no lo asimilo ni por a ni por b.

Lo básico de punteros más o menos lo se, se que los punteros se declaran con:

Código
  1. tipo *var;

ej:

Código
  1. int *p;

El caracter & delante de una variable se usa para hayar la dirección de memoria de dicha variable, para después, guardarla en un puntero, ej:

Código
  1. int *p;
  2. int a=5;
  3. p=&a;

Y también se que el caracter * sirve para hayar el valor de lo que apunta un puntero, por ejemplo
Código
  1. int *p;
  2. int a=5;
  3. p=&a;
  4. int b=*p;
  5. printf("el valor de b es: %d\n", b);

Hasta ahí llego, el problema lo tengo en cosas más avanzadas, como cuando leo la relación que hay entre punteros y arrays, no acabo de entenderlo, por ejemplo he escuchado que un array es un puntero pero ya digo no me queda del todo claro como manejarlos.

Por ejemplo, no veo la diferencia entre un

Código
  1. char nombre[10];

de un:

Código
  1. char *nombre;

¿Es lo mismo?

También, si me pudieran explicar un poco los punteros (quitando lo básico que he puesto arriba que se) se lo agradecería muchísimo.

Saludos.


Título: Re: Ayuda con punteros en C
Publicado por: ivancea96 en 25 Agosto 2015, 14:14 pm
Un array es un puntero. La diferencia es, que en evz de apuntar a 1 variable, apunta a un conjunto de variables, una delante de otra (en memoria).

Código
  1. char nombre[10];
  2. char *nombre;

¿Es lo mismo?

No, no lo es. El primero tiene 10 chars de memoria. El segundo, solo es un puntero.
A nivel práctico sí, ambos son punteros. Pero para utilizar el segundo como puntero, tienes que reservarle memoria:

Código
  1. char *nombre;
  2. nombre = (char*) malloc(sizeof(char) * 10);
Con eso, igualamos el puntero a una dirección de memoria que contiene 10 char.

Para acceder a cada uno, utilizas el operador []:
Código
  1. nombre[5] = 'C';

Si utilizas malloc para reservar memoria, luego tienes que liberarla:
Código
  1. free(nombre);


Título: Re: Ayuda con punteros en C
Publicado por: snake_linux en 25 Agosto 2015, 15:25 pm
Un array es un puntero. La diferencia es, que en evz de apuntar a 1 variable, apunta a un conjunto de variables, una delante de otra (en memoria).

No, no lo es. El primero tiene 10 chars de memoria. El segundo, solo es un puntero.
A nivel práctico sí, ambos son punteros. Pero para utilizar el segundo como puntero, tienes que reservarle memoria:

Código
  1. char *nombre;
  2. nombre = (char*) malloc(sizeof(char) * 10);
Con eso, igualamos el puntero a una dirección de memoria que contiene 10 char.

Para acceder a cada uno, utilizas el operador []:
Código
  1. nombre[5] = 'C';

Si utilizas malloc para reservar memoria, luego tienes que liberarla:
Código
  1. free(nombre);

Entonces, una vez que has reservado la memoria necesaria para el char *, la única diferencia entré eso y crear un array de la manera clásica de char nombre[valor] es que la primera forma, se hace con memoria dinámica, por lo que puedo liberar ese espacio cuando quiera y además puedo incluso (por lo que he leido investigando) redimensionarlo sin perder los datos que tenía. ¿ Es así ?.

Aparte de lo que he puesto que se en el post, y junto con esto, ¿ No hay nada más sobre punteros ? Es que estoy investigando por internet de allí y allá y como veo la info "a cachos" no me entero.

Saludos y gracias.


Título: Re: Ayuda con punteros en C
Publicado por: ivancea96 en 25 Agosto 2015, 15:45 pm
Los punteros realmente, solo es eso, un apuntador a una dirección de memoria. Luego los usas como veas.

Pero sí, en general, pasar variables por referencia, arrays y matrices.

Lo único eso, una matriz:
Código
  1. int **matriz;
  2. matriz = (int**) malloc(sizeof(int*) * 10);
  3. int i;
  4. for(i=0; i<10; i++)
  5.    matriz[i] = (int*) malloc(sizeof(int) * 10);
  6.  
  7. matriz[1][8] = 66;

Así obtendrías una matriz de 10x10 dinámica. Realmente es lo mismo que un array, pero jugando con tipos. Ya ahí usas los punteros como quieras.

Código
  1. int *****matriz;
Disfruta rellenándolo con una matriz de 5 dimensiones xD


Título: Re: Ayuda con punteros en C
Publicado por: snake_linux en 25 Agosto 2015, 16:54 pm
Los punteros realmente, solo es eso, un apuntador a una dirección de memoria. Luego los usas como veas.

Pero sí, en general, pasar variables por referencia, arrays y matrices.

Lo único eso, una matriz:
Código
  1. int **matriz;
  2. matriz = (int**) malloc(sizeof(int*) * 10);
  3. int i;
  4. for(i=0; i<10; i++)
  5.    matriz[i] = (int*) malloc(sizeof(int) * 10);
  6.  
  7. matriz[1][8] = 66;

Así obtendrías una matriz de 10x10 dinámica. Realmente es lo mismo que un array, pero jugando con tipos. Ya ahí usas los punteros como quieras.

Código
  1. int *****matriz;
Disfruta rellenándolo con una matriz de 5 dimensiones xD

No me ha quedado claro el código que me has puesto, si con la segunda linea ya reservas espacio para una matriz, ¿ Para que es ese for ?.

Gracas.

Saludos.


Título: Re: Ayuda con punteros en C
Publicado por: kr.chacacreker en 25 Agosto 2015, 17:18 pm
No me ha quedado claro el código que me has puesto, si con la segunda linea ya reservas espacio para una matriz, ¿ Para que es ese for ?.

Gracias.

Saludos.
Fijate
Código
  1. matriz = (int**) malloc(sizeof(int*) * 10);
lo que hace es reservar 10 punteros,el (int**) es un cast, una "conversión". Luego en
Código
  1. int i;
  2. for(i=0; i<10; i++)
  3.    matriz[i] = (int*) malloc(sizeof(int) * 10);
  4.  
para cada puntero reservado reserva 1 entero.

Eso jodido para quien no ha visto algo de ingeniería inversa ya que lo ves de otro modo, te recomiendo que pases un poco por los tutes de Introducción al ollydbg de ricardo narvaja, No explica punteros pero te das cuenta de algunas cosas por ej: que cada byte de memoria es apuntado por una dirección de memoria.


Título: Re: Ayuda con punteros en C
Publicado por: ivancea96 en 25 Agosto 2015, 18:08 pm
Una matriz, no es más que un puntero que apunta a un array de punteros.
Así que una vez reservada memoria para el array de punteros, hay que reservar memoria para cada puntero. Eso lo haces con el for.


Título: Re: Ayuda con punteros en C
Publicado por: snake_linux en 25 Agosto 2015, 18:12 pm
Una matriz, no es más que un puntero que apunta a un array de punteros.
Así que una vez reservada memoria para el array de punteros, hay que reservar memoria para cada puntero. Eso lo haces con el for.

Gracias por la aclaración, ya me has resuelto la duda, gracias :)


Título: Re: Ayuda con punteros en C
Publicado por: Mientras en 26 Agosto 2015, 00:17 am
Bueno, yo no soy de usar **, ya que no lo manejo muy bien  :-[

Como se almacena en memoria un array bidimensional ?. En uno unidimensional sé que es secuencial, y que puedo acceder mediante *(p) , *(p+1) ....






Título: Re: Ayuda con punteros en C
Publicado por: ivancea96 en 26 Agosto 2015, 01:15 am
Hay algo que no he comentado.

Los punteros son como se ha dicho, todo bien.

PERO:
Código
  1. int a[5][5];
  2. int b[10];

NO se guardan en memoria de la misma manera. Esas variables se guardan en la pila, mientras que las variables llamadas con "malloc()" se almacenan en el "heap". Además, la organización de los datos no es el mismo.

Pero bueno, simplemente saber que cuando creas "int a[5][6]" no es igual que "int **a".


Título: Re: Ayuda con punteros en C
Publicado por: Blaster en 26 Agosto 2015, 01:33 am
el problema lo tengo en cosas más avanzadas, como cuando leo la relación que hay entre punteros y arrays, no acabo de entenderlo, por ejemplo he escuchado que un array es un puntero pero ya digo no me queda del todo claro como manejarlos.

En esencia el nombre de un array no es un puntero mas bien es un identificador para el tipo del array, que al hacer referencia a la misma se realiza una conversión implícita a puntero (esto lo hace automáticamente el compilador) sucede cuando por ejemplo pasas el array como parámetro a una función


Título: Re: Ayuda con punteros en C
Publicado por: furciorifa en 26 Agosto 2015, 22:51 pm
Los punteros no son muy difíciles solamente hay que tener una libreta y dibujar cuadritos uno para el valor y otro para la memoria de la variable que contiene ese valor, he visto proyectos con punteros triples pero la verdad es pesado explicar, porque generalmente no entienden fácil sería más presencial la explicación para que domines punteros.


Título: Re: Ayuda con punteros en C
Publicado por: kondrag_X1 en 27 Agosto 2015, 15:50 pm
ami este tema de c también me interesa porque si mal no recuerdo los punteros también pueden recorres como un array.