Справка по упражнениям K & R C - PullRequest
       33

Справка по упражнениям K & R C

7 голосов
/ 12 сентября 2009

Я изучал книгу по языку программирования K & R C и застрял в упражнении 2-6, где написано:

Напишите функцию setbits (x, p, n, y), которая возвращает x с n битами, которые начинаются с позиции p, равной крайним правым n битам y, оставляя другие биты неизменными.

У меня проблемы с пониманием того, что они хотят от меня. Я посмотрел на возможный ответ здесь , но я все еще не совсем понимаю. Я думаю, что это формулировка, которая сбивает меня с толку. Может кто-нибудь объяснить, что они ищут, чтобы я сделал по-другому? Я надеюсь, что другие формулировки помогут мне понять, что мне нужно делать в коде.

Ответы [ 6 ]

12 голосов
/ 13 сентября 2009

Излагая ответ Ави:

int i = setbits(0xAB = b10101011, 5, 3, 0xAA = b10101010);
i equals 0x93 = b10010011

Скажите, что я = 0xAB. В двоичном виде это: 10101011

Давайте нумеруем каждую битовую позицию.

Position #: 7   6   5   4   3   2   1   0
Bit:        1   0   1   0   1   0   1   1

Самый правый бит (наименее значимый) - это позиция "0". Самым левым (самым значимым) является положение "7".

Таким образом, следующие два значения, p и n, говорят: «Вы хотите изменить n битов, начиная с бита p». Так что, если p = 5 и n = 3, вы хотите начать с бита номер 5, и всего вы модифицируете 3 бита. Что означает биты 5, 4, 3. «101» в этом примере.

Position #: 7   6   5   4   3   2   1   0
Bit:        1   0   1   0   1   0   1   1
                   |         |
                    ---------
               (Modifying these three bits)

Как мы их модифицируем? Мы их заменяем. С другим набором из 3 бит. Три младших разряда из y.

Так вот у:

Position #: 7   6   5   4   3   2   1   0
Bit:        1   0   1   0   1   0   1   0 

А самыми правыми битами будут биты 2, 1, 0. или значение «010». Конечно, если значение n = 6, вам нужно заменить эти шесть битов из i на «101010» - самые правые 6 битов.

Итак, ваша задача - взять указанные биты из i - в данном случае «101» - и заменить их указанными битами из y - «010».

Если вы сделаете это, возвращаемое значение будет

1 0 1 0 1 0 1 0

3 голосов
/ 12 сентября 2009

Например:

int i = setbits(0xAB = b10101011, 5, 3, 0xAA = b10101010);
i equals 0x93 = b10010011

Мы берем 3 бита, начиная с позиции 5 в x (101), и заменяем их самыми правыми тремя битами из y (010).

2 голосов
/ 12 сентября 2009

Этот «возможный ответ» - просто код без комментариев. Не удивительно, что это тебе не помогло.

Вопрос (и, возможно, ответчики) предполагают, что вы знакомы с битовыми полями. Подобные вещи очень распространены во встроенном программировании, где вы управляете аппаратными регистрами.

Скажем, есть регистр, который устанавливает уровень громкости звука, между прочим. Это может, в то же время, позволить вам выбрать динамики или микрофоны и тому подобное. Биты могут выглядеть так:

ssAAAmxx - каждая буква представляет битовое поле в пределах этого числа. Чтобы изменить громкость, вы должны изменить значение «AAA». Теперь предположим, что в вашей программе есть что-то, что позволяет вам регулировать громкость. Это простой элемент управления, и он всегда возвращает число от 0 до 7. Формат для этого выглядит следующим образом:

xxxxxAAA - Ваша задача состоит в том, чтобы взять биты AAA из этого (назовите это «y») и установить их в это число выше (назовите его «x»), не изменяя биты, которые не Как. Таким образом, проблема гласит: «Возьмите самые правые 3 бита y и установите их в x, начиная с бита 5 (помните, они считают биты с нуля). Затем 3 и 5 в нашем примере становятся n и p в исходная задача.

1 голос
/ 12 сентября 2009

Операция "вставка битового поля"

Идея состоит в том, что y обычно будет меньше n битов, но в противном случае используйте только n . На английском языке задача состоит в том, чтобы вставить y в x , начиная с p , используя ширину поля n .

0 голосов
/ 17 июня 2014

Как насчет этого?

unsigned int
setbits(unsigned int x, int p, int n, unsigned int y)
{
    char buffer[65];

    unsigned x1 = x >> (p + 1);
    x1 <<= (p + 1);

    /*
     * x1 now contains all the bits before position 'p'.
     */

    unsigned x2 = y & ~(~0 << n);
    x2 <<= (p + 1) - n;

    /*
     * x2 now contains the rightmost 'n' bits of 'y', left shifted (p + 1) - n bits.
     */
    unsigned x3 = x & ~(~0 << ((p + 1) - n));

    /*
     * x3 now contains the rightmost (p + 1) - n bits.
     */

    return x1 | x2 | x3;
}
0 голосов
/ 12 сентября 2009

Заменить n битов x, начиная с позиции p, на самые правые n битов y.

И, вероятно, вам следует воспользоваться подпрограммой getbits() в главе 2.9

...