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博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值