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 ...
随机推荐
- Codeforces 1209D Cow and Snacks
题目大意 有 $n$ 个不同的糖果,从 $1$ 到 $n$ 编号.有 $k$ 个客人.要用糖果招待客人. 对于每个客人,这些糖果中恰有两个是其最爱.第 $i$ 个客人最爱的糖果编号是 $x_i$ 和 ...
- [BZOJ 2002] [HNOI2010]弹飞绵羊(Link Cut Tree)
[BZOJ 2002] [HNOI2010]弹飞绵羊(Link Cut Tree) 题面 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一 ...
- python_0基础开始_day07
第七节 1,基础数据类型补充 str: print(str.capitalize()) —— 首字母大写 print(str.title()) —— 每个单词的首字母大写 print(str.swap ...
- tomcat进行压测时,cpu占用90%
1.top 命令查看占用cpu高的进程,pid=15019 2.查看该进程下所有占用cppu高的线程 top -Hp pid 即:top -Hp 15019 得到pid 3.获取15030的16进 ...
- JavaScript制作九九乘法表
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 06 Python之列表和元组
1. 什么是列表 定义: 能装对象的对象 在python中使用[]来描述列表, 内部元素用逗号隔开. 对数据类型没有要求 列表存在索引和切片. 和字符串是一样的. 2. 相关的增删改查操作 添加: 1 ...
- Linux Exploit系列之七 绕过 ASLR -- 第二部分
原文地址:https://github.com/wizardforcel/sploitfun-linux-x86-exp-tut-zh/blob/master/7.md 这一节是简单暴力的一节,作者讲 ...
- 安装Anaconda3-201812详解
Anaconda指的是一个开源的Python发行版本,其包含了conda.Python等180多个科学包及其依赖项. 因为包含了大量的科学包,Anaconda 的下载文件比较大(约 531 MB), ...
- php不重新编译,添加模块
本文已安装mysqli模块为例 一:检查 1:首先保证php-fpm能正常启动 2:查看当前已安装的php模块是否有mysqli [root@oldboyedu ~]# /application/ph ...
- deep_learning_Function_tensorflow_reshape()
numpy.reshape(a, newshape, order='C')[source],参数`newshape`是啥意思? 根据Numpy文档(https://docs.scipy.org/doc ...