Может ли кто-нибудь объяснить мне строку putchar в этой побитовой функции? - PullRequest
0 голосов
/ 25 октября 2019

Кто-нибудь знает, что 1u делает в этой функции? Следующая функция берет целое число и печатает его биты. Линия, которую я пытаюсь выяснить, это линия путчаров. Я вижу, что он принимает целое число без знака в качестве аргумента и итерирует единицу или ноль в цикле размером двоичного числа, что точно так же происходит с 8 * sizeof (int) и выполняет побитовую операцию «и» над выражением (1u<< i) где i - это просто итерация цикла, которая решает, на сколько бит сдвинуться. Вы в 1u просто модификатор, чтобы объявить число без знака или что-то? Я пытаюсь точно понять, как строка путчара в этой функции отображает каждый бит x с этой строкой. </p>

Это операция & bitwise, поэтому, если биты в x и биты (1u << i) оба1, цикл putchars 1, иначе 0. Но так как я не совсем понимаю, что такое 1u, я не знаю, что делает сдвиг битов влево, чтобы распечатать биты x. </p>

Может ли кто-нибудь выразить это для меня непрофессионалом?

void showbits( unsigned int x )
{
    for (int i = (sizeof(int) * 8) - 1; i >= 0; i--)
    {
        putchar(x & (1u << i) ? '1' : '0');
    }
    printf("\n");
}

Ответы [ 2 ]

2 голосов
/ 25 октября 2019

Код печатает двоичное представление x

Эта строка

for (int i = (sizeof(int) * 8) - 1; i >= 0; i--)

делает i имеющими значения от "number_of_bits_in_an_int" - 1 и вплоть до 0.

Итак, если мы предположим, что размер int равен 4 (символам), код можно записать так:

for (int i = 31; i >= 0; i--)

Так что в этом случае цикл может быть расширен как:

putchar(x & (1u << 31) ? '1' : '0');
putchar(x & (1u << 30) ? '1' : '0');
putchar(x & (1u << 29) ? '1' : '0');
...
putchar(x & (1u <<  1) ? '1' : '0');
putchar(x & (1u <<  0) ? '1' : '0');

Затем можно вычислить часть (1u << ..). 1u - это целое число без знака со значением 1, которое сдвигается влево несколько раз. Он генерирует шаговый 1-битный паттерн, начиная с MSB. Например:

1000.0000.0000.0000.0000.0000.0000.0000  (i.e. 1u << 31)
0100.0000.0000.0000.0000.0000.0000.0000  (i.e. 1u << 30)
0010.0000.0000.0000.0000.0000.0000.0000  (i.e. 1u << 29)
...
0000.0000.0000.0000.0000.0000.0000.0010  (i.e. 1u << 1)
0000.0000.0000.0000.0000.0000.0000.0001  (i.e. 1u << 0)

Когда этот шаблон является побитовым и имеет значение x с использованием &, а результат используется как логическое значение, он будет генерировать true, когда соответствующий бит в x равен 1(и false, если оно равно нулю).

Таким образом, код может быть записан в виде этого псевдокода:

putchar(is_bit_31_in_x_set ? '1' : '0');
putchar(is_bit_30_in_x_set ? '1' : '0');
putchar(is_bit_29_in_x_set ? '1' : '0');
...
putchar(is_bit_1_in_x_set ? '1' : '0');
putchar(is_bit_0_in_x_set ? '1' : '0');

Если sizeof не равен 4 (как предполагалось выше),Код по-прежнему печатает двоичное представление - просто с другим количеством битов. Например, с sizeof int равным 2, цикл будет идти от 15 до 0.

0 голосов
/ 25 октября 2019

Вот что делает 1u << i.

1 << 0    -> 0b0001 << 0     =>   0b0001      =>   1
1 << 1    -> 0b0001 << 1     =>   0b0010      =>   2
1 << 2    -> 0b0001 << 2     =>   0b0100      =>   4
1 << 3    -> 0b0001 << 3     =>   0b1000      =>   8
.
.

Значение x and ed должно сохранять знак числа при смещении вправо. На самом деле, на мой взгляд, я представляю, как сдвиг вправо с продлением знака продвигается вперед.

...