9

我有一个名为的函数,它用以下限制replaceByte(x,n,c)替换字节:nxc

  • 从 0 (LSB) 到 3 (MSB) 编号的字节
  • 例子:replaceByte(0x12345678,1,0xab) = 0x1234ab78
  • 您可以假设 0 <= n <= 3 和 0 <= c <= 255
  • 法律行动:! ~ & ^ | + << >>
  • 最大操作数:10

    int replaceByte(int x, int n, int c) {
            int shift = (c << (8 * n));
            int mask = 0xff << shift;
            return (mask & x) | shift;
        }
    

但是当我测试它时,我得到了这个错误:

错误:测试 replaceByte(-2147483648[0x80000000],0[0x0],0[0x0]) 失败... ...给出 0[0x0]。应该是-2147483648[0x80000000]

在意识到 * 不是合法运算符后,我终于弄清楚了……如果您好奇,这就是我所做的:

int replaceByte(int x, int n, int c) {
  int mask = 0xff << (n << 3);
  int shift = (c << (n << 3));
  return (~mask & x) | shift;
}
4

3 回答 3

7

由于这看起来像家庭作业,我不会发布代码,而是列出您需要执行的步骤:

  1. 转换c为 32 位数字,这样在移位时不会丢失任何位
  2. 接下来,c向左移动适当的位数(如果n==0不移位,如果n==1移位 8 等)
  3. 创建一个 32 位位掩码,将 的最低 8 位归零x,然后将此掩码移动与上一步相同的量
  4. 对移位的位掩码执行按位与运算并将x适当的位清零x
  5. 执行移位c值的按位或(或加法)并x替换后者的屏蔽位
于 2012-04-12T22:48:24.740 回答
6

啊……你快到了。

只是改变

return (mask & x) | shift; 

return (~mask & x) | shift;

mask应该包含除了要屏蔽的区域之外的所有区域,反之亦然。

我正在使用这个简单的代码,它在 gcc 中运行良好

#include<stdio.h>

int replaceByte(int x, int n, int c) 
{
    int shift = (c << (8 * n));
    int mask = 0xff << shift;
    return (~mask & x) | shift;
}

int main ()
{

    printf("%X",replaceByte(0x80000000,0,0));

    return 0;
}
于 2012-04-13T03:11:58.663 回答
3

正确的解决方案也适用于 c = 0:

     int replaceByte(int x, int n, int c)
     {
        int shift = 8 * n;
        int value = c << shift;
        int mask = 0xff << shift;

        return (~mask & x) | value;
     }
于 2019-04-15T03:20:45.017 回答