Преобразовать массив байтов в целое число

Я работаю над проектом IJVM с использованием языка Си. Сначала я импортировал двоичный файл в свою программу, который должен быть проанализирован как слова. Теперь я сделал переменную (текст), которая содержит двоичный файл, и мне нужно преобразовать его в массив слов. Я получил подсказку

    int result = ((bytes[0] & 0xFF) << 24) |
    ((bytes[1] & 0xFF) <<16) |
    ((bytes[2] & 0xFF) << 8) | (bytes[3] & 0xFF);

Это работало только для первых 4 байтов, что мне нужно, это массив result,

Я пробовал что-то подобное, но это никогда не работало..:(

void type_converter(byte_t* text)
{
  for (int i = 0; i < sizeof(text)/4; i++) {
    for (int j = 0; i < sizeof(text)/4; i++) {

      int result[i] = ((text[j+0] & 0xFF) << 24) |
      ((text[j+1] & 0xFF) << 16) |
      ((text[j+2] & 0xFF) << 8) | (text[j+3] & 0xFF);
      instruction[i] = result;
      j =+ 4;
    }
  }

1 ответ

Решение

Пример кода OP:

  • Внутренний цикл не имеет смысла (или я не понял намерения).

  • Внешний цикл я бы изменил на: for (int i = 0; i + 3 < size; i += 4), Пожалуйста, обратите внимание на i + 3, Это делает цикл безопасным от частичного количества байтов в конце буфера. i += 4 делает соответствующий шаг в 4 байтовых прыжках.

  • size это то, что вы должны предоставить. Как уже говорил Мартин: sizeof text предоставляет размер указателя. Нет возможности определить это оператором (если у вас нет прямого доступа к исходному массиву). Вы должны сделать параметр size за это. (Это очень распространенное решение в программах на Си.)

  • Btw. нет декларации для result или же instruction, Следовательно, я бы сделал один из них в качестве другого параметра функции.

Итак, ваша функция изменения может выглядеть так:

void type_converter(uint32_t *result, byte_t *text, size_t size)
{
  for (size_t i = 0; i + 3 < size; i += 4) {
    result[i / 4]
      = ((text[i+0] & 0xFF) << 24)
      | ((text[i+1] & 0xFF) << 16)
      | ((text[i+2] & 0xFF) << 8)
      | (text[i+3] & 0xFF);
    }
  }
}

И, пожалуйста, не забывайте, что result должен обеспечить достаточно места для хранения size / 4uint32_t слова.


Поскольку я только что вспомнил, как я делал подобные вещи в прошлом, это можно немного изменить, чтобы предотвратить i + 3 в состоянии цикла:

void type_converter(uint32_t *result, byte_t *text, size_t size)
{
  for (size_t i = 3; i < size; i += 4) {
    result[i / 4]
      = ((text[i-3] & 0xFF) << 24)
      | ((text[i-2] & 0xFF) << 16)
      | ((text[i-1] & 0xFF) << 8)
      | (text[i] & 0xFF);
    }
  }
}

Живая Демо на wandbox

Замечания:

Я только что понял, что такая комбинация байтов предназначена для чисел с прямым порядком байтов (старший байт в первой позиции). Для little-endian индексы должны были быть переупорядочены.

Другие вопросы по тегам