Duda sobre punteros en C

Iniciado por mester, 29 Julio 2015, 18:14 PM

0 Miembros y 2 Visitantes están viendo este tema.

mester

Tengo este programa:

#include<stdio.h>
#include<string.h>
int main(){
int x;
char nombres[10][40];
char *comp;
for(x=0;x<10;x++){
printf("Escribe un nombre:\t\tNombres: %d\n",x);
scanf("%s",&nombres[x][40]);
}
for(x=0;x<10;x++)
printf("Nombres: %s ",&nombres[x][40]);
printf("\nCual quieres saber\n");
scanf("%s",comp);
for(x=0;x<10;x++){
if(strcmp(nombres[x],comp)==0)
printf("Si que esta\n");
}
return 0;
}

Pero no tengo mucha idea de por qué debo declarar 'comp' como un puntero o por qué para escanear 'nombres' debo usar "&", o por qué 'comp' no lo recibo con un "&" en el scanf.
¿Un array es un puntero? Como va esto xd que se me dan muy mal los punteros
Justicia es dar a cada uno lo que se merece

joecarl

#1
Sí, los arrays funcionan de forma similar a los punteros. Es posible que el programa te funcione pero eso no quiere decir que esté bien, de hecho no lo está, ese programa tiene varios fallos.

El primero:
Código (cpp) [Seleccionar]
scanf("%s",&nombres[x][40]);
Ahí realmente deberias poner:
Código (cpp) [Seleccionar]
scanf("%s",nombres[x]);

Al igual que
Código (cpp) [Seleccionar]
printf("Nombres: %s ",&nombres[x][40]);
Que debería ser:
Código (cpp) [Seleccionar]
printf("Nombres: %s ",nombres[x]);

Por último, has declarado comp como un puntero a char, pero no estas reservando ningún espacio en memoria para almacenarla, sin embargo luego estas tratando de llenarla con scanf("%s",comp); con lo que estás escribiendo en zonas de memoria no reservadas. Para evitar esto declara comp como una cadena de caracteres: char comp[40];

EDIT: también puedes declarar comp como un puntero y luego reservar el espacio dinámicamente:

Código (cpp) [Seleccionar]

char *comp;
comp= malloc(40*sizeof(char));
//....
free(comp);

Pero en este caso no merece la pena ya que es un programa muy simple, solo quería mostrarte las diferentes posibilidades que hay.

mester

¿A qué te refieres con?
Cita de: joecarl en 29 Julio 2015, 21:15 PM
no estas reservando ningún espacio en memoria para almacenarla, sin embargo luego estas tratando de llenarla con scanf("%s",comp); con lo que estás escribiendo en zonas de memoria no reservadas.
Ya te digo que en punteros estoy muy verde y no tengo ni idea, llevo parte de la tarde intentando entenderlo y no sé, se me desmonta todo cuando hago un programa porque no entiendo que mierdas hago mal xd
Justicia es dar a cada uno lo que se merece

joecarl

A ver, cuando escribes
Código (cpp) [Seleccionar]
char *comp; estás reservando en memoria una sola variable que almacenará un puntero a char. Sin embargo tu necesitas reservar una variable para cada carácter, por eso es necesario crear un array
Código (cpp) [Seleccionar]
char comp[40]; De esa manera reservas 40 variables en memoria y tienes espacio para 40 caracteres (en realidad para 39, ya que el ultimo debe dejarse libre para el carácter nulo que indica la finalización de cadena).

El nombre de un array devuelve la dirección de memoria del primer elemento del array, es decir en este caso escribir comp es lo mismo que escribir &comp[0]

Al llamar a scanf("%s",comp) estás haciendo que los caracteres introducido por teclado se guarden en la memoria, la primera dirección de memoria en la que se guarda el primer carácter es la que le pasamos por parámetro, en este caso es la apuntada comp, el segundo carácter se guardara en esa misma direcion+1 y así hasta terminar.

Por tanto, si declaras comp como puntero y no reservas espacio en memoria y luego intentas llenar la memoria sin haberla reservado previamente puedes dar lugar a error o funcionamientos impredecibles.

mester

Cita de: joecarl en 29 Julio 2015, 22:33 PM
A ver, cuando escribes
Código (cpp) [Seleccionar]
char *comp; estás reservando en memoria una sola variable que almacenará un puntero a char. Sin embargo tu necesitas reservar una variable para cada carácter, por eso es necesario crear un array
Código (cpp) [Seleccionar]
char comp[40]; De esa manera reservas 40 variables en memoria y tienes espacio para 40 caracteres (en realidad para 39, ya que el ultimo debe dejarse libre para el carácter nulo que indica la finalización de cadena).

El nombre de un array devuelve la dirección de memoria del primer elemento del array, es decir en este caso escribir comp es lo mismo que escribir &comp[0]

Al llamar a scanf("%s",comp) estás haciendo que los caracteres introducido por teclado se guarden en la memoria, la primera dirección de memoria en la que se guarda el primer carácter es la que le pasamos por parámetro, en este caso es la apuntada comp, el segundo carácter se guardara en esa misma direcion+1 y así hasta terminar.

Por tanto, si declaras comp como puntero y no reservas espacio en memoria y luego intentas llenar la memoria sin haberla reservado previamente puedes dar lugar a error o funcionamientos impredecibles.
Ostias, gracias por tu tiempo, ya lo he entendido. Me estoy poniendo a tope con punteros y con lo que me has dicho ya lo he pillado jeje
Justicia es dar a cada uno lo que se merece