2011-12-30 30 views

Respuesta

14

Usted puede obtener los bytes utilizando algún puntero aritmética:

int x = 12578329; // 0xBFEE19 
for (size_t i = 0; i < sizeof(x); ++i) { 
    // Convert to unsigned char* because a char is 1 byte in size. 
    // That is guaranteed by the standard. 
    // Note that is it NOT required to be 8 bits in size. 
    unsigned char byte = *((unsigned char *)&x + i); 
    printf("Byte %d = %u\n", i, (unsigned)byte); 
} 

En mi máquina (Intel x86-64), la salida es:

Byte 0 = 25 // 0x19 
Byte 1 = 238 // 0xEE 
Byte 2 = 191 // 0xBF 
Byte 3 = 0 // 0x00 
+1

¿Cómo es el 4294967278 en un byte? El tipo 'char' predeterminado probablemente esté firmado en su sistema y el lanzamiento en' unsigned' produce números grandes. –

+0

@Eser Aygün Voy a actualizar el código. Gracias por el comentario. –

+0

¿Alguna razón para usar la aritmética de puntero manual en lugar del acceso a la matriz mucho más legible? –

3

Si quiere obtener esa información, por ejemplo:

int value = -278; 

(seleccioné ese valor porque no me interesa mucho ing de 125 - el byte menos significativo es el 125 y los demás bytes son todos 0)

primero tiene un puntero a ese valor:

int* pointer = &value; 

Ahora puede encasillarse que a un puntero char '! que es solo un byte, y obtiene los bytes individuales por indexación.

for (int i = 0; i < sizeof(value); i++) { 
    char thisbyte = *(((char*) pointer) + i); 
    // do whatever processing you want. 
} 

Tenga en cuenta que el orden de bytes para enteros y otros tipos de datos depende de su sistema - mirar hacia arriba 'big-endian' vs 'ascendente hacia la izquierda'.

+0

¿Alguna razón para utilizar la aritmética de puntero manual en lugar del acceso a la matriz mucho más legible? –

+0

¿Porque es obvio para los educandos que estamos usando un puntero? No considero que la aritmética del puntero sea incorrecta o ilegible. – Dan

+1

No está mal, pero seguramente no discutas que es tan legible como el acceso a la matriz ...! Compare '* (x + i)' con 'x [i]'. De hecho, ¿por qué existe la sintaxis de acceso a la matriz, si no la usamos cuando corresponde? –

2

esto debería funcionar:

int x = 125; 
unsigned char *bytes = (unsigned char *) (&x); 
unsigned char byte0 = bytes[0]; 
unsigned char byte1 = bytes[1]; 
... 
unsigned char byteN = bytes[sizeof(int) - 1]; 

Pero tenga en cuenta que el orden de bytes de enteros depende de la plataforma.

+0

el orden de bytes depende de la CPU y no depende del sistema operativo – DipSwitch

+0

@DipSwitch Tienes razón. Corregido –

3

Se podría hacer uso de un union pero tenga en cuenta que el orden de los bytes depende del procesador y se llama Endianness http://en.wikipedia.org/wiki/Endianness

#include <stdio.h> 
#include <stdint.h> 

union my_int { 
    int val; 
    uint8_t bytes[sizeof(int)]; 
}; 

int main(int argc, char** argv) { 
    union my_int mi; 
    int idx; 

    mi.val = 128; 

    for (idx = 0; idx < sizeof(int); idx++) 
     printf("byte %d = %hhu\n", idx, mi.bytes[idx]); 

    return 0; 
} 
+0

@WTP ah lol, ni siquiera se dio cuenta: p – DipSwitch

14

Usted tiene que saber el número de bits (a menudo 8) en cada "byte ". A continuación, puede extraer cada byte alternando ANDing the int con la máscara adecuada. Imagínese que un int es de 32 bits, a continuación, para obtener 4 bytes de the_int:

int a = (the_int >> 24) & 0xff; // high-order (leftmost) byte: bits 24-31 
    int b = (the_int >> 16) & 0xff; // next byte, counting from left: bits 16-23 
    int c = (the_int >> 8) & 0xff; // next byte, bits 8-15 
    int d = the_int   & 0xff; // low-order byte: bits 0-7 

Y ahí lo tienes: cada byte está en el bajo orden de 8 bits de a, b, c, y d.

+0

Lo está haciendo más difícil de lo que es y usar el cambio para extraer bytes requiere bastante de CPU. Sería mucho más simple y rápido acceder directamente a la ubicación de cada byte en la memoria ... – DipSwitch

+0

@Dip - mi forma brutal tiene la virtud de que es portátil en las CPU, mientras que otras pueden no serlo. Pero como quieras, por supuesto. –

+1

+1: Considero esto mucho mejor que jugar con la ubicación de la memoria. 1) si es endian-agnóstico. 2) La CPU puede realizar operaciones en los registros del procesador, por lo que suele ser mucho más eficiente. De hecho, para algunas máquinas (de 8 bits), es posible que esto no genere ningún código (si tiene un compilador decente). – Lindydancer

Cuestiones relacionadas