您的位置:首页 > 其它

关于printf参数与栈的问题的一点认识

2017-02-25 11:31 281 查看
关于printf参数与栈的问题的一点认识

首先,pritnf中参数是由右开始进栈的

然后依次出栈,这样就与格式符中由左向右一一对应了。
如:printf("%d1 %d2 %d3 %d4", a, b, c, d );
由参数入栈后的顺序是;d, c, b, a,所得的栈为:
|a   |<-栈顶
|b   |
|c   |
|d   |<-栈底
他们出栈的顺序就是一直出栈,得a, b, c, d这与"%d1 %d2 %d3 %d4"格式符相对应。

其次,对于增量运算符,前缀与后缀的区别。

经过参照:
1,++做前缀和做后缀到底有什么本质区别? - 知乎上面说: 编译器行为的区别 - 后置的时候为了能够返回加之前的值,编译器会给你构造一个临时变量用于参与整个表达式,
2,++、--前后缀区别 - RandomName的专栏 - 博客频道 - CSDN.NET
上面的意思也 就是说,如果a++出现在整个表达中,参与表达式运算的是a的一个临时变量。而不是a。a去完成了自增运算。所以a++;语句可以写为tmp=a;  ++a;

3,printf 参数入栈顺序 - 博客频道 - CSDN.NET
对于a++的结果,是有ebp寻址函数栈空间来记录中间结果的,在最后给printf压栈的时候,再从栈中把中间结果取出来

也说明了:
a++过程中的这个临时变量的出处,也就是这个中间变量由ebp寻址函数栈空间来记录的。
同时,也说明,当a++作为printf()的参数压栈时,压入的是这个临时变量,而非变量a。
因此下面的结果也就不难理解了。

a = 1;   printf("%d %d\n", a, a++);

a = 1;   printf("%d %d %d\n", a, a++, a);

a = 1;   printf("%d %d %d %d\n", a, ++a, a++, a);


其结果是

2 1

2 1 2

3 3 1 3


对于第一个语句:a = 1; printf("%d
%d\n", a, a++);
压栈后为:
|a       | <-顶
|tmp = a,| ++a;
<-底
正如上所述,因为a++在栈底实际上压入的是临时变量tmp
= a;而a又完成了自增。
所以出栈时,结果为:2 1

对于第二语句:a=1;
printf("%d
%d %d\n",
a,
a++,
a);

压栈后为:

|a       | <-顶

|tmp = a,| ++a;

|a       | <-底

同样,a++在栈中实际上压入的是临时变量tmp = a;而a又完成了自增。

所以出栈时,结果为:2 1 2

对于第三语句a=1;
printf("%d
%d %d %d\n",
a,++a,
a++,
a);

压栈后为:

|a       | <-顶

|++a,    | ;

|tmp = a,| ++a;

|a       | <-底

同样,a++在栈中实际上压入的是临时变量tmp = a;而a又完成了自增。

所以出栈时,结果为:3 3 1 3
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: