代码之家  ›  专栏  ›  技术社区  ›  Lennart Koopmann

有人能解释一下C函数吗?

c
  •  -1
  • Lennart Koopmann  · 技术社区  · 17 年前

    我对这个语法有一些问题。有人能给我解释一下这个C函数在做什么吗?

    unsigned long protodec_henten(int from, int size, unsigned char *frame)
    {
       int i = 0;
       unsigned long tmp = 0;
    
       for (i = 0; i < size; i++)
         tmp |= (frame[from + i]) << (size - 1 - i);
    
       return tmp;
    }
    

    谢谢您!

    7 回复  |  直到 17 年前
        1
  •  15
  •   JaredPar    17 年前

    我猜你指的是下面这行语法混乱的那一行。

    tmp |= (frame[from + i]) << (size - 1 - i);
    

    让我们把这个分解

    • frame[from+i]:“from”表示数组的初始索引,i只是当前偏移量。因此,这实际上是从索引“from”开始迭代数组
    • 大小-1-i:这是在计算要移位的位数,并基于当前索引执行此操作。这个数字将从-1开始,并随着循环的进行而减小。
    • (帧[From+I]<<(大小-1-I):这将值从+I移动指定位数
    • TPM =…:dos对迭代值移位后仍可用的字节执行按位或表达式。
        2
  •  7
  •   viraptor    17 年前

    其他人已经对每一行进行了描述,所以我只需添加函数 做 . 你可以想象字节 frame 位置之间( from )和( from+size )在不同位置的“堆栈”上。第一个字节将放在左侧。

    bits from:      tmp: |    +  +     |(LSB-side of tmp)
    frame[from]:           ---+----
    frame[from+1]:          -----+--
    frame[from+2]:           -+------
    ...
    

    现在TMP有一个位集,如果“下面”的任何字节在相关位置有一个位集。

        3
  •  2
  •   TMN    17 年前

    看起来像个打包机。如果,正如埃里克建议的,所有的角色 frame 要么是零要么是一,那么这就需要 size 并将其值打包到 tmp . 例如,如果 框架 (偏移) start )包含值 00 01 00 00 01 01 01 00 然后 protodec_henten(0,8,frame) 将返回(省略前导零)0x4E(或 01001110 二进制的)有更好的方法可以做到这一点,所以它可能在做其他的事情,但很难说是什么。

        4
  •  0
  •   Filip Ekberg    17 年前

    我想你不明白 tmp |= 因为这可能是代码中唯一“难以理解”的部分。如果您尝试搜索c运算符,您将找到一个列表 here 现在 |= 意思是“按位或”,你可以阅读更多关于它们的信息。 here .

    所以这段代码真正做的是需要一些输入,告诉函数从哪里开始在“buffer”/“frame”中读取,然后按“size”参数所示按位或按任意位置读取。

        5
  •  0
  •   Benjamin Autin Andrés Bonilla    17 年前

    看起来像哈希函数。 第二种想法是,这将产生一个非常差的哈希函数。

    它们将每一帧的大小都移动了剩余部分,然后用一个静态值对其进行O形环操作。然后返回该值。

        6
  •  0
  •   Eric Bainville    17 年前

    由于按位或,只有当所有值都在 frame 是0还是1。

    在这种情况下,它会 size 连续值(即位) 框架 从索引开始 from 成单一 unsigned long . 最后一位(在索引处 from+size-1 )将作为最低有效位插入。

        7
  •  -3
  •   Tim Rupe    17 年前

    整个代码只是将一系列数据复制到tmp变量中。事实上,它只是以一种艰难的方式做一个记忆。

    为什么不直接做:memcpy(&tmp,frame+from,size)