K&R C 第 2 章赋值运算符和表达式
K&R C chapter 2 assignment operators and expressions
赋值运算符不是我期望的困难。到目前为止,本节中的所有内容都很熟悉,但他们解释它的方式让它看起来很陌生。我认为这是我感到困惑的位运算符。
无论如何这是我没有得到的部分。
The function bitcount
counts the number of 1-bits in its integer argument.
/*bitcount: count 1 bits in x */
int bitcount (unsigned x)
{
int b;
for(b=0; x != 0; x >>= 1) {
if(x & 01)
b++;
return b;
}
Declaring the argument x
to be unsigned ensures that when it is right-shifted, vacated bits will be filled with zeros, not sign bits, regardless of the machine the program is run on.
并不是说我真的理解代码,但最后一句话让我最困惑。这是什么意思? “符号位”表示“一”吗?这与二进制补码有关吗?
我真的很难完成按位运算。谁能推荐一些全面的 material 来补充本书中的按位内容?
假设x
是二进制补码。为了便于说明,让我们使用八位宽度。 (C 总是以更宽的宽度移动,至少 int
。)
如果x
是64(010000002),我们将它右移一位,我们得到32(001000002).当我们重复它时,我们得到 16 (000100002), 8 (000010002), 4 (000001002)、2 (000000102) 和 1 (000000012).
当x
为-64时,补码表示为110000002。如果我们将其右移并引入 0 位,则这些位为 011000002,表示 64+32 = 96。因此 −64 变为 96。现在,如果一个只是在使用位。但是,如果我们想使用移位来除数,我们需要 −32,而不是 96。−32 的位是 111000002。所以我们可以通过引入 1 位而不是 0 位来获得它。 −16 的位是 111100002。则-8、-4、-2、-1分别为111110002、111111002、111111102, 111111112。在每种情况下,我们在移位时都带入一个 1 位。
因此,如果我们想使用位移位进行除法,那么一位位移有一个简单的规则:将所有位右移一个位置并保持符号位不变(0 或 1)。如果我们要移动多于一位,请继续复制符号位。
这叫做算术右移。因此,我们有两种右移:一种是复制符号位的算术右移,另一种是带入 0 位的逻辑右移。
对于无符号类型,C 标准规定右移是合乎逻辑的。
对于有符号类型,C 标准并没有说明它是算术类型还是逻辑类型。它将它留给实现来定义该实现使用的(或可能定义其他东西)。这可能是由于历史原因;早期的机器可能没有提供算术右移指令(甚至可能没有使用二进制补码),尽管现在似乎很难想象。
因此,当您编写向右移位的代码并且希望确定将得到的结果时,您可以使用无符号类型来确保得到逻辑移位。
在二进制补码表示中,最高位保留给符号。正数最高位为 0,负数最高位为 1。
如果将负数的位右移,则最初位于最高位的 1 将移至下一个较低位,如果继续移位,最终将以最低位结束。
在代码中,for 循环将 x 的位移动一位并将移位后的值分配给 x。
for (b = 0; x != 0; x >>=1 )
首先b,用于统计数字中1位的个数设置为0。
继续循环的条件是 x != 0。当所有的 1 位从 x 移出时,唯一剩下的将是 0 位。 x 将等于 0.
每次迭代后执行的操作是将x中的值右移1。
循环体中的 if 条件对 x 执行按位与操作。位掩码的值为 1,这是 int 值的一个实例,除最低位外所有位均为 0。如果最低位为 1,则该 AND 运算将评估为 1(或在 C 中为真),如果最低位为 0,则为 0(或在 C 中为假)。如果 if 条件为是的。
赋值运算符不是我期望的困难。到目前为止,本节中的所有内容都很熟悉,但他们解释它的方式让它看起来很陌生。我认为这是我感到困惑的位运算符。
无论如何这是我没有得到的部分。
The function
bitcount
counts the number of 1-bits in its integer argument./*bitcount: count 1 bits in x */ int bitcount (unsigned x) { int b; for(b=0; x != 0; x >>= 1) { if(x & 01) b++; return b; }
Declaring the argument
x
to be unsigned ensures that when it is right-shifted, vacated bits will be filled with zeros, not sign bits, regardless of the machine the program is run on.
并不是说我真的理解代码,但最后一句话让我最困惑。这是什么意思? “符号位”表示“一”吗?这与二进制补码有关吗?
我真的很难完成按位运算。谁能推荐一些全面的 material 来补充本书中的按位内容?
假设x
是二进制补码。为了便于说明,让我们使用八位宽度。 (C 总是以更宽的宽度移动,至少 int
。)
如果x
是64(010000002),我们将它右移一位,我们得到32(001000002).当我们重复它时,我们得到 16 (000100002), 8 (000010002), 4 (000001002)、2 (000000102) 和 1 (000000012).
当x
为-64时,补码表示为110000002。如果我们将其右移并引入 0 位,则这些位为 011000002,表示 64+32 = 96。因此 −64 变为 96。现在,如果一个只是在使用位。但是,如果我们想使用移位来除数,我们需要 −32,而不是 96。−32 的位是 111000002。所以我们可以通过引入 1 位而不是 0 位来获得它。 −16 的位是 111100002。则-8、-4、-2、-1分别为111110002、111111002、111111102, 111111112。在每种情况下,我们在移位时都带入一个 1 位。
因此,如果我们想使用位移位进行除法,那么一位位移有一个简单的规则:将所有位右移一个位置并保持符号位不变(0 或 1)。如果我们要移动多于一位,请继续复制符号位。
这叫做算术右移。因此,我们有两种右移:一种是复制符号位的算术右移,另一种是带入 0 位的逻辑右移。
对于无符号类型,C 标准规定右移是合乎逻辑的。
对于有符号类型,C 标准并没有说明它是算术类型还是逻辑类型。它将它留给实现来定义该实现使用的(或可能定义其他东西)。这可能是由于历史原因;早期的机器可能没有提供算术右移指令(甚至可能没有使用二进制补码),尽管现在似乎很难想象。
因此,当您编写向右移位的代码并且希望确定将得到的结果时,您可以使用无符号类型来确保得到逻辑移位。
在二进制补码表示中,最高位保留给符号。正数最高位为 0,负数最高位为 1。 如果将负数的位右移,则最初位于最高位的 1 将移至下一个较低位,如果继续移位,最终将以最低位结束。 在代码中,for 循环将 x 的位移动一位并将移位后的值分配给 x。
for (b = 0; x != 0; x >>=1 )
首先b,用于统计数字中1位的个数设置为0。
继续循环的条件是 x != 0。当所有的 1 位从 x 移出时,唯一剩下的将是 0 位。 x 将等于 0.
每次迭代后执行的操作是将x中的值右移1。
循环体中的 if 条件对 x 执行按位与操作。位掩码的值为 1,这是 int 值的一个实例,除最低位外所有位均为 0。如果最低位为 1,则该 AND 运算将评估为 1(或在 C 中为真),如果最低位为 0,则为 0(或在 C 中为假)。如果 if 条件为是的。