Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: HRSLASH en 28 Agosto 2012, 06:37 am



Título: Consulta punteros (C)
Publicado por: HRSLASH en 28 Agosto 2012, 06:37 am
Hola gente! he aquí la consulta:
Tengo un sector de n unsigned char en la memoria reservado con malloc y para manejar los datos del sector uso otro puntero q apunte al inicio pero lo declaro como unsigned short pq quiero extraer los datos de a 2 bytes, he aqui la cuestion, cuando hago avanzar el puntero obviamente lo hace de a dos bytes, en ciertos casos quiero hacerlo avanzar de a un byte por lo que hago lo sig p = (unsigned char *)p + 1 , que funciona, pero el compilador me lanza la advertencia de que estoy asignando punteros de tipo incompatible lo cual es razonable. Hay alguna manera de hacerlo correctamente??


Título: Re: Consulta punteros (C)
Publicado por: rir3760 en 28 Agosto 2012, 17:37 pm
Si con "correctamente" te refieres a un comportamiento que cumpla con el estándar de C no, no hay forma. Eso se debe a los requisitos de alineación: un puntero a "unsigned int" debe apuntar a una dirección que sea múltiplo de "sizeof(unsigned int)" (dos en tu caso).

Un saludo


Título: Re: Consulta punteros (C)
Publicado por: ecfisa en 28 Agosto 2012, 18:43 pm
Hola.

No sé el motivo por el cuál deseas ese comportamiento del puntero, pero si tu objetivo es obtener o acceder a los medios octetos (nibbles) de cada elemento del arreglo, podes hacer:

Código
  1. int main()
  2. {
  3.  unsigned char v[5] = {0xF1,0xF2,0xF3,0xF4,0xF5}, *p, i, l, h;
  4.  p = &v;
  5.  for (i=0; i < 5; i++) {
  6.    h = *p >> 4;
  7.    l = *p & 0x0F;
  8.    printf("%X %X\n",h, l);
  9.    p++;
  10.  }
  11.  getchar();
  12. }
  13.  

Por otro lado la asignación:
Código:
p = (unsigned char *)p + 1

Es equvalente a hacer:
Código:
 p++;
o
Código:
p += 1;
o
Código:
 p = p +1;


Saludos.


Título: Re: Consulta punteros (C)
Publicado por: rir3760 en 29 Agosto 2012, 00:11 am
Por otro lado la asignación:
Código:
p = (unsigned char *)p + 1

Es equvalente a hacer:
Código:
 p++;
No. El detalle es la conversión explicita al tipo "unsigned char *".

En la aritmética de punteros la expresión:
Código
  1. p + i
Resulta en un incremento en la dirección igual a "i * sizeof *p".

* En el caso del tipo "char *" la expresión "sizeof *p" siempre resulta en uno.

* En el caso del tipo "unsigned int *" la expresión "sizeof *p" resulta (en el caso de HRSLASH) en dos.

Un saludo


Título: Re: Consulta punteros (C)
Publicado por: ecfisa en 29 Agosto 2012, 02:17 am
Hola rir3760.

Tenes razón.

En realidad debí aclarar: "para este este caso la asignacion... es equivalente a...". Ya que los tipos tipos char, unsigned char y signed char tienen un tamaño de 1 byte. Esto por supuesto no sería válido si fueran tipos de un tamaño mayor.

Saludos.


Título: Re: Consulta punteros (C)
Publicado por: HRSLASH en 31 Agosto 2012, 21:19 pm
Gracias por las respuestas!!  :D


Título: Re: Consulta punteros (C)
Publicado por: do-while en 1 Septiembre 2012, 01:19 am
¡Buenas!

¿Has probado esto?
ptro = (unsigned short*) (((char*) p) + 1);

¡Saludos!


Título: Re: Consulta punteros (C)
Publicado por: rir3760 en 1 Septiembre 2012, 18:54 pm
¿Has probado esto?
ptro = (unsigned short*) (((char*) p) + 1);
No funcionaria.

Con esta parte no hay problema (había un par de paréntesis de mas):
Código
  1. ((char *) p + 1)
La dirección almacenada en "p" se convierte al tipo "char *" y se le suma una unidad ("sizeof(char)" siempre es igual a uno).

El problema surgiría con la segunda conversión:
Código
  1. (unsigned short*) ((char *) p + 1)
Ya que el puntero a carácter no cumplirá con los requisitos de alineación del puntero a "unsigned int".

Un saludo


Título: Re: Consulta punteros (C)
Publicado por: do-while en 3 Septiembre 2012, 07:38 am
¡Buenas!

Si compilais y ejecutais esto, por lo menos utilizando gcc, no hay ningun problema:
Código
  1. #include <stdio.h>
  2.  
  3. int main(int argc, char *argv[])
  4. {
  5.    char s[] = "Uno, dos, tres, cuatro...";
  6.    unsigned short *p,i;
  7.  
  8.    for(i = 0 ; i < 5 ; i++)
  9.    {
  10.        p = (unsigned short*)(s + i);
  11.        printf("%p\n",p);
  12.    }
  13.  
  14.    return 0;
  15. }
  16.  

Espero que te sirva.

¡Saludos!