【问题标题】:K&R C Exercise HelpK&R C 锻炼帮助
【发布时间】:2010-11-27 19:14:23
【问题描述】:

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

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

我无法理解他们要我做什么。我看了一个可能的答案here,但我还是不太明白。我认为这是让我失望的措辞。谁能以不同的方式解释他们要我做什么?我希望不同的措辞能帮助我理解我需要在代码方面做些什么。

【问题讨论】:

    标签: c binary bit-manipulation kr-c


    【解决方案1】:

    详解阿维的回答:

    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 的值,那么您需要将 i 中的这 6 位替换为“101010”——最右边的 6 位。

    所以你的任务是从 i 中取出指定的位 - 在本例中为“101” - 并将它们替换为 y 中的指定位 - “010”。

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

    1 0 1 0 1 0 1 0

    【讨论】:

    • 这是一个非常好的、详尽的解释。非常感谢。
    • 很好的答案。仅获取示例输入和正确答案以验证其是否正常工作也非常有用
    • 确实很好的解释。最后一行是答案?我不确定您传达的内容,但答案应该是:10010011
    【解决方案2】:

    例如:

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

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

    【讨论】:

      【解决方案3】:

      那个“可能的答案”只是没有 cmets 的代码。难怪它对你没有帮助。

      问题(可能还有回答者)假设您熟悉位域。这种事情在您控制硬件寄存器的嵌入式编程中非常常见。

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

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

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

      【讨论】:

        【解决方案4】:

        操作是“位域插入”

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

        【讨论】:

          【解决方案5】:

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

          也许你应该利用第 2.9 章中的 getbits() 例程

          【讨论】:

            【解决方案6】:

            这个怎么样?

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-09-15
              • 2019-11-10
              相关资源
              最近更新 更多