【发布时间】:2021-01-31 15:33:39
【问题描述】:
“编写一个函数 setbits(x, p, n, y) 返回 x,其中从位置 p 开始的 n 位设置为 y 的最右边 n 位,其他位保持不变。”
我很难弄清楚我做错了什么。
#include <stdio.h>
unsigned setbits(unsigned int x, int p, int n, unsigned y);
int main()
{
unsigned x = 213;
unsigned y = 121;
int p = 4;
int n = 4;
x = setbits(x, p, n, y);
printf("%u\n", x);
getch();
return 0;
}
unsigned setbits(unsigned x, int p, int n, unsigned y)
{
return ((~(~0 << n) & y) << (p + 1 - n) | (~(~(~0 << n)) << (p + 1 - n) & x));
}
结果我在纸上得到 211,但我的代码生成 210。K&R 答案簿算法也返回 210。我不知道我在这里做错了什么。
编辑:这是答案簿中的代码:
unsigned setbits(unsigned x, int p, int n, unsigned y)
{
return x & ~(~(~0 << n) << (p + 1 - n)) | (y & ~(~0 << n)) << (p + 1 - n);
}
重新编辑。我在将代码分成单独的行时发现了这一点。问题是最后一个 x 旁边的括号放错了:
//original
{
return ((~(~0 << n) & y) << (p + 1 - n) | (~(~(~0 << n)) << (p + 1 - n) & x));
}
//fixed
{
return ((~(~0 << n) & y) << (p + 1 - n)) | (~(~(~0 << n) << (p + 1 - n)) & x);
}
这是分解的代码。这看起来还是很糟糕吗?我应该使用这样的变量吗:
int setbits(unsigned x, int p, int n, unsigned y)
{
unsigned z, k;
z = y & ~(~0 << n);
z = z << (p + 1 - n);
k = ~((~(~0 << n)) << (p + 1 - n));
k = k & x;
return z | k;
}
【问题讨论】:
-
显示您的步数。我不知道你在哪里出错了。
-
...我也不能。换句话说,该代码不是很容易阅读或理解。也许如果你把它考虑一下,它会变得更清楚?
-
我确定我的速度很慢,但是
u是什么? (你能证明你的论文也有效吗?) -
在这里可以学到一个重要的教训:在一行中编写一个复杂的表达式并不聪明——它使阅读/理解变得困难,甚至更难调试。将您的 setbits 函数重构为几行,每行都包含一个更简单的表达式 - 生成的代码效率不会降低,您将能够在调试器中单步执行代码并检查中间结果。
-
我想如果我将它们全部分开,我就不需要 100 个括号了,嗯?我会试试看。 K&R 示例和答题簿也都在一行中。
标签: c