为什么这个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                
}