printf计算参数是从右到左压栈的(a++和++a的压栈的区别)
一、问题
c++代码:
#include <iostream>
#include <stdio.h>
using namespace std;
int main(){
int a=;
cout<<a++<<" "<<a<<endl;//
a=;
cout<<a<<" "<<a++<<endl;//
a=;
printf("%d %d\n",a,a++);//
a=;
printf("%d %d\n",a++,a);//
}
java代码:
public class Test{
public static void main(String[] args){
int a=1;
System.out.println((a++)+" "+a);//1 2
a=1;
System.out.println(a+" "+(a++));//1 1
}
}
对比两段代码,可知JAVA代码中比较有规律(从左到右),而C中的规律呢?(向下看)
C代码:
#include "stdafx.h"
#include <iostream>
#include <stdio.h>
using namespace std;
int a=;
int afun(){
printf("调用afun(){a++;}\n");
return a++;
}
int bfun(){
printf("调用bfun(){a;}\n");
return a;
}
void main(){
//printf("%d %d\n",a++,a);//
printf("%d %d\n",afun(),bfun());
}
运行结果:

注意与之前直接打印所输出的结果不同(为什么啊???往下看):
(1)直接打印 printf("%d %d\n",a++,a);//输出12
(2)函数调用 printf("%d %d\n",afun(),bfun());//输出11
二、原理(cout与printf原理一样)
下面内容参考博文:http://blog.csdn.net/kzzhr/article/details/8482657
http://www.zzzj.com/html/20090609/71613.html
其实,在处理printf时,压栈顺序为从右往左,也就是说从右往左的计算(“计算”不等于“输出”)。
a++和++a的压栈的区别:在计算时,遇到x++会记录此时的x的值作为最后的输出结果。遇到x和++x的时候则不会将此时的计算结果作为最终的输出,只会修改x的值,在最终输出的时候都输出x的值(所以++x和x的结果总是一样的)。
为什么会是这个样子呢?参见某高手解释吧:
对于a++的结果,是有ebp寻址函数栈空间来记录中间结果的,在最后给printf压栈的时候,再从栈中把中间结果取出来;而对于++a的结果,则直接压寄存器变量,寄存器经过了所有的自增操作。
printf计算参数是从右到左压栈的(a++和++a的压栈的区别)的更多相关文章
- printf:函数参数计算从右向左,从左向右?
造冰箱的大熊猫@cnblogs 2019/8/3 1.问题 某天写了如下代码: unsigned char ReadByteFromFile ( FILE * fp ) { unsigned char ...
- 5-2-2 printf参数从右往左压栈
5-2-2 C中printf计算参数时是从右到左压栈的 #include <stdio.h> int main (int argc, char **argv) { ; ,,,,}; int ...
- C语言函数参数压栈顺序为何是从右到左?(从左向右的话,碰到printf的会陷入死循环)
上学期学习了汇编语言,并在操作系统实验中使用了汇编+C语言混合编程,中间也了解了一些C语言与汇编语言的对应关系. 由于汇编语言是底层的编程语言,各种函数参数都要直接控制栈进行存取,在混合编程中,要用汇 ...
- C/C++---printf/cout 从右至左压栈顺序实例详解
__cdecl压栈顺序实例 明白计算:计算是从右到左计算的 栈和寄存器变量:x++,是将计算结果存放到栈空间,最后是要出栈的:而++x和x是将计算结果直接存放到某个寄存器变量中(是同一个),所以计算完 ...
- C语言函数入参压栈顺序为什么是从右向左?
看到有人提问到,在处理printf/cout时,压栈顺序是什么样的?大家都知道是从右往左,也就是说从右往左的计算,但是,这里的计算不等于输出. a++和++a的压栈的区别:在计算时,遇到a++会记录此 ...
- thiscall仅仅应用于“C++”成员函数(this指针存放于CX寄存器,参数从右到左压)
_stdcall是Pascal程序的缺省调用方式,通常用于Win32 Api中,函数采用从右到左的压栈方式,自己在退出时清空堆栈.VC将函数编译后会在函数名前面加上下划线前缀,在函数名后加上" ...
- 南阳oj 求N!的二进制表示最低位的1的位置(从右向左数)。
N! 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 阶乘(Factorial)是一个很有意思的函数,但是不少人都比较怕它.现在这里有一个问题,给定一个N(0< ...
- C语言十六进制转换成十进制:要从右到左用二进制的每个数去乘以16的相应次方
#include <stdio.h> /* 十六进制转换成十进制:要从右到左用二进制的每个数去乘以16的相应次方: 在16进制中:a(A)=10 b(B)=11 c(C)=12 d(D)= ...
- [android]如何使LinearLayout布局从右向左水平排列,而不是从左向右排列
方法1: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:l ...
随机推荐
- 轻度折腾nuc8i5beh
最近入手了一台迷你电脑:Intel NUC--Next Unit of Computing,配了1根16GB内存条(2666)和两块固态(m.2+sata),搭载i5-8259U ,Intel Iri ...
- 【转载】softmax的性质及其实现
原文地址:https://segmentfault.com/a/1190000010039529?utm_source=tag-newest softmax函数将任意n维的实值向量转换为取值范围在(0 ...
- 浅谈Linux du命令
**du(disk usage),顾名思义,查看目录/文件占用空间大小** 1.查看当前目录下的所有目录以及子目录的大小 du -h du -ah #-h:用K.M.G的人性化形式显示#-a:显示目 ...
- Postgresql 监控sql之 pg_stat_statements模块
postgresql.confpg_stat_statements.max = 1000000pg_stat_statements.track = allpg_stat_statements.trac ...
- springmvc的MultipartFile参数如果不上传文件报错的问题
@RequestMapping(value = "/updateInformation",method = RequestMethod.POST) @ResponseBody pu ...
- luogu P4006 小 Y 和二叉树
luogu loj 可以发现度数\(< 3\)的点可以作为先序遍历的第一个点,那么就把度数\(< 3\)的编号最小的点作为第一个点.然后现在要确定它的左右儿子(或者是右儿子和父亲).我们把 ...
- JS根据一个经纬度及距离角度,算出另外一个经纬度
var mapNumberUtil = {}; /** * 根据一个经纬度及距离角度,算出另外一个经纬度 * @param {*} lng 经度 113.3960698 * @param {*} la ...
- SuperMap-WebGL-坐标系及转换说明
转载自:https://blog.csdn.net/supermapsupport/article/details/89519310 一.坐标系介绍我们先来列举下Cesium中的坐标系:WGS84经纬 ...
- thinkphp漏洞集合
整合了一个集合,方便查询 thinkphp 5.0.22 1.http://192.168.1.1/thinkphp/public/?s=.|think\config/get&name=dat ...
- springboot(2)-阶段篇
web开发 spring boot web开发非常的简单,其中包括常用的json输出.filters.property.log等 json 接口开发 在以前的spring 开发的时候需要我们提供jso ...