Autor Tema: punteros un dolor de cabeza  (Leído 1722 veces)

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

Desconectado japifer_22

  • PIC18
  • ****
  • Mensajes: 405
punteros un dolor de cabeza
« en: 29 de Julio de 2019, 16:45:59 »
Hola a todos,
escribo en esta oportunidad por que estoy teniendo problemas al trabajar con punteros. Resulta que estoy haciendo esto:

Código: [Seleccionar]
bool config(char* p_data,size_t nbyte){
  static char* p_save[]={"","","","","","","","",""};

  p_save[0]=p_data;
  EepromRTC.readChars(NUMCHARINITMENU+15,p_data,5);
  printf("%s",p_data);
  printf("%s",p_save[0]);
}

lo que intento de hacer con esta función es poder guardar la variable p_data (ejem: "hola mundo") en p_save, posición 0, pero mi problema es que cuando intento imprimir el valor de p_save[0] me da el resultado que toma p_data en la linea EepromRTC.readChars(NUMCHARINITMENU+15,p_data,5); y según yo no debería ya que guardo el valor de p_data = "hola mundo" en p_save[0] antes que cambien.

Saludos!!

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:punteros un dolor de cabeza
« Respuesta #1 en: 29 de Julio de 2019, 21:14:08 »
O estas teniendo una confusion con lo que queres hacer o no estas entendiendo como es que funciona. Primero que no usaria esto para definirlo vacio: ""

Es decir :
Código: C
  1. static char* p_save[]={"","","","","","","","",""};
por
Código: C
  1. static char* p_save[9];


El puntero es como un "acceso indirecto" de un programa en tu PC. Si borras el programa, el acceso directo sigue estando aunque no direccione a donde debe ser.

Si haces:

  p_save[0]=p_data;

p_save[0] va a ser un acceso directo a p_data, el problema es que si cambias p_data entonces el contenido va a cambiar... Por que lo unico que se guardo en p_save es la direccion donde esta p_data esta ubicado, no su contenido.. Por eso me extraña lo que escribiste como:

Citar
poder guardar la variable p_data (ejem: "hola mundo") en p_save

Si queres guardar el los strings entonces es otra cosa... creo que antes de continuar deberiamos definir si es eso o no.. Ademas podrías explicar con un ejemplo como es que queres que funcione tu codigo ? No logro entender la explicacion que queres dar. El codigo que pasaste ambos van a imprimir lo mismo, Si p_data cambia, entonces el contenido que apunta p_save cambia.

Citar
EepromRTC.readChars(NUMCHARINITMENU+15,p_data,5);

No tengo la menor idea que hace esa funcion tampoco, si tenes el documento donde lo explica mejor.
« Última modificación: 29 de Julio de 2019, 21:17:03 por KILLERJC »

Desconectado japifer_22

  • PIC18
  • ****
  • Mensajes: 405
Re:punteros un dolor de cabeza
« Respuesta #2 en: 29 de Julio de 2019, 22:31:25 »
Hola KILLERJC, gracias por la respuesta.
en cuanto a:
Citar
El puntero es como un "acceso indirecto" de un programa en tu PC. Si borras el programa, el acceso directo sigue estando aunque no direccione a donde debe ser.

así lo tenia entendido pero hoy he andado con la cabeza en otro lado y mis minutos de programación me lo he cuestionado todo.. en fin...

lo que intento de hacer es por medio de la función config y la entrada de datos p_data seleccionar distintos menu por medio de un switch, y una vez accedido al "case" que quiero, por medio de la misma variable p_data guardar el nuevo contenido que trae en un arreglo static char* p_save[9];, de la forma
Código: C
  1. p_save[0]=p_data;

y el contenido de p_save[0] que no sufra cambio una vez que se guarde... para así ir guardando los nuevos datos que trae p_data en otras posiciones de p_save[0]

Saludos y desde ya gracias por el tiempo

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:punteros un dolor de cabeza
« Respuesta #3 en: 30 de Julio de 2019, 06:39:49 »
Ahora que me doy cuenta..... ¿ Estas usando C++ ? ¿O estas usando C con un puntero a una funcion sobre un struct? (al ver el EEpromRTC.readchar() )
Porque estamos hablando de dos cosas muy distintas entre uno y otro. Y tu aproximacion al trabajo de strings es a C y veo que intentas hacer cosas como si fuera C++ (copiar strings con una sola asignacion).


--------------------------------------------------------------------------------------


Citar
y el contenido de p_save[0] que no sufra cambio una vez que se guarde

Bueno ahi tenes el problema el cual no vas a poder hacerlo con un array de punteros a char...
Si queres guardar CONTENIDO, entonces tu array p_save va a necesitar el lugar para hacerlo, y hacerlo caracter a caracter. Supongamos que p_data es de maximo 15 caracteres incluido el nulo entonces tu p_save seria:

Código: C
  1. static char p_save[9][15];

Podrias hacer un array de punteros si quisieras y que apunte a la memoria. La otra y es que no se usa mucho en los microcontroladores es utilizar la memoria dinamica (con todo lo que conlleva). Y ahi si tendrias tu array de punteros.

De todas formas hacer esto:

Código: C
  1. p_save[0]=p_data;

Nunca te va a copiar los datos.. Solo la direccion de donde comienza p_data, por lo que si modificas p_data, lo que accedes desde p_save[0] es el p_data modificado.
Lo que tenes que hacer es copiar caracter a caracter hasta el caracter nulo empezando por p_save[0][0]

--------------------------------------------------------------------------------------------------------

Espero generar un ejemplo mas practico de lo que estas intentando hacer:

Direccion   Nombre  Contenido
0x0001     p_data     "Hola mundo"
0x0020     p_save[0]     0x0001

Tenes algo asi... luego de tu p_save[0] = p_data .... Observaras que p_save[0] sigue apuntando a 0x0001.
En caso de que modifiques p_data y pongas otro string quedaria:

Direccion   Nombre  Contenido
0x0001     p_data     "Peperepe repepe"
0x0020     p_save[0]     0x0001

Es decir p_save[0] no cambia y sigue apuntando a p_data, por lo que no vas a guardar el VALOR, y es aca donde te equivocas con los punteros. Vos estas buscando algo asi:

Direccion   Nombre  Contenido
0x0001     p_data     "Peperepe repepe"
0x0020     p_save[0]  "Peperepe repepe"

Y para eso necesitas que p_save tenga lugar para tener todo el string.. es decir es un array de strings.

Existe otra forma de que los punteros SI funcionen.
Si en el caso de que los strings son constantes y almacenados en la FLASH y p_data es simplemente un puntero a char (y no un array) Es posible guardar el puntero. Pero eso significa que p_data lo unico que va a servir es para apuntar a otro string que este en la FLASH,  y no para almacenar algun dato aleatorio como lo estas buscando.

« Última modificación: 30 de Julio de 2019, 06:42:18 por KILLERJC »

Desconectado japifer_22

  • PIC18
  • ****
  • Mensajes: 405
Re:punteros un dolor de cabeza
« Respuesta #4 en: 18 de Agosto de 2019, 23:20:26 »
Killerjc. muchas gracias por la aclaración.