printf函数输出顺序的理解

printf函数输出规则的理解

背景内容

注意:笔者并未研究printf的实现源码,仅从调用结果分析该问题,如有理解不当之处请指正。
最近使用printf()函数碰到了一个有趣的现象。

int j=0;
printf("[%x][%x][%x][%x]\n",j++,j++,j++,j++); //Result: [3] [2] [1] [0]

原本以为输出结果是[0] [1] [2] [3],没想到结果是:[3] [2] [1] [0]。而,

printf("[%x] [%x] [%x] [%x]\n", j++, j=j+1, j++, j++); //[3] [4] [1] [0]

竟然是[3] [4] [1] [0]。
因此写了一些测试代码,

int \
j=0; printf("[%x] [%x] [%x] [%x]\n", /*row1*/j++, j++,   j++, j++); //[3] [2] [1] [0]
j=0; printf("[%x] [%x] [%x] [%x]\n", /*row2*/j,   j++,   j++, j++); //[3] [2] [1] [0]
j=0; printf("[%x] [%x] [%x] [%x]\n", /*row3*/j++, j++,   j,   j++); //[2] [1] [3] [0]
j=0; printf("[%x] [%x] [%x] [%x]\n", /*row4*/j++, j=j+1, j++, j++); //[3] [4] [1] [0]
j=0; printf("[%x] [%x] [%x] [%x]\n", /*row5*/j++, ++j,   j++, j++); //[3] [4] [1] [0]
j=0; printf("[%x] [%x] [%x] [%x]\n", /*row6*/j++, ++j,   j++, ++j); //[3] [4] [1] [4]
j=0; printf("[%x] [%x] [%x] [%x]\n", /*row7*/++j, ++j,   ++j, ++j); //[4] [4] [4] [4]

理解内容

由row1~row3可见,
printf()函数从右至左先计算了各个表达式的值,再从左至右进行格式化输出。

由row1,row5,row7可见,
j++表达式返回递增前的值,可能是printf创建了临时变量(猜测"a=j; j=j+1; return a;"),此处保存了临时变量a;
++j表达式返回了递增后的j,此处保存了j;
row1:
=> j++, j++, j++, j++
=> 从右至左计算,返回临时变量tmp
=> step3(tmp3=3, j=4), step2(tmp2=2, j=3), step1(tmp1=1, j=2), step0(tmp0=0,j=1);
=> 从左至右输出(tmp3, tmp2, tmp1, tmp0)。
=> [3] [2] [1] [0]

row5:
=> j++, ++j, j++, j++
=> 从右至左计算,j++返回临时变量tmp,++j返回j
=> step3(tmp3=3, j=4), step2(j=3), step1(tmp1=1, j=2), step0(tmp0=0, j=1);
=> 从左至右输出(tmp3, j, tmp1, tmp0)。
=> [3] [4] [1] [0]

row7:
=> ++j, ++j, ++j, ++j
=> 从右至左计算,++j返回j
=> step3(j=4), step2(j=3), step1(j=2), step0(j=1);
=> 从左至右输出(j, j, j, j)。
=> [4] [4] [4] [4]

同理,row4的step2处返回了j,最终输出4。

那么,

扫描二维码关注公众号,回复: 11980372 查看本文章
int arr[5] = {
    
    0, 1, 2, 3, 4};
int *p = arr;
j=0; printf("[%x][%x][%x][%x]\n", p[j++], p[j++], p[j++], p[j++]);
j=0; printf("[%x][%x][%x][%x]\n", p[++j], p[++j], p[++j], p[++j]);
j=0; printf("[%x][%x][%x][%x]\n", p[j++], p[++j], p[j++], p[++j]);
p = arr;j=0; printf("[%x][%x][%x][%x]\n", *p++, *p++, *p++, *p++);
p = arr;j=0; printf("[%x][%x][%x][%x]\n", *++p, *++p, *++p, *++p);
p = arr;j=0; printf("[%x][%x][%x][%x]\n", *++p, *p++, *++p, *p++);

这段代码的结果会是多少呢?

猜你喜欢

转载自blog.csdn.net/jimaofu0494/article/details/97271909