Test Foro de elhacker.net SMF 2.1

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:


int main()
{
  unsigned char v[5] = {0xF1,0xF2,0xF3,0xF4,0xF5}, *p, i, l, h;
  p = &v;
  for (i=0; i < 5; i++) {
    h = *p >> 4;
    l = *p & 0x0F;
    printf("%X %X\n",h, l);
    p++;
  }
  getchar();
}


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

Es equvalente a hacer:
p++;
o
p += 1;
o
p = p +1;


Saludos.
Título: Re: Consulta punteros (C)
Publicado por: rir3760 en 29 Agosto 2012, 00:11 AM
Cita de: ecfisa en 28 Agosto 2012, 18:43 PMPor otro lado la asignación:
p = (unsigned char *)p + 1

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

En la aritmética de punteros la expresión:
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
Cita de: do-while en  1 Septiembre 2012, 01:19 AM
¿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):
((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:
(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:

#include <stdio.h>

int main(int argc, char *argv[])
{
    char s[] = "Uno, dos, tres, cuatro...";
    unsigned short *p,i;

    for(i = 0 ; i < 5 ; i++)
    {
        p = (unsigned short*)(s + i);
        printf("%p\n",p);
    }

    return 0;
}


Espero que te sirva.

¡Saludos!