printf()函数压栈a++与++a的输出

printf()中a++与++a的输出问题

在C语言中有个很常用的函数printf(),使用时从右向左压栈,也就是说在printf("%d %d %d %d\n",a,a++,++a,++a)中,依次从右向左开始计算,计算完后才会往%d中输出,因为有多条赋值语句,所以他是个累加过程,直到压栈结束后输出最终得累加值
下面是几组测试样例:

int a;
 a=1;      printf("%d %d %d %d\n",a,a++,++a,++a);  //4 3 4 4
 a=1;      printf("%d %d %d %d\n",++a,a++,++a,a);  //4 2 4 4
 a=1;      printf("%d %d %d %d\n",++a,a,a++,++a);  //4 4 2 4
 a=1;      printf("%d %d %d %d\n",a++,a++,++a,a++);  //4 3 5 1

在这里面有一个a++,和++a两种赋值的语句,它们在printf()中输出时需要注意一下
a++我们都知道是先使用后加一的,那么在printf("%d %d %d %d\n",a,a++,++a,++a);这里也是一样的,从右向左依次计算值,我们先假设把累加数值暂存在t中,则从右向左依次为
int a=1;

 ++a     a自增1               t=2 
 ++a     a自增1               t=3
 a++    先使用(输出3)再自增1   t=4
 a       不改变               t=4

所有的a++与a的值都按最终的t输出,所以输出为4 3 4 4

只要遇到a++这种先使用在变化的量优先输出。

再比如a=10; printf("%d %d %d %d\n",a,a++,++a,++a);代码
在这里插入图片描述
因此输出结果为13 12 13 13

以上就是我总结的判断在printf()中a++与++a的输出问题。
最后再补上一组测试用例:

int a;
 a=10;      printf("%d %d %d %d\n",a--,a++,++a,--a);  
 a=10;      printf("%d %d %d %d\n",++a,a++,a,a--);  
 a=10;      printf("%d %d %d %d\n",a++,a--,a++,++a);  
 a=10;      printf("%d %d %d %d\n",a++,a,++a,a++);  

输出结果分别为

//11 10 10 10
//11 9 11 10
//11 12 11 12
//12 13 13 10

最后说明一下因为目前博主只是小菜鸟一枚,很多东西都不懂,只是随便写写,希望我写的这篇文章对你能有帮助。


2021-3-22 更新;

printf函数压栈问题,与编译器以及最终编译时的选项参数(如gcc -O1 … )都有关。因此,单纯的讨论此题的输出内容,我个人认为没有什么意义,但是通过分析这些输出结果进而分析出其具体的执行过程,还是很有意思的。

不同的编译器上生成的汇编指令,都各自有针对其代码优化的地方。(我们可以通过汇编代码分析程序究竟做了哪些操作。)

下面展示一个示例程序,每一种输出情况我将使用画图板简单的模拟器执行过程。

代码:

#include <iostream>
using namespace std;

int main()
{
	int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

	int* p = arr;

	printf("%d %d %d\n", *(p++), *(p++), *(++p));
	//printf("%d %d %d %d\n", *p, *(p++), *(p++), *(++p));      

	return 0;


}
情况一

在VS编译器上,使用debug模式输出:
在这里插入图片描述
在剖析其原理时,我们需明晰后置加加的实现原理。其“先使用后加一”意为,先返回一个保存当前值的临时变量,再自身自增1 。(ps:在c语言中前置++/–与后置++/–都视为临时量,不可做左值。在c++中只有后置++/–视为临时量,不可做左值。)

//后置++
T operator++(int) //占位符,表示后置++
{
    T tmp = this;
    this = this + 1; 	//执行递增
    return tmp; 		//返回临时值 
}

注:因为printf()函数是可变参数编程,参数不确定个数,因此采用自右向左的入栈方式。(其他函数的参数入栈方式并没有明确规定,一般而言也是从右往左入栈的。 而具体的根据编译器和调用约定的不同,可能会有所不同。)

在下图中参数的入栈均遵循自右向左入栈。输出时按照参数的顺序(自左到右输出),我们从(图左)栈视图中,自上向下为输出的顺序。如该图表示输出 3,2,4 。
在这里插入图片描述

情况二

在VS编译器上,使用release模式输出:
在这里插入图片描述
在这里插入图片描述

情况三

使用minGW-g++编译器:
在这里插入图片描述
在这里插入图片描述
输出:
在这里插入图片描述

在这里插入图片描述

  • 28
    点赞
  • 67
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我叫RT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值