一、问题

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的压栈的区别)的更多相关文章

  1. printf:函数参数计算从右向左,从左向右?

    造冰箱的大熊猫@cnblogs 2019/8/3 1.问题 某天写了如下代码: unsigned char ReadByteFromFile ( FILE * fp ) { unsigned char ...

  2. 5-2-2 printf参数从右往左压栈

    5-2-2 C中printf计算参数时是从右到左压栈的 #include <stdio.h> int main (int argc, char **argv) { ; ,,,,}; int ...

  3. C语言函数参数压栈顺序为何是从右到左?(从左向右的话,碰到printf的会陷入死循环)

    上学期学习了汇编语言,并在操作系统实验中使用了汇编+C语言混合编程,中间也了解了一些C语言与汇编语言的对应关系. 由于汇编语言是底层的编程语言,各种函数参数都要直接控制栈进行存取,在混合编程中,要用汇 ...

  4. C/C++---printf/cout 从右至左压栈顺序实例详解

    __cdecl压栈顺序实例 明白计算:计算是从右到左计算的 栈和寄存器变量:x++,是将计算结果存放到栈空间,最后是要出栈的:而++x和x是将计算结果直接存放到某个寄存器变量中(是同一个),所以计算完 ...

  5. C语言函数入参压栈顺序为什么是从右向左?

    看到有人提问到,在处理printf/cout时,压栈顺序是什么样的?大家都知道是从右往左,也就是说从右往左的计算,但是,这里的计算不等于输出. a++和++a的压栈的区别:在计算时,遇到a++会记录此 ...

  6. thiscall仅仅应用于“C++”成员函数(this指针存放于CX寄存器,参数从右到左压)

    _stdcall是Pascal程序的缺省调用方式,通常用于Win32 Api中,函数采用从右到左的压栈方式,自己在退出时清空堆栈.VC将函数编译后会在函数名前面加上下划线前缀,在函数名后加上" ...

  7. 南阳oj 求N!的二进制表示最低位的1的位置(从右向左数)。

    N! 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 阶乘(Factorial)是一个很有意思的函数,但是不少人都比较怕它.现在这里有一个问题,给定一个N(0< ...

  8. C语言十六进制转换成十进制:要从右到左用二进制的每个数去乘以16的相应次方

    #include <stdio.h> /* 十六进制转换成十进制:要从右到左用二进制的每个数去乘以16的相应次方: 在16进制中:a(A)=10 b(B)=11 c(C)=12 d(D)= ...

  9. [android]如何使LinearLayout布局从右向左水平排列,而不是从左向右排列

    方法1: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:l ...

随机推荐

  1. 【计算机视觉】背景建模--Vibe 算法优缺点分析

    一.Vibe 算法的优点 Vibe背景建模为运动目标检测研究邻域开拓了新思路,是一种新颖.快速及有效的运动目标检测算法.其优点有以下两点: 1.思想简单,易于实现.Vibe通常随机选取邻域20个样本为 ...

  2. Flash-aware Page Replacement Algorithm

    1.Abstract:(1)字体太乱,单词中有空格(2) FAPRA此名词第一出现时应有“ FAPRA(Flash-aware Page Replacement Algorithm)”说明. 2.in ...

  3. php 二维数据排序 排行榜

    php 二维数据排序 排行榜 $rateCount = array(); foreach($groupUsers as $user){ $rateCount[] = $user['rate']; } ...

  4. [转帖]Linux /tmp目录下执行脚本失败提示Permission denied

    Linux /tmp目录下执行脚本失败提示Permission denied https://www.cnblogs.com/linyfeng/p/11087655.html 国产化的环境上 就有一个 ...

  5. mybatis-sql执行流程源码分析

    1. SqlSessionFactory 与 SqlSession. 通过前面的章节对于mybatis 的介绍及使用,大家都能体会到SqlSession的重要性了吧, 没错,从表面上来看,咱们都是通过 ...

  6. [Luogu5686] 和积和

    Description 给定两个下标从\(1\)到\(n\)编号的序列 \(a_i,b_i\),定义函数\(S(l,r)(1\le l\le r\le n)\)为: \[\sum_{i=l}^r a_ ...

  7. C++学习 之 函数的重载及内联(笔记)

    1.函数的使用: 1.1 将数组传递给函数: 当需要给函数传递数组作为参数时,其实传过来的是实参的地址就相当于使用引用或指针作为形参. 例: int DisPlayArray(int Number[] ...

  8. 数据库or、in、<>、>=、<=、butween区别

    操作前先关闭数据库缓存 #创建测试的test表 DROP TABLE IF EXISTS test; CREATE TABLE test( `id` ) NOT NULL, `name` ) DEFA ...

  9. 从入门到自闭之Python递归

    递归:不断地调用自身,用函数实现 死递归(死循环): def func(): print(1) func() func() 知识点:官方说明最大深度1000,但实际执行998或997以下,看电脑性能 ...

  10. Zabbix 配置钉钉脚本告警

    1.钉钉账号创建,并创建一个组,在组中添加一个机器人,然后记下webhook地址即可. 2.编辑一个报警脚本,此处使用的是BASH脚本,并覆盖我们的webhook地址到相应的位置. [root@loc ...