¿Cómo obtener el valor de bytes individuales de una variable?

5 minutos de lectura

avatar de usuario
tobey

Sé que para obtener la cantidad de bytes utilizados por un tipo de variable, usa sizeof(int) por ejemplo. ¿Cómo obtiene el valor de los bytes individuales utilizados cuando almacena un número con ese tipo de variable? (es decir int x = 125.)

  • Posible duplicado de c obtener enésimo byte de entero

    – phuclv

    26 de julio de 2018 a las 7:35

avatar de usuario
pete wilson

Debe saber la cantidad de bits (a menudo 8) en cada “byte”. Luego puede extraer cada byte a su vez haciendo ANDing el int con la máscara adecuada. Imagine que un int tiene 32 bits, luego 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 los 8 bits de orden inferior de a, b, c y d.

  • +1: Considero que esto es 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

    30 de diciembre de 2011 a las 14:40

  • Sería un mejor ejemplo si el tipo de a, b etc habría sido unsigned char. En ese caso, el compilador podría asignar las variables en los mismos registros del procesador que contiene the_intsi son del tamaño adecuado.

    – Lindydancer

    30 de diciembre de 2011 a las 14:53

  • +1 esta respuesta es la más correcta. Todos los demás son dependientes de endian. @dip no requiere un uso intensivo del procesador en muchas plataformas y, de todos modos, el compilador transformará esto en lo que sea es la mejor implementación detrás de escena.

    – ams

    30 de diciembre de 2011 a las 14:59


  • @PeteWilson: Yo diría que el caso en que un char no es 8 bits es tan raro que tendrías que hacer todo a mano de todos modos. Supongo que uno podría escribir el código usando el CHAR_BITS macro para estar seguro, pero no creo que valga la pena el esfuerzo. Gracias por su oferta: bailo Lindy Hop y (normalmente) me mantengo erguido (aunque no hago aéreos), sin embargo, preferiría que votara mis respuestas en función del contenido en lugar de en mi actuación en la pista de baile 😉

    – Lindydancer

    30 de diciembre de 2011 a las 15:27

  • @ams por lo que veo, algo nuevo aprendido y para Pete Lo que quise decir es que muchos cambios de CPU se realizan por bits y cuestan más ciclos (al igual que multiplicar, dividir, módulo y bifurcar) que simples manipulaciones de bits y lectura/escritura, etc. Pero tienes razón, es la mejor manera de hacer esto que conozco ahora. Lo siento por ser un dolor =)

    – Dip switch

    30 de diciembre de 2011 a las 16:13

Puede obtener los bytes usando alguna aritmética de punteros:

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), el resultado es:

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

  • ¿Cómo 4294967278 es un byte? Por defecto char El tipo probablemente esté registrado en su sistema y se esté convirtiendo en unsigned produce grandes números.

    – Eser Aygün

    30 de diciembre de 2011 a las 14:15

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

    – Konrad Rodolfo

    30 de diciembre de 2011 a las 14:19


  • @Konrad Rudolph porque fue lo primero que se me ocurrió.

    usuario142019

    30 de diciembre de 2011 a las 14:20

  • ¿Qué sucede si usa ‘char’ en lugar de ‘char sin firmar’?

    –Tobey

    30 de diciembre de 2011 a las 14:38

  • @toby la firma de char está definida la implementación. Esto significa que con algunos compiladores la representación interna se ve diferente. En este código no desea el bit de signo. Si utiliza char en lugar de unsigned charpodría incluir el bit de signo y la conversión ya no funcionará.

    usuario142019

    30 de diciembre de 2011 a las 14:39


avatar de usuario
Dip switch

Podrías hacer uso de un union pero tenga en cuenta que el orden de 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;
}

Si desea obtener esa información, diga para:

int value = -278;

(Seleccioné ese valor porque no es muy interesante para 125: ¡el byte menos significativo es 125 y los demás bytes son todos 0!)

Primero necesita un puntero a ese valor:

int* pointer = &value;

Ahora puede encasillar eso en un puntero ‘char’ que es solo un byte, y obtener los bytes individuales mediante la 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 los bytes para ints y otros tipos de datos depende de su sistema: busque ‘big-endian’ frente a ‘little-endian’.

avatar de usuario
Eser Aygün

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 los bytes de los números enteros depende de la plataforma.

  • el orden de los bytes depende de la CPU, no del sistema operativo

    – Dip switch

    30 de diciembre de 2011 a las 14:13

  • el orden de los bytes depende de la CPU, no del sistema operativo

    – Dip switch

    30 de diciembre de 2011 a las 14:13

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad