K& R C练习帮助

时间:2009-09-12 19:03:37

标签: c binary bit-manipulation kr-c

我一直在阅读K& R C编程语言书,我坚持练习2-6,内容如下:

  

写一个函数setbits(x,p,n,y),返回x,其中n位从位置p开始,设置为y的最右边n位,其他位保持不变。

我无法理解他们正在寻找我的确切事情。我看了一个可能的答案here,但我仍然不太明白。我认为这是让我失望的措辞。任何人都可以用不同的方式解释他们想要我做什么吗?我希望不同的措辞可以帮助我理解我需要做什么代码。

6 个答案:

答案 0 :(得分:12)

阐述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)

我们如何修改它们?我们正在取代它们。使用另一组3位。来自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位 - 最右边的6位。

所以你的任务是从i获取指定的位 - 在这种情况下,“101” - 并用y中的指定位替换它们 - “010”。

如果您这样做,那么您的返回值为

1 0 1 0 1 0 1 0

答案 1 :(得分:3)

例如:

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

我们从x(101)中的第5位开始取3位,并用y(010)中最右边的3位替换它们。

答案 2 :(得分:2)

“可能的答案”只是没有评论的代码。难怪它没有帮助你。

问题(可能是回答者)假设您熟悉位字段。在嵌入式编程中,这种情况非常常见,您可以在其中控制硬件寄存器。

假设有一个寄存器可以设置音量等级。同时,它可能会让您选择扬声器或麦克风以及类似的东西。这些位可能如下所示:

ssAAAmxx - 每个字母代表该数字内的位域。要更改音量,您必须更改“AAA”的值。现在,假设你的程序中有一些东西可以让你调整音量。它是一个简单的控件,它总是返回0到7之间的数字。它的格式如下:

xxxxxAAA - 你的工作就是从这里获取AAA位(称之为“y”),并将它们设置为上面的那个数字(称之为“x”),而不改变不是如。因此,问题是:“取y的最右边3位,并将它们设置为x,从第5位开始(记住,它们从0开始计数位)。然后,在我们的例子中,3和5成为n和p原来的问题。

答案 3 :(得分:1)

操作是“位域插入”

这个想法是 y 通常少于 n 位,但如果不是,只使用 n 。在英语中,任务是使用 n 的字段宽度从 p 开始将 y 插入 x

答案 4 :(得分:0)

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

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

答案 5 :(得分:-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;
}