c语言printf函数处理输出值参数如何处理
举例:
#include<stdio.h>
int main()
{
int i = 0;
printf("%d,%d,%d\n", --i, --i, i++);
}
有人会认为打印结果为:0,0,-1
但实际打印结果为:
相信大家都知道,printf()这个函数在打印参数内容时,入栈是从右往左的,当有多个参数时,先遍历一遍参数然后在依次打印。
那么,上述例子入栈顺序也就是i++、i–、i–。(入栈同时计算,出栈直接输出并不计算。栈先进后出)
栈:栈相当于一个水瓶子,往里面放东西,最先进去的在栈底,所有只有等上面的所有的都出去了,栈底的东西才能出来,即先进后出。
那么,上述例子,i=0,i++先运算后加,输出结果是0但i变成1了,后面–i先减后运算,不是应该是0??
到底为什么?
解释
(1)处理表达式i++
当处理表达式i++时,cpu中寄存器将最初i=0放入一个临时整型大小的地址(相当于副本,副本为0),寄存器将i+1存储到原来i的内存中(真值为1)。
(2)处理表达式–i,寄存器将i-1存储到原来i的内存中(此时的i为1,真值为0,无副本)。
(3)处理表达式–i,寄存器将i-1存储到原来i的内存中(此时的i为0,真值为-1,无副本)。
(4)最后,通过寄存器将临时地址的值(副本)入栈(i++),通过寄存器将内存中i的入栈(最后内存那个真值i,-1,并非此刻那个i,0,处理中间–i),通过寄存器将内存中i的入栈。
栈 | 表达式 | 真值 | 副本 |
---|---|---|---|
栈顶 | - -i | -1 | 无 |
- -i | 0 | 无 | |
栈底 | i++ | 1 | 0 |
结论
对于前置++、–(即++a、–a),它只进行真值加一的操作(不进行将自己拷贝一次)。
对于后置++、–(即a++、a–),它先将自己拷贝存储(副本),然后真值加一。
最后,前置输出最后那个真值,后置输出副本的值。