代码执行的结果是什么? C 运算符优先级

What will be result of code execution? C Operator Precedence

我无法预测下面链接的代码的结果。 为什么程序正在打印 2 0 6 0 10 0 16 0 20 0 ?我想这完全是关于运算符的优先级,但经过一段时间的思考后,我无法意识到我的解释有什么问题。你能解释一下吗?

#include <stdio.h>

int main(void)
{
    int tab[10] = {2,4,6,8,10,14,16,18,20};
    int *pi, i;
    for(pi = tab; ++pi < tab+9;)
    {
        *pi++ = 0;
        *pi *= 2;
    }

    for(int i=0; i<10; i++)
        printf("%d ", tab[i]);

    return 0;
}

实际输出为2 0 12 0 20 0 32 0 40 0(如Blastfurnace评论https://ideone.com/UUy8QO所示)

pi 最初确实在第一个单元格上,但您的停止条件会增加指针。因此,在循环内部,对于第一条指令,pitab[1] 中。它首先将此单元格置为 0,然后用 ++ 递增。在第二行,它使值加倍,因此它加倍 tab[2]。然后,停止条件再次递增指针,依此类推。

for 循环做的第一件事是在 tab 处指向 pi,即 pi=&tab[0] 所以 pi 指向数字 2。下一段要执行的代码是 for 循环的 "condition" 语句 ++pi < tab+9。这首先递增 pi(所以它现在指向 tab[1] 中的数字 4)并检查它是否仍然指向 tab 的成员,早于最后的 20.

for循环体中,行*pi++ = 0;首先在pi指向的地址存储了一个0(这意味着tab[1]现在是0 而不是 4),然后 (post-) 递增 pi 指向 tab[2],即 6。然后行 *pi *= 2; 将 [= 指向的值加倍11=],所以 tab[2] 变成 12.

接下来发生的事情是重新计算 for 循环的条件语句(因为它的迭代语句为空):pi 递增并检查。

其余的迭代相当平静。 tab的最终状态是第一个成员不变,索引为奇数的成员为零,其他成员从初始值翻倍。

关于运算符和优先级的一般建议:几乎总是两种情况之一。第一个是您和编译器不同意代码中运算符的应用顺序——换句话说,您的代码没有按照您的预期执行。第二个是您完全理解编译器将要做什么,但阅读您的代码的程序员却不理解——换句话说,您的代码没有按照 他们 的预期进行。幸运的是,这两种情况都可以通过添加括号来消除任何疑问来缓解。