我不理解下面这行C代码

4
3个回答

7

<<按位左移运算符,它将给定值的位向左移动。因此1L<<(32-maskbits)将值1向左移动32-maskbits次。

&按位与运算符

因此循环表达式mask & (1L<<(32-maskbits)) == 0测试mask值内所有位,从低到高。循环将在mask的第一个(最低)非零位停止,在该点maskbits将包含上面(包括)该位的位数。

例如:

  • 如果mask == 0xFFFFmask == 0xFFFFFFFF(==二进制11111111111111111111111111111111),循环将在第一次迭代时停止,并且maskbits将为32
  • 如果mask == 0x0001mask == 0x00000001(==二进制00000000000000000000000000000001),循环将再次在第一次迭代时停止,并且maskbits将为32
  • 如果mask == 0x1000mask == 0x01000000(==二进制00000001000000000000000000000000),循环将在第24次迭代时停止,并且maskbits将为8

1
为了避免整数溢出,建议在某些平台上使用 long 类型来声明变量。因为在这些平台上,int 类型只有 16 位长,如果你将任何 int 值左移超过 16 位,结果是未定义的(可能为 0)。而将值声明为 long 可以确保它至少有 32 位长。 - Péter Török
还有一个问题:我对“1L”语句有点困惑。它到底是什么? - mspoerr
@mspoerr:这是一个长整型变量。请阅读Peter的评论。 - dierre
@mspoerr: 我写了一个例子,也许能帮到你。 @Peter Torok: 没问题。 - dierre
1
有符号值的移位操作是棘手的,可能导致未定义的行为。在这个例子中,如果long的宽度为32,对于maskbits的值为1,移位操作1L << 31可能会产生未定义的行为。因此,在这里,至少应该将1L替换为1UL,以获得一个无符号长整型的掩码值。更好的做法是使用UINT32_C(1)来代替。 - Jens Gustedt
显示剩余3条评论

1

想知道发生了什么:运行它。

#include <stdio.h> 
#include <iostream>
using namespace std;

char *binary (unsigned int v) {
static char binstr[33] ;
int i ;

binstr[32] = '\0' ;
for (i=0; i<32; i++) {
binstr[31-i] = v & 1 ? '1' : '0' ;
v = v / 2 ;
}

return binstr ;
}

int main(void){  

  unsigned long maskbits,mask;  

mask = 0x01000000;
cout << "MASK IS: " << binary(mask) << "\n";
cout << "32 is: " << binary(32) << "\n\n";
for ( maskbits=32 ; (mask & (1L<<(32-maskbits))) == 0 ; maskbits-- ) {
cout << "maskbits: " << binary(maskbits) << "\n";
cout << "\t(32-maskbits): " << binary((32-maskbits)) << "\n";
cout << "\t1L<<(32-maskbits): " << binary((1L<<(32-maskbits))) << "\n";
cout << "\t(mask & (1L<<(32-maskbits))): " << binary((mask & (1L<<(32-maskbits)))) << "\n\n";

}

cout << "\nFinal maskbits: " << maskbits;

return 0;
}

http://ideone.com/eB8Kp



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