结论
printf
函数的计算是从右向左进行;- 遇到
i++
,会把此时i
的值当作最后的输出值,注意,确定为输出后,i
还会自增; - 遇到
i
或++i
,仅仅修改当前i
的值,最后才输出i
。
例子
#include<stdio.h>
int main()
{
int i=2;
printf("%d,%d,%d,%d,\n",i++,++i,i,i++);
printf("%d\n",i);
return 0;
}
输出:
4,5,5,2,
5
分析
从右往左看:printf("%d,%d,%d,%d,\n",i++,++i,i,i++);
首先,i++
,第四位的输出定格在2
,再运算,i
的值是3
。
其次,i
,第三位的输出不能确定,因为前面还有运算,此时i
是3
。
然后,++i
,先运算,此时i
的值是4
,但第二位的输出还不能确定。
最后,i++
,第一位的输出定格在4
,再运算,i
的值是5,此时可以确定倒数第二位和第三位的输出都是5。
验证
有人不信“最后”的分析,也就是说不相信printf
中的i
和++i
是等所用运算完毕后,由最终的i
确定,那么我们在printf
的第一位再加个++i
。理论上,这个++i
是最后执行,i
会由5变成6,且6作为从右往左数第2,3,5位的输出。
#include<stdio.h>
int main()
{
int i=2;
printf("%d,%d,%d,%d,%d,\n",++i,i++,++i,i,i++);
printf("%d\n",i);
return 0;
}
结果是:
6,4,6,6,2,
6
与理论相符。
拓展:C函数参数计算顺序
#include <stdio.h>
void fn(int a,int b,int c)
{
printf("%d,%d,%d", a, b, c);
}
int main()
{
int a = 3;
fn(a++, a++, a++);
return 0;
}
输出:
5,4,3
分析: C函数参数作为一个整体执行的顺序是从右向左,所以会先处理最右端的参数,然后依次向左处理。所以结果为最右端的a++先被处理结果为3,然后++,接着4和5,这样就有了上面的结果。
究极测试
下面程序的输出是什么?
#include <bits/stdc++.h>
using namespace std;
int fun(int n, int m) {
int j=1;
j*=++n+m--;
return j;
}
int main( ) {
int k;
for(k=0;k<5;k++){
printf("%d,%d\n", k,fun(k++,k++)+(++k));
printf("%d\n", k);
}
return 0;
}
输出:
3,5
3
7,17
7
分析:记住原则,在函数参数列表中,计算从右往左;在一条语句中,计算从左往右。
printf("%d,%d\n", k,fun(k++,k++)+(++k));
是printf
函数,它有两项参数,从左到右是:k
,fun(k++,k++)+(++k)
。因此计算时是先fun(k++,k++)+(++k)
再k
。
fun(k++,k++)+(++k)
是一条语句,因此先计算fun(k++,k++)
再加上(++k)
。
- 计算
fun(k++,k++)
:第一次进for
循环,k=0
,按照从右往左的顺序计算,第一个传进去的是0,然后k变为1,第二个传进去的是1,然后k变为2。 - 计算
(++k)
:执行完fun(k++,k++)
,k是2,再看(++k)
,先加后用,(++k)
呈现出来是3,此时k也是3。fun(k++,k++)
返回2,再加上(++k)
是3,因此fun(k++,k++)+(++k)
为5,该位置输出5。 - 再看
printf
中的第一个输出k
,经过fun(k++,k++)+(++k)
的运算,k此时为3,因此输出3。 - 最后看
printf("%d\n", k);
其实和上面的k一样,也是3。