C语言中,可变参数函数调用的过程?!

以下是一位同学,发送给我的问题。

如下图,是学生在学习完指针章节后,写的测试代码。

他的疑问是:pa为什么指向a[3]的地址啊?

查看程序的输出后,知道他想问的是:为什么第二个printf语句输出的分别是数组a中第3、2、1个元素的地址,即&a[3],&a[2], &a[3]。这一点可以从下面第三个printf输出结果验证——刚好每个元素地址相隔4个字节。

这是个非常有意思的问题?!知识点涉及可变函数的调用过程(参数传递)、指针的自加自减运算!

(1)可变参数函数的调用过程:可变参数函数调用时,因为参数不可知,因此采用自右到左的入栈规则,如下图所讲!

结合上面的例子,我们知道printf语句三个参数入栈顺序为:++pa, pa++, pa,因为初始pa=a,因此入栈后的值为:

要注意,printf输出时顺序刚好与上面入栈相反(先进后出),因此先输出第1个pa,此时值是&a[2]。然后输出pa++,是先输出再++,也就是入栈时的&a[1];最后才是++pa对应的,这个是最难理解的——入栈时是&a[1],为什么最后输出的是&a[2]?

(2)查询资料后,得知:printf函数确实是从右向左遍历参数,但从右向左遍历时不是遍历一次就打印输出一个参数值,而是走完整个过程,统一打印最后一个值。这解释了上面第一和第三个输出。其中有一个特殊的运算符号,后置++,对于后置++来说,他最终不会返回整体统一返回的值,只会返回当时算到这一步时i对应的初始值(入栈时计算得到的值),这解释了第二个输出。

大家可以运行下面例子,看看你理解了没有?!

最后留一个下面的问题,大家算算下面的输出:

int  i = 1;

printf("%d,%d,%d,%d,%d,%d,%d",i,i++,++i,i++,++i,i++,++i)

参考资料:(66条消息) c语言中printf函数与前置后置++的过程分析_不熬夜不抽烟不喝酒的博客-CSDN博客

猜你喜欢

转载自blog.csdn.net/bennyfun79/article/details/127963301