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

来源:互联网 发布:java opencv 人脸比对 编辑:程序博客网 时间:2024/06/05 16:44
关于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。
因此下面的结果也就不难理解了。
  1. a = 1; printf("%d %d\n", a, a++);
  2. a = 1; printf("%d %d %d\n", a, a++, a);
  3. a = 1; printf("%d %d %d %d\n", a, ++a, a++, a);
其结果是
  1. 2 1
  2. 2 1 2
  3. 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






0 0
原创粉丝点击