我尝试使用左移来使用计数器来识别setbit。当我尝试左移var时,我发现它陷入了无限循环,只有零被打印。以下代码有什么问题?在while循环内使用左移甚至合法吗?
#include <stdio.h>
#include <limits.h>
int main(int argc, char **argv)
{
int var =1;
while(var<INT_MAX)
{
var = var<<1;
printf("%d\n", var);
}
return 0;
}
在循环内使用移位操作非常好。您的代码存在的问题是var
永远不会等于或大于INT_MAX
。
为了更好的理解,让我用8位有符号整数而不是32位有符号整数解释问题。
您以值var = 00000001b
开头(b
表示它是一个二进制数),而8位带符号整数的INT_MAX
为INT_MAX = 01111111b = 127
(请注意,最高位为0,这是因为它是符号位)
现在,如果您向左移动var
,则将此单1缓慢向右移动
var << 1 = 00000010b = 2
var << 2 = 00000100b = 4
var << 3 = 00001000b = 8
var << 4 = 00010000b = 16
var << 5 = 00100000b = 32
var << 6 = 01000000b = 64
var << 7 = 10000000b = -128
var << 8 = 00000000b = 0
在第七次移位后,1位达到最高位,但是由于我们有一个8位带符号整数,因此我们将10000000b
解释为不是128
,而是解释为-128
,因此var < INT_MAX
将始终为真。
如果您不知道为什么会这样,您可能需要阅读two complement号。
在此循环中
while(var<INT_MAX)
{
var = var<<1;
printf("%d\n", var);
}
var永远不能等于INT_MAX,因为其中只设置了一位
int var = 1;
已转移。
尝试以下循环:
while(var<INT_MAX)
{
var = ( var << 1 ) + 1;
printf("%d\n", var);
}
这里是一个演示程序,为简单起见,这里使用了签名类型signed char,而不是使用signed type int。
#include <stdio.h>
#include <limits.h>
int main(void)
{
signed char var = 1;
while ( var < SCHAR_MAX )
{
var = ( var << 1 ) + 1;
printf( "%d\n", var );
}
return 0;
}
程序输出为
3
7
15
31
63
127
并且根据C标准(5.2.4.2.1整数类型<limits.h>
的大小]
— maximum value for an object of type signed char
SCHAR_MAX +127 // 2^7 − 1