3

我在 K&R II C Programming ANSI C 书中读到“>>”和“<<”运算符控制位,当然,作为菜鸟,我不明白何时使用它们。我对弄清楚如何手动构建数据包很感兴趣,我遇到了以下代码段:

unsigned short csum(unsigned short *buf, int nwords)
{       
        unsigned long sum;
        for(sum=0; nwords>0; nwords--)
                sum += *buf++;
        sum = (sum >> 16) + (sum &0xffff);
        sum += (sum >> 16);
        return (unsigned short)(~sum);
}

我知道这会计算校验和,但我不明白这里发生了什么。XD

显然这超出了我的技能范围,但我想我可以使用这个片段作为替罪羊来找出一些悬而未决的问题。您何时知道何时使用按位运算符来实现某个值,为什么不直接加 (+) 或减 (-)?另外,如果两者没有运算符,为什么&0xffff旁边有一个十六进制?sum

PS是什么~sum意思?

4

3 回答 3

1

您所说的一切都与位级别的操作有关。例如,“var >> num”将 var 向右移动 num(这意味着它将 var 除以 2^num)。~var 也会在位级别反转 var(例如,如果 var = 5 in bit notation= 101 ----> ~var = 010)

于 2012-06-05T15:12:26.090 回答
1

你什么时候知道什么时候使用按位运算符来实现某个值

当您需要对对象的各个位进行操作时,请使用按位运算符,而简单的整数算术要么不够用,要么不太清楚地描述代码的意图。

我知道这听起来很简单,但实际上就是这么简单。

为什么&0xffff旁边有一个十六进制sum

&是位与运算符。在这种情况下,它用于实现位掩码

是什么~sum意思?

~是按位逆运算;它反转每个位的值。

我希望在您用来学习 C 的任何书中都解释了这些运算符中的每一个。

于 2012-06-05T15:13:42.073 回答
1

这不是一个问题,这是一大堆问题。:)

  1. 当您想将数字视为位集合而不是整数时,可以使用位运算符。说“我想要这个位模式向左移动两位”比创建数学上等效的操作要容易得多。它们在概念上是不同的;如果您将数字视为位,则使用位运算符更有意义。
  2. 通过& 0xffff屏蔽所有高位来确保该值为 16 位。这假设系统的unsigned long宽度至少为 16 位,这是一个非常安全的假设。( &bitwise AND) 通常用于此目的。查看逻辑合取的真值表并认为“假为 0,真为 1”以了解其工作原理。
  3. 十六进制常量之前是 C的&按位与运算符,用于进行我上面描述的屏​​蔽。基本上,对于一位变量a & b,结果是1当且仅当两者ab都是1。运算符将此逻辑应用于其输入项中的每对位。
  4. 运算符是 C的~按位反转,它“翻转”其参数的位。它通常用于创建蒙版。
于 2012-06-05T15:13:51.970 回答