我对下面链接的代码的预测结果有疑问。
为什么程序正在打印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;
}
答案 0 :(得分:3)
for
循环要做的第一件事是将pi
指向tab
,即pi=&tab[0]
所以pi
指向数字2。下一个要执行的代码是for
循环的“条件”语句++pi < tab+9
。第一个递增pi
(因此现在指向tab[1]
中的数字4),并检查它是否仍指向最后一个20之前的tab
成员。
在for
循环的主体中,行*pi++ = 0;
首先在pi
所指向的地址处存储0(这意味着tab[1]
现在为0,而不是大于4),然后(后置)将pi
递增到指向tab[2]
的6。然后,行*pi *= 2;
将pi
指向的值加倍,所以{ {1}}变为12。
接下来发生的事情是tab[2]
循环的条件语句的重新评估(由于其迭代语句为空):for
被递增并检查。
其余的迭代是相当平稳的。 pi
的最终状态是第一个成员未更改,索引为奇数的成员为零,其他成员从其初始值翻倍。
有关运算符和优先级的一般建议:两种情况之一几乎总是如此。首先是您和编译器不同意代码中运算符的应用顺序,换句话说,您的代码没有达到您的期望。第二个是您完全理解了编译器将要执行的操作,但是程序员却没有读懂代码,换句话说,您的代码没有达到他们的期望。幸运的是,可以通过添加括号消除任何疑问来缓解这两种情况。
答案 1 :(得分:1)
实际输出为2 0 12 0 20 0 32 0 40 0
(如高炉评论https://ideone.com/UUy8QO所示)
pi
确实确实在第一个单元格上,但是您的停止条件使指针递增。因此,在循环内部,对于第一条指令,pi
在tab[1]
中。它首先将该单元格设置为0,然后以++递增。在第二行,它将值加倍,因此将tab[2]
加倍。然后,停止条件再次使指针递增,依此类推。