K&R C练习帮助

8
我一直在阅读K&R C编程语言书籍,我卡在了第2-6个练习上,其中写道:
编写一个函数setbits(x,p,n,y),它返回x,使从位置p开始的n位设置为y的最右边的n位,同时保留其他位不变。
我很难理解他们要我做的确切事情。我看了一个可能的答案这里,但我仍然不太明白。我觉得是措辞让我困惑。 有人可以用不同的方式解释一下他们希望我以不同的方式理解我需要编写的代码吗?
6个回答

14

对Avi的回答进行详细说明:

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

假设你的 i = 0xAB。用二进制表示,这是:10101011

让我们为每个位位置编号。

Position #: 7   6   5   4   3   2   1   0
Bit:        1   0   1   0   1   0   1   1
右侧最后一位是位置“0”,左侧最左边(最重要的)是位置“7”。因此,下面的两个值p和n表示“您想修改从位p开始的n个位”。 因此,如果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)

我们是如何修改它们的呢?我们替换它们。用另一组由y中最低有效位的三个比特组成的位。

那么这就是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,则需要用"101010"替换i中的这六个位-也就是最右边的6位。

因此,你的任务是从i中取出指定的位数-在这种情况下是"101"-并用y中指定的位数-"010"替换它们。

如果你这样做了,那么你的返回值将是

1 0 1 0 1 0 1 0


这是一个非常好的、详尽的解释。非常感谢你。 - Koby
很棒的答案。只要获取一个样本输入和正确答案来验证它是否有效,这也非常有用。 - mickadoo
确实非常好的解释。最后一行是答案吗?我不确定您传达的意思,但答案应该是:10010011 - PKumar

3

例如:

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

我们需要取 x 中从位置 5 开始的三个二进制位(101),并将它们替换为 y 中最右边的三个二进制位(010)。

3
那个“可能的答案”只是没有注释的代码。难怪它对你没有帮助。
问题(以及可能的回答者)假设你熟悉位域。这种情况在嵌入式编程中非常常见,其中你控制硬件寄存器。
假设有一个寄存器可以设置音频音量级别,同时还可以让你选择扬声器或麦克风等等。位可能看起来像这样:
ssAAAmxx - 每个字母代表该数字中的一个位域。要更改音量,必须更改“AAA”的值。现在,假设你的程序中有一些东西可以让你调整音量。这是一个简单的控件,它总是返回0到7之间的数字。格式如下:
xxxxxAAA - 你的任务是从中取出AAA位(称为“y”),并将它们设置到上面的数字(称为“x”)中,而不改变不是A的位。因此,问题将变成“从y的最右边的3位开始(记住,他们从零开始计数),将它们设置到x中的第5位。然后,在我们的示例中,3和5变成了原始问题中的n和p。

2

操作为“位域插入”

该操作的思想是,y通常比n少,但如果不是这样,那么只使用n。任务是将y插入到从p开始的x中,使用字段宽度为n


0

将从p位置开始的x的n位替换为y的最右边的n位。

可能你应该利用第2.9章中的getbits()例程。


-1

这个怎么样?

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接