C编程 - 位运算符及其使用时机

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
显然,这超出了我的技能范围,但我想我可以用这段代码来解决一些未解答的问题。什么时候你需要使用按位运算符来达到特定的值,为什么不直接使用加(+)或减(-)呢?此外,为什么在sum旁边有一个十六进制的&0xffff ,如果两者没有运算符?
P.S. ~sum是什么意思?
3个回答

1

你所说的一切都涉及到位级操作。例如,“var >> num”将变量向右移动num位(这意味着它将变量除以2^num)。此外,“~var”在位级上反转变量(例如,如果var = 5,则在位表示法中= 101 ----> ~var = 010)。


所以,所有的1变成0,所有的0变成1? - user569322

1
何时使用位运算符来实现特定值?
当您需要操作对象的单个位时,且简单的整数算术不足以满足要求或者会使代码意图不够清晰时,请使用位运算符。
我知道这听起来很简单,但事实上就是这么简单。
为什么在sum旁边有一个十六进制的&0xffff?
&是按位与运算符。在这种情况下,它用于实现一个位掩码。
~sum是什么意思?
~是按位取反操作符;它反转每个位的值。
我希望您正在使用学习C的任何书籍中都能解释这些运算符。

但是为什么在这种情况下不使用算术运算?这对程序意味着什么? - user569322
@Ken:我不知道该怎么回答。这个计算的性质几乎需要位运算。 - Oliver Charlesworth

1

那不是一个问题,那是一堆问题。:)

  1. 当您想将一个数字视为一组位而不是整数时,可以使用位运算符。说“我想将这个位模式向左移动两位”比创建等效的数学操作要容易得多。它们在概念上是不同的;如果您将数字视为位,则使用位运算符更有意义。
  2. & 0xffff 确保值为 16 位,通过屏蔽所有高位来实现。这假定系统的 unsigned long 至少为 16 位宽,这是一个相当安全的假设。位运算符 & 经常用于此目的。查看逻辑合取的真值表 truth table 并思考“false 是 0,true 是 1”以了解其工作原理。
  3. 十六进制常量前面的 & 是 C 的按位与运算符,用于执行上述掩码操作。基本上,对于单比特变量 a & b,仅当 ab 都为 1 时,结果才为 1。该运算符将此逻辑应用于其输入项中的每一对比特。
  4. ~ 运算符是 C 的按位取反运算符,它“翻转”其参数的位。它通常用于创建掩码。

为什么十六进制数前面要加上 & 符号?如果我把它去掉,对程序会有什么影响? - user569322
@Ken 代码的作者只是省略了运算符&和十六进制字面量之间的空格。空格并不总是必要的,以将标记彼此分开,这是这种情况。如果您删除它,它将无法编译,因为两个操作数之间没有运算符。 - Daniel Fischer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接