看到有人提问到,在处理printf/cout时,压栈顺序是什么样的?大家都知道是从右往左,也就是说从右往左的计算,但是,这里的计算不等于输出。

a++和++a的压栈的区别:在计算时,遇到a++会记录此时的a的值作为最后的输出结果。遇到a和++a的时候则不会将此时的计算结果作为最终的输出,只会修改a的值,在最终输出的时候都输出a的值(所以++a和a的结果总是一样的)。

比如:

int a = 2;

cout << ++a << a++ << a << ++a << a++ << a << ++a << endl;

输出为:7 5 7 7 3 7 7

但是不禁要问,为什么C语言的函数调用入参压栈顺序一定是自右向左?反过来不可以吗?

首先,在函数调用过程中,最先入栈的是调用函数调用处的下一条指令的地址,这样调用完成后返回到该地址继续执行,这个地址是很重要的,然后才是函数的入参,函数的内部局部变量。调用结束,将栈内容一一出栈,最后栈顶指向了开始存储的指令地址,主函数继续从这里开始还行。

其次,函数调用入参的入栈顺序和C语言支持变长参数有关,比如printf函数就支持变长参数,也即void printf(const char *fmt,……),这个时候并不知道参数有多少个,如果从左向右入栈,那么fmt就在栈底,该参数的位置无法通过栈顶指针偏移来确定,因为不知道栈顶和栈底之间有多少个参数,大小是多少,无法确定,但是,如果从右向左入栈的话,fmt参数就在栈顶的位置,通过这个固定的普通参数就可以通过偏移逐一寻址到后续参数的地址。

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

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

C、C&plus;&plus;语言中参数的压栈顺序

要回答这个问题,就不得不谈一谈printf()函数,printf函数的原型是:printf(const char* format,-) 没错,它是一个不定参函数,那么我们在实际使用中是怎么样知道它的参 ...

C&sol;C&plus;&plus;多参数函数参数的计算顺序与压栈顺序

一.前言 今天在看Thinking in C++这本书时,书中的一个例子引起了我的注意,具体是使用了下面这句 单看这条语句的语义会发现仅仅是使用一个简单的string的substr函数将所得子串pus ...

c&sol;c&plus;&plus;的函数参数压栈顺序

整理日:2015年3月18日 为了这句话丢了很多次人.无所谓了,反正咱脸皮厚. 总结一下 编译出来的c/c++程序的参数压栈顺序只和编译器相关! 下面列举了一些常见的编译器的调用约定 VC6 调用约定 ...

测试当前C环境的栈帧增长方向以及传递参数时的压栈顺序

前文链接:上次由于一个很常见的printf-bug(下文有提及)引发了我对栈的思考,并写下了一点总结.这次就尝试对不同的C环境进行实践,检测其传递参数的一些性质. 这是今天写的检查C环境的一段程序.能 ...

C&sol;C&plus;&plus;---printf&sol;cout 从右至左压栈顺序实例详解

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

js的replace函数入参为function时的疑问

近期在写js导出excel文件时运用到replace方法,此处详细的记录下它各个参数所代表的的意义. 定义和用法 replace() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式 ...

python函数入参和返回值

c语言函数参数从右往左,C语言函数入参压栈顺序为什么是从右向左?相关推荐

  1. C语言函数参数压栈顺序为何是从右到左?

    #转载自:http://blog.csdn.net/jiange_zh 上学期学习了汇编语言,并在操作系统实验中使用了汇编+C语言混合编程,中间也了解了一些C语言与汇编语言的对应关系. 由于汇编语言是 ...

  2. C、C++语言中参数的压栈顺序

    要回答这个问题,就不得不谈一谈printf()函数,printf函数的原型是:printf(const char* format,-) 没错,它是一个不定参函数,那么我们在实际使用中是怎么样知道它的参 ...

  3. 函数压栈的简解(计算顺序与压栈顺序)

    重点: 函数有两个概念(压栈顺序和计算顺序) 压栈顺序知识点 1.栈是先进后出的结构 2.ebp:基地址寄存器 (栈底) esp:栈指针 (栈顶) 3.栈底到栈顶的内存地址是由高到低.就是10-> ...

  4. C语言初探 之 printf压栈顺序(printf(%d %d %d %d %d %d\n,a++, ++a, a++, ++a, a++, ++a ))

    写在篇头: 在不同的编译器下结果不同,本例测试的环境为 devcpp5.3.0.1 . -------------------------------------------------------- ...

  5. C语言初探 之 printf压栈顺序

    写在篇头: 在不同的编译器下结果不同,本例测试的环境为 devcpp5.3.0.1 . -------------------------------------------------------- ...

  6. Day04:函数参数、对象、嵌套、闭包函数和装饰器

    上节课复习:     1.什么是函数         函数就是具备某一功能的工具     2.为何用函数         1.程序的组织结构和可读性         2.减少代码冗余         ...

  7. go编译库给c语言map参数,在 Go 中使用 C 语言的动态库

    我和我的儿子在上周末干了一件非常有意思的事情,我们开发了一个用 Go 编写的命令行游戏,最近我正在重写一款曾经在年轻时开发的游戏,当时用的还是 Kaypro II. ![](https://raw.g ...

  8. python中list作为函数参数_在python中list作函数形参,防止被实参修改的实现方法

    0.摘要 我们将一个list传入函数后,函数内部对实参修改后,形参也会随之改变.本文将主要介绍这种错误的现象.原因和解决方法. 1.代码示例 def fun(inner_lst): inner_lst ...

  9. Python基础(可变数据类型不能做函数参数、装饰器、剥皮函数、时间间隔)

    1.可变数据类型不能做函数参数: 参数会动态改变 def func(a, l=[]):l.append(a)print(id(l))return lf1 = func(1) print(f1) # [ ...

最新文章

  1. Python “with” keyword
  2. Mac下PyCharm CE 配置PyQt5环境
  3. [攻防世界 pwn]——pwn1(内涵peak小知识)
  4. 部署在Netweaver应用上的Fiori缓存的调试
  5. 爬虫神器:一条命令下载《复仇者联盟3:无限战争》
  6. sql join语句语法_SQL Left Join语句:示例语法
  7. 6park留园 android,‎App Store 上的“掌上留园-6park”
  8. drawboard pdf拆分文件_掌握在线PDF拆分技巧,从此打开文件不再处于“加载中”...
  9. 端口渗透·网站渗透过程 --21 ,22,873,3306,6379,8080(8080端口是针对CMS的渗透)...
  10. 14.2.4 InnoDB Undo Logs
  11. 手把手教你用 Keras 实现 LSTM 预测英语单词发音
  12. java syn包_TCP攻击之SYN攻击
  13. 纯CSS3实现凹凸文字
  14. 固件-驱动-软件 区别
  15. i12蓝牙耳机怎么设置成中文_windows10的蓝牙怎么打开?如何修复Windows 10中的蓝牙问题...
  16. python实现剪刀石头布小游戏
  17. x32dbg、x64dbg逆向微信发送信息
  18. 新年寄语 —— 奋斗2022
  19. 微信小程序开发 01
  20. layDate使用心得

热门文章

  1. 了解V模型,W模型,H模型
  2. V模型 W模型 H模型
  3. 五年级上册计算机教学工作计划,小学五年级上册信息技术教学工作计划(精选5篇)...
  4. Linux如何连接到WIFI网络
  5. 模板引擎:ftl文件生成word
  6. 食用盐的12个美容方法
  7. XP系统下MSDTC不可用解决办法
  8. CGAL Cookbook --CGAL简介
  9. 外观模式 Facade
  10. 老毛桃怎样查看计算机桌面文件,桌面上的文件在PE里怎么找-win7在pe下的桌面文件,win7在pe下的桌面文件不见了...