为什么这个C程序中的for循环会打印11次Hi?
Why does this for loop in C program print Hi 11 times?
#include <stdio.h>
int main()
{
int i = 1024;
for (; i; i >>= 1)
printf("Hi");
return 0;
}
为什么for循环会打印11次Hi?没看懂。
表达式i >>= 1
等价于i = i / 2
所以如果最初 i
等于 1024
那么循环体将针对值
执行
1024 512 256 128 64 32 16 8 4 2 1
也就是11次。由于整数运算,表达式 1 / 2
的值等于 0
。
您可以通过更改 printf 的调用来检查
#include <stdio.h>
int main( void )
{
int i = 1024;
for (; i; i >>= 1) printf( "%d ", i );
putchar( '\n' );
}
按位右移运算符示例:
int x = 1024
int z = x >>=1 # right shift operator
// then printing z will print 512, i.e. x/2
因此,现在如果您在更新示例中 'i' 的值时使用 for 循环继续更新 z 的值,您将看到 'i' 或 'z' 将低至 1(因为 'i' 是 int 类型)
# include <stdio.h>
# include <iostream>
int main()
{
int i = 1024;
for (; i; i >>= 1)
std::cout << "\n" << i;
return 0;
}
在你的代码中,因为 i = 1024 (2^10) 最多可以被 2 除 11 次,因此循环打印“Hi”11 次,其中 i = [1024, 512, ....2, 1].
查看此 link 了解更多详情:
https://en.cppreference.com/w/cpp/language/operator_assignment
>>=
运算符将二进制数的位向右移动其右侧的值,并将结果赋值回变量。这里 i
向右移动了 1
。最低有效位(最右边)被丢弃。
for
中间的循环条件只是 i
,这相当于 i != 0
,因为 non-zero 值被认为是“真实的”和零C 中的“假”
1024 在二进制中是 0b10000000000
,即 1 后跟 10 个零。需要向右移动 11 次,直到 1“脱落”并只留下零,这导致循环条件不再为真。
(如其他答案所述,向右移动一位相当于整数除以二,因为向左移动的每个二进制数字的值确实比前一个(一个,二、四、八等),就像十进制一样,值是十的幂(一、十、百等)。然而,这与问题无关,因为我们可以留在bits, as described above. 同样,即使整数除法丢弃小数部分,这也不是 1 >> 1
为零的原因...)
#include <stdio.h>
int main()
{
for (int i = 1024; i>0; i >>= 1) {
printf("%d ", i);
}
// proccess above as follows:
// 1024 (decimal) equal with 00000100 00000000 (binary)
//
// 1024 >>= 1 mean rotate 00000100 00000000 to right one bit (put 0 bit in left positin, values will be shift to right one bit each loop)
// 00000100 00000000 = 1024 (STEP 1) > START
// 00000010 00000000 = 512 (STEP 2)
// 00000001 00000000 = 256 (STEP 3)
// 00000000 10000000 = 128 (STEP 4)
// 00000000 01000000 = 64 (STEP 5)
// 00000000 00100000 = 32 (STEP 6)
// 00000000 00010000 = 16 (STEP 7)
// 00000000 00001000 = 8 (STEP 8)
// 00000000 00000100 = 4 (STEP 9)
// 00000000 00000010 = 2 (STEP 10)
// 00000000 00000001 = 1 (STEP 11) > FINISH
}
#include <stdio.h>
int main()
{
int i = 1024;
for (; i; i >>= 1)
printf("Hi");
return 0;
}
为什么for循环会打印11次Hi?没看懂。
表达式i >>= 1
等价于i = i / 2
所以如果最初 i
等于 1024
那么循环体将针对值
1024 512 256 128 64 32 16 8 4 2 1
也就是11次。由于整数运算,表达式 1 / 2
的值等于 0
。
您可以通过更改 printf 的调用来检查
#include <stdio.h>
int main( void )
{
int i = 1024;
for (; i; i >>= 1) printf( "%d ", i );
putchar( '\n' );
}
按位右移运算符示例:
int x = 1024
int z = x >>=1 # right shift operator
// then printing z will print 512, i.e. x/2
因此,现在如果您在更新示例中 'i' 的值时使用 for 循环继续更新 z 的值,您将看到 'i' 或 'z' 将低至 1(因为 'i' 是 int 类型)
# include <stdio.h>
# include <iostream>
int main()
{
int i = 1024;
for (; i; i >>= 1)
std::cout << "\n" << i;
return 0;
}
在你的代码中,因为 i = 1024 (2^10) 最多可以被 2 除 11 次,因此循环打印“Hi”11 次,其中 i = [1024, 512, ....2, 1].
查看此 link 了解更多详情: https://en.cppreference.com/w/cpp/language/operator_assignment
>>=
运算符将二进制数的位向右移动其右侧的值,并将结果赋值回变量。这里 i
向右移动了 1
。最低有效位(最右边)被丢弃。
for
中间的循环条件只是 i
,这相当于 i != 0
,因为 non-zero 值被认为是“真实的”和零C 中的“假”
1024 在二进制中是 0b10000000000
,即 1 后跟 10 个零。需要向右移动 11 次,直到 1“脱落”并只留下零,这导致循环条件不再为真。
(如其他答案所述,向右移动一位相当于整数除以二,因为向左移动的每个二进制数字的值确实比前一个(一个,二、四、八等),就像十进制一样,值是十的幂(一、十、百等)。然而,这与问题无关,因为我们可以留在bits, as described above. 同样,即使整数除法丢弃小数部分,这也不是 1 >> 1
为零的原因...)
#include <stdio.h>
int main()
{
for (int i = 1024; i>0; i >>= 1) {
printf("%d ", i);
}
// proccess above as follows:
// 1024 (decimal) equal with 00000100 00000000 (binary)
//
// 1024 >>= 1 mean rotate 00000100 00000000 to right one bit (put 0 bit in left positin, values will be shift to right one bit each loop)
// 00000100 00000000 = 1024 (STEP 1) > START
// 00000010 00000000 = 512 (STEP 2)
// 00000001 00000000 = 256 (STEP 3)
// 00000000 10000000 = 128 (STEP 4)
// 00000000 01000000 = 64 (STEP 5)
// 00000000 00100000 = 32 (STEP 6)
// 00000000 00010000 = 16 (STEP 7)
// 00000000 00001000 = 8 (STEP 8)
// 00000000 00000100 = 4 (STEP 9)
// 00000000 00000010 = 2 (STEP 10)
// 00000000 00000001 = 1 (STEP 11) > FINISH
}