我一直在阅读K& R C编程语言书,我坚持练习2-6,内容如下:
写一个函数setbits(x,p,n,y),返回x,其中n位从位置p开始,设置为y的最右边n位,其他位保持不变。
我无法理解他们正在寻找我的确切事情。我看了一个可能的答案here,但我仍然不太明白。我认为这是让我失望的措辞。任何人都可以用不同的方式解释他们想要我做什么吗?我希望不同的措辞可以帮助我理解我需要做什么代码。
答案 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;
}