《C程序设计语言》练习 2-6

本文介绍了一个名为setbits的函数实现,该函数用于将一个整数x中从第p位开始的n位设置为另一个整数y最右侧n位的值。通过详细解释和示例代码展示了如何通过位运算来完成这一任务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

练习 2-6
编写一个函数 setbits(x, p, n, y),该函数返回对 x 执行下列操作后
的结果值:将 x 中从第 p 位开始的 n 个(二进制)位设置为 y 中最右边 n 位的值,x 的其余
各位保持不变。


主要的算法其实就两句话:

int setbits(x, p, n, y)
{
    int a;
    a = ~(~(~0 << n) << (p - 1));
    y = (y & ~(~0 << n)) << (p - 1);
    return x & a | y;
}

多注释完整版

#include <stdio.h>

int setbits(x, p, n, y);

main()
{
    int x, y, z;

    x = 123; // 0000-0111-1011
    y = 456; // 0001-1100-1000

    z = setbits(x, 2, 5, y);//0000-0101-0001

    printf("%d\n", z);
}


/*
    把x
    从p开始n位清掉,
    然后用y的后n位补上
*/
int setbits(x, p, n, y)
{
    int a;

    /*
    a : 清除用过滤器

    a = p(2)开始清掉n(5)位

    a = ~(~(~0 << n) << (p - 1))
    a = ~(~(1111-1111-1111-1111 << 5) << (2 - 1))
    a = ~(~(1111-1111-1110-0000) << 1)
    a = ~(0000-0000-0001-1111 << 1)
    a = ~(0000-0000-0011-1110)
    a = 1111-1111-1100-0001
    */
    a = ~(~(~0 << n) << (p - 1));


    /*
    y : 补上的数据

    y = 取y右边的(n)位,移动到要补的位置上

    y = (y & ~(1111-1111-1111-1111 << 5)) << (2 - 1);
    y = (y & ~(1111-1111-1110-0000)) << 1;
    y = (y & 0000-0000-0001-1111) << 1;
    y = (0000-0001-1100-1000 & 0000-0000-0001-1111) << 1;
    y =  0000-0000-0000-1000 << 1;
    y = 0000-0000-0001-0000
    */
    y = (y & ~(~0 << n)) << (p - 1);


    /*
    先清后补

    x & a | y
    = 0000-0000-0111-1011 & 1111-1111-1100-0001 | 0000-0000-0001-0000

      0000-0000-0111-1011
    & 1111-1111-1100-0001
    | 0000-0000-0001-0000

    -----------------------------------------------------------------------
    清完开始补

    x & a | y
    = 0000-0000-0100-0001 | 0000-0000-0001-0000

      0000-0000-0100-0001
    | 0000-0000-0001-0000

    -----------------------------------------------------------------------
    结果
    x & a | y
    = 0000-0000-0101-0001

    */
    return x & a | y;
}

注释写的我好恶心啊…(`Д´)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值