Как получить значение отдельных байтов переменной? - PullRequest
9 голосов
/ 30 декабря 2011

Я знаю, что для получения количества байтов, используемых типом переменной, вы используете, например, sizeof(int). Как вы получаете значение отдельных байтов, используемых при сохранении числа с этим типом переменной? (т.е. int x = 125.)

Ответы [ 5 ]

17 голосов
/ 30 декабря 2011

Вы должны знать количество бит (часто 8) в каждом «байте». Затем вы можете извлекать каждый байт по очереди, используя AND с соответствующей маской. Представьте, что int 32-битный, а затем 4 байта из 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

И вот что у вас есть: каждый байт находится в младших 8 битах a, b, c и d.

16 голосов
/ 30 декабря 2011

Вы можете получить байты, используя некоторую арифметику указателей:

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);
}

На моей машине (Intel x86-64) вывод:

Byte 0 = 25  // 0x19
Byte 1 = 238 // 0xEE
Byte 2 = 191 // 0xBF
Byte 3 = 0 // 0x00
4 голосов
/ 30 декабря 2011

Вы можете использовать union, но имейте в виду, что порядок байтов зависит от процессора и называется 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;
}
4 голосов
/ 30 декабря 2011

Если вы хотите получить эту информацию, скажите:

int value = -278;

(я выбрал это значение, потому что оно не очень интересно для 125 - младший байт равен 125, а все остальные байты равны 0!)

Сначала вам нужен указатель на это значение:

int* pointer = &value;

Теперь вы можете типизировать это к указателю 'char', который составляет всего один байт, и получить отдельные байты путем индексации.

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

Обратите внимание, что порядок байтов для целых и других типов данных зависит от вашей системы - ищите 'big-endian' против 'little-endian'.

3 голосов
/ 30 декабря 2011

Это должно работать:

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];

Но учтите, что порядок байтов целых чисел зависит от платформы.

...