【问题标题】:bit reset in a block of memory内存块中的位复位
【发布时间】:2012-10-01 11:17:57
【问题描述】:

我有一块分配了 20 字节(160 位)的内存块,memset 值为 1。每个位代表一个传入数据,如果接收到数据,则设置该位,否则重置。我最初设置了所有 160 位,如果没有收到数据,我将重置。下面是示例代码:

char *buf = malloc(20);
memset(buf,1,20);

recvfun() {
static int index;
index++;
   if(!received)
     *buf = *buf ^ (1<<(160-index));
...
}

我认为 *buf 只会给出 8 位,而不是完整的内存块,所以每次我尝试重置位时,上面的代码只会在前 8 位中重置。如果假设没有收到第 99 个数据,我需要重置第 99 位。你能帮我实现这个目标吗?感谢您宝贵的时间。

【问题讨论】:

    标签: c logic bit-manipulation


    【解决方案1】:

    您需要将其分解为字节索引和位索引,例如改变:

    if(!received)
      *buf = *buf ^ (1<<(160-index));
    

    到:

    if (!received)
    {
        const int byte_index = index / CHAR_BIT;
        const int bit_index = index & (1 << CHAR_BIT - 1);
        buf[byte_index] ^= (1 << bit_index);
    }
    

    还要注意,如果要将所有位初始化为 1,则上述代码中的 memset(buf,1,20); 应为 memset(buf,255,20);

    【讨论】:

      【解决方案2】:

      你需要计算两件事:

      • 块中的索引
      • 位偏移

      计算它的代码非常简单:

      blockindex = index / 8;
      offset     = index % 8;
      

      然后只需通过组合索引和偏移量来设置位:

      buf[blockindex] ^= 1 << offset;
      

      编辑:虽然我的回答使用与 Paul R 相同的原则,但 Paul 的回答在技术上更好,因为他使用正确的常量 (CHAR_BIT) 而不是硬编码 8(我感到羞耻)。

      【讨论】:

        猜你喜欢
        • 2011-11-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-04
        • 2021-06-02
        • 2011-08-20
        • 2011-04-18
        相关资源
        最近更新 更多