C代码的说明

时间:2011-01-27 03:18:16

标签: c

以下代码的含义是什么:

WORD len;  
LWORD in;  
LWORD out;

WORD buff_dlen(CBUFF *bp)
{
    return((WORD)((bp->in - bp->out) & (bp->len - 1)));
}

我理解bp->in - bp->out表示inout之间存在差异,但它与& (bp->len - 1);有什么关系?

3 个答案:

答案 0 :(得分:2)

该函数返回可用于在二次幂大小的环形缓冲区中读取的空间。

答案 1 :(得分:1)

&运算符将返回值bp->in - bp->outbp->len - 1之间的逻辑AND(每位数)。

答案 2 :(得分:0)

阐述我的评论:我认为这个片段来自netutil.c中的嵌入式TCP / IP实现。如果这是正确的,CBUFFnetutil.h中定义为:

/* Default circular buffer size: MUST be power of 2 
** This definition is for initialisation only, and may be overriden to 
** create a larger or smaller buffer. To determine the actual buffer size, all 
** functions MUST use the 'len' value below, not the _CBUFFLEN_ definition */ 
#ifndef _CBUFFLEN_ 
#define _CBUFFLEN_ 0x800 
#endif 
/* Circular buffer structure */ 
typedef struct 
{ 
    WORD len;                   /* Length of data (must be first) */ 
    LWORD in;                   /* Incoming data */ 
    LWORD out;                  /* Outgoing data */ 
    LWORD trial;                /* Outgoing data 'on trial' */ 
    BYTE data[_CBUFFLEN_];      /* Buffer */ 
} CBUFF;

似乎inout成员在缓冲区中是偏移量,“指向”输入和输出数据开头的位置。由于这是一个循环缓冲区,因此从out中减去in有两种可能性(可能是确定传入数据长度的方法):

  • in > out:结果是一个小于len的正数。因此,按位&无效,因为任何小于0x800 0x7FF的数字都是数字本身。
  • out > in:在这种情况下,结果为负数,介于0-len之间;传入的数据“环绕”循环缓冲区。这比较复杂,因为它依赖于负数如何在内存中表示。一些例子可能有助于阐明正在发生的事情(回想一下,十进制中的0x800是2048):

bp->in-bp->out  |  representation  |  &'ed with 0x7FF   | decimal representation
----------------+------------------+--------------------+-----------------------
     -1         |      0xFFFF      |       0x07FF       |      2047 (2048-1)
     -2         |      0xFFFE      |       0x07FE       |      2046 (2048-2)
     -10        |      0xFFF6      |       0x07F6       |      2038 (2048-10)
     -2046      |      0xf802      |       0x0002       |      2    (2048-2046)
     -2047      |      0xf801      |       0x0001       |      1    (2048-2047)

正如您所看到的,这是一种简单的技术,可以“解包”循环缓冲区并检索inout之间的有效距离。