Consulta punteros (C)

Iniciado por HRSLASH, 28 Agosto 2012, 06:37 AM

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

HRSLASH

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??
La televisión es para mi el medio mas instructivo y cultural que conozco, cuando la prenden me voy a leer

rir3760

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
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language

ecfisa

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.

rir3760

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
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language

ecfisa

#4
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.

HRSLASH

Gracias por las respuestas!!  :D
La televisión es para mi el medio mas instructivo y cultural que conozco, cuando la prenden me voy a leer

do-while

¡Buenas!

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

¡Saludos!
- Doctor, confundo los números y los colores.
- Vaya marrón.
- ¿Marrón? ¡Por el culo te la hinco!

rir3760

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
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language

do-while

¡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!
- Doctor, confundo los números y los colores.
- Vaya marrón.
- ¿Marrón? ¡Por el culo te la hinco!