c语言中函数参数入栈的顺序是什么?为什么
看到面试题C语言中函数参数的入栈顺序如何?
自己不知道,边上网找资料。下面是详细解释
#include <stdio.h>
void foo(int x, int y, int z)
{
printf("x = %d at [%X]/n", x, &x);
printf("y = %d at [%X]/n", y, &y);
printf("z = %d at [%X]/n", z, &z);
}
int main(int argc, char *argv[])
{
foo(100, 200, 300);
return 0;
}
运行结果:
x = 100 at [BFE28760]
y = 200 at [BFE28764]
z = 300 at [BFE28768]
C程序栈底为高地址,栈顶为低地址,因此上面的实例可以说明函数参数入栈顺序的确是从右至左的。可到底为什么呢?查了一直些文献得知,参数入栈顺序是和具体编译器实现相关的。比如,Pascal语言中参数就是从左到右入栈的,有些语言中还可以通过修饰符进行指定,如Visual C++。即然两种方式都可以,为什么C语言要选择从右至左呢?
进一步发现,Pascal语言不支持可变长参数,而C语言支持这种特色,正是这个原因使得C语言函数参数入栈顺序为从右至左。具体原因为:C方式参数入栈顺序(从右至左)的好处就是可以动态变化参数个数。通过栈堆分析可知,自左向右的入栈方式,最前面的参数被压在栈底。除非知道参数个数,否则是无法通过栈指针的相对位移求得最左边的参数。这样就变成了左边参数的个数不确定,正好和动态参数个数的方向相反。
因此,C语言函数参数采用自右向左的入栈顺序,主要原因是为了支持可变长参数形式,C语言中可变参数都是从左到右,所以不管你有多少个参数反正将最右面的那个压入栈底,最左面的参数出入栈顶。换句话说,如果不支持这个特色,C语言完全和Pascal一样,采用自左向右的参数入栈方式
博文选自C语言参数的入栈的顺序
c语言中函数参数入栈的顺序是什么?为什么的更多相关文章
- x86汇编寄存器,函数参数入栈说明
https://en.wikipedia.org/wiki/X86_calling_conventions
- C语言中可变参数函数实现原理
C函数调用的栈结构 可变参数函数的实现与函数调用的栈结构密切相关,正常情况下C的函数参数入栈规则为__stdcall, 它是从右到左的,即函数中的最右边的参数最先入栈.例如,对于函数: void fu ...
- c++参数入栈顺序和参数计算顺序
关于 本文涉及到代码,演示环境为:win10 + VS2017 ,ubuntu+clang clang版本: 参数入栈顺序 顺序 几种常见的函数参数入栈顺序,还有两种就不介绍了(__clrcall._ ...
- C语言中可变参数的函数(三个点,“...”)
C语言中可变参数的函数(三个点,“...”) 本文主要介绍va_start和va_end的使用及原理. 在以前的一篇帖子Format MessageBox 详解中曾使用到va_start和va_end ...
- C语言中可变参数的原理——printf()函数
函数原型: int printf(const char *format[,argument]...) 返 回 值: 成功则返回实际输出的字符数,失败返回-1. 函数说明: 使用过C语言的人所再熟悉不过 ...
- C语言中的堆与栈20160604
首先声明这里说的是C语言中的堆与栈,并不是数据结构中的!一.前言介绍:C语言程序经过编译连接后形成编译.连接后形成的二进制映像文件是静态区域由代码段和数据段(由二部分部分组成:只读数据 段,未初始化数 ...
- C语言中函数参数传递
C语言中函数参数传递的三种方式 (1)值传递,就是把你的变量的值传递给函数的形式参数,实际就是用变量的值来新生成一个形式参数,因而在函数里对形参的改变不会影响到函数外的变量的值.(2)地址传递,就是把 ...
- c语言中函数的简单介绍
c语言中函数的介绍: 函数,简单的说就是代码的打包.存放在一个地方,当需要的时候调用. 函数分类: 1.无参无返回值函数 void func() 2.无参有返回值函数 int func() 3.有参 ...
- C语言中函数返回字符串的4中方法
C语言中函数返回字符串的4中方法 函数的构成部分:返回类型.函数名称.参数.函数主体 参数:函数调用时传入的参数称为实参,函数定义时出现的参数为形参 形参的作用在于接收实参传入的值,形参和函数内部的其 ...
随机推荐
- erlang 大神
http://blog.csdn.net/erlib/article/details/46655905
- AIR:使用 HTML + Javascript 开发桌面应用
背景 断断续续用Winform和WPF开发过一些小工具,始终不得其法门,在玩Flex的时候就接触过AIR,最近发现可以用HTML + Javascript开发AIR应用,本文就尝试一下(Hello,W ...
- 第十一章 PhpMyAdmin连接远程mysql服务器---连接openwrt 703N服务器
//千万不要在你原来的那个phpmyadmin文件夹上操作~~~要复制一个新的进行操作,这样我们就可以同时使用本地和远程 一.下载phpmyadmin到本地 我使用的是windows下的集成WAM ...
- [Linux] Ubuntu下解压rar文件的方法
一般通过默认安装的ubuntu是不能解压rar文件的,只有在安装了rar解压工具之后,才可以解压.其实在ubuntu下安装rar解压工具是非常简单的,只需要两个步骤就可以迅速搞定. ubuntu 下r ...
- Java效率工具之Lombok
参考: http://www.54tianzhisheng.cn/2018/01/09/lombok/ https://zhuanlan.zhihu.com/p/32779910
- DICOM:DICOM三大开源库对比分析之“数据加载”
背景: 上一篇博文DICOM:DICOM万能编辑工具之Sante DICOM Editor介绍了DICOM万能编辑工具,在日常使用过程中发现,“只要Sante DICOM Editor打不开的数据,基 ...
- UVA 10790 (13.08.06)
How Many Points of Intersection? We have two rows. There are a dots on the toprow andb dots on the ...
- Drupal、IoT 和开源硬件之间的交集
导读 来认识一下Amber Matz,她是来自 Lullabot Education 旗下的Drupalize.Me的产品经理以及培训师.当她没有倒腾 Arduino.Raspberry Pi 以及电 ...
- 自定义错误信息并写入到Elmah
在ap.net Web项目中一直使用Elmah进行日志记录, 但一直有一个问题困扰我很久,那就是我如何自己生成一个错误并记录到Elmah里去. 你知道有时你需要在项目中生成一个错误用于一些特殊的需求 ...
- STL - 移除(remove)和释放(erase)集合元素
remove(移除): 这个操作并不是真正地删除元素,它会移除指定的元素,然后后面的元素依次前移,最后用别的元素来补充. erase(释放): 这个操作会指定释放区间的头和尾迭代器(iterator) ...