BitShifting, сохраняя 3 u_int8_t в одно целое и снова считывая - PullRequest
1 голос
/ 24 сентября 2011

У меня вопрос к вам, ребята, который сводит меня с ума уже 2 дня.Может быть, потому, что я скучаю по основам сдвига битов, но почему-то мне это не приходит в голову.То, что я хочу, - это простая программа, которая читает 3 символа или uint8_t, сохраняет их в одно большое целое, а затем снова читает его.

Впервые я экспериментирую со сдвигом битов и почему-то застрял.

Это код:

int main (int argc, const char * argv[])
{
    u_int8_t insert1;
    u_int8_t insert2;
    u_int8_t insert3;
    int data;

    printf("Please enter value1: ");
    scanf("%d", &insert1);
    printf("Please enter value2: ");
    scanf("%d", &insert2);
    printf("Please enter value3: ");
    scanf("%d", &insert3);

    data |= insert3<<16 | insert2<<8 | insert1;

    printf("\nValue1: %d\n", data);
    printf("Value2: %d\n", data>>8);
    printf("Value3: %d\n", data>>16);
    return 0;
}

Когда я ввожу

126 103 255

Я получаю:

Значение1: 16711680Значение 2: 65280 Значение 3: 255

Что совершенно неверно.Я почти уверен, что значение правильно хранится в данных, но я не знаю, как их прочитать.

Большое спасибо: -)

Ответы [ 3 ]

6 голосов
/ 24 сентября 2011

У вас есть три ошибки:

  1. вы передаете указатель на uint8_t в scanf, но вы используете преобразование %d, которое ожидает указательдо int;вам нужно использовать %hhd, чтобы сообщить scanf, что вы используете хранилище размером char, в противном случае вы рискуете испортить свой стек;или вы можете изменить свои переменные на тип int или лучше (поскольку вопрос помечен C++), используйте оператор извлечения std::istream (operator >>), который является безопасным для типа

  2. вы не инициализировали data и использовали |=, таким образом смешивая неинициализированное значение с введенными вами значениями (которые будут создавать мусор)

  3. при использованииprintf, вам нужно замаскировать старший бит, если вы хотите видеть только младшие биты

Итак, ваш код должен выглядеть так:

#include <iostream>

static void readvalue(const char* name, uint8_t& outValue) {
    std::cout << "Please enter " << name << ": " << std::flush;
    std::cin >> outValue;
    std::cout << "\n";
}

int main() {
    uint8_t value1, value2, value3;
    readvalue("value1", value1);
    readvalue("value2", value2);
    readvalue("value3", value3);

    data = insert3<<16 | insert2<<8 | insert1;

    std::cout << "Value1: " << (data & 0xff);
    std::cout << "Value2: " << ((data >> 8) & 0xff);
    std::cout << "Value3: " << ((data >> 16) & 0xff);
}
6 голосов
/ 24 сентября 2011

Вы никогда не инициализировали data и делаете это:

data |= 

Либо инициализируйте его до нуля, либо измените строку на эту:

data = insert3<<16 | insert2<<8 | insert1;
0 голосов
/ 27 октября 2011

Я почти уверен, что это должно быть >>> вместо >>.У меня тоже была похожая проблема.Изменить: Это верно для Java, когда вы работаете с отрицательными числами, однако вы не сможете легко хранить отрицательные числа и получить их позже, так как вам нужно будет знать, когда у вас есть отрицательное или положительное число внутрицелое число и добавьте, если это соответственно.

...