代码执行的结果是什么? 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
最初确实在第一个单元格上,但您的停止条件会增加指针。因此,在循环内部,对于第一条指令,pi
在 tab[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
的最终状态是第一个成员不变,索引为奇数的成员为零,其他成员从初始值翻倍。
关于运算符和优先级的一般建议:几乎总是两种情况之一。第一个是您和编译器不同意代码中运算符的应用顺序——换句话说,您的代码没有按照您的预期执行。第二个是您完全理解编译器将要做什么,但阅读您的代码的程序员却不理解——换句话说,您的代码没有按照 他们 的预期进行。幸运的是,这两种情况都可以通过添加括号来消除任何疑问来缓解。
我无法预测下面链接的代码的结果。
为什么程序正在打印 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
最初确实在第一个单元格上,但您的停止条件会增加指针。因此,在循环内部,对于第一条指令,pi
在 tab[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
的最终状态是第一个成员不变,索引为奇数的成员为零,其他成员从初始值翻倍。
关于运算符和优先级的一般建议:几乎总是两种情况之一。第一个是您和编译器不同意代码中运算符的应用顺序——换句话说,您的代码没有按照您的预期执行。第二个是您完全理解编译器将要做什么,但阅读您的代码的程序员却不理解——换句话说,您的代码没有按照 他们 的预期进行。幸运的是,这两种情况都可以通过添加括号来消除任何疑问来缓解。