`
javasalatu
  • 浏览: 723629 次
  • 性别: Icon_minigender_2
  • 来自: 北京
博客专栏
96df99eb-e89d-3228-9c8e-967fc745ec52
程序员的自我经营之道
浏览量:7701
文章分类
社区版块
存档分类
最新评论

C语言中函数参数的入栈顺序

 
阅读更多

对技术执着的人,比如说我,往往对一些问题,不仅想做到“知其然”,还想做到“知其所以然”。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语言完全和Pascal一样,采用自左向右的参数入栈方式。

分享到:
评论

相关推荐

    C语言中函数参数的入栈顺序详解及实例

    主要介绍了C语言中函数参数的入栈顺序详解及实例的相关资料,需要的朋友可以参考下

    浅谈C语言函数调用参数压栈的相关问题

    参数的入栈顺序主要看调用方式,一般来说,__cdecl 和__stdcall 都是参数从右到左入栈。 看下面的代码: #include int test(int a, int b) { printf("address of a %x.\n", &a); printf("address of b %x.\n", &...

    C语言函数调用栈(二)

    主调函数将参数压入栈中,被调函数以相对于帧基指针的正偏移量来访问栈中的参数。对于有多个参数的函数,调用约定需规定主调函数将参数压栈的顺序(从左至右还是从右至左)。某些调用约定允许使用寄存器传参以提高性能...

    关于函数调用方式__stdcall和__cdecl详解

    函数参数的入栈顺序为从右到左入栈。函数返回时使用retn x指令,其中x为调整堆栈的字节数。这种方式叫做自动清栈。即被调用的函数的参数个数是固定的,调用者必须严格按照定义传递参数,一个不多,一个不少。 __...

    c语言食堂就餐排队问题290行

    实现顺序栈的基本操作,包括入栈、出栈和获取栈顶元素。 InitQueue()、EnQueue() 和 DeQueue() 函数: 用于初始化顺序队列、入队和出队操作。 LoopJudge() 函数: 用于判断循环结束条件。 CountStu() 函数: 计算...

    数据结构顺序栈实验2

    编写函数,采用顺序存储实现栈的初始化、入栈、出栈操作。【实验要求】 1、数据要求 顺序表中的数据是图书信息(书号、书名、价格)。 2、输入要求 输入n+1行,其中前n行是n本图书的信息(书号、书名、价格),每本...

    c语言数据结构算法演示(Windows版)

    右下显示拓扑排序过程中入度为零的顶点的栈S,右上显示的栈 T 存放拓扑序列,其入栈顺序和栈 S 的出栈顺序相同,从栈顶到栈底的顶点顺序即为顶点的逆拓扑序列。算法执行结束后将弹出窗口列出全部结果,其中红色字体...

    用 C 语言实现顺序栈的示例C&C.zip

    用 C 语言实现顺序栈的示例。它包含了顺序栈的各种基本操作,包括初始化、判断是否为空、获取长度、清空、销毁、入栈和出栈...在main函数中,对顺序栈进行了一系列操作,展示了其基本功能。 仅供参考,遵纪守法!!!

    lowkeyway#Embedded#参数传递和返回值传递1

    1. 函数参数,默认调用惯例情况下从右向左的顺序依次把参数压入栈中 2. 函数的返回地址,即调用方调用此函数(如call func1)的下一条指令的地址 3.

    《妙趣横生的算法(C语言实现)》(杨峰 编著)

    1.2.2 向顺序表中插入元素 1.2.3 从顺序表中删除元素 1.2.4 实例与分析 1.3 链表 1.3.1 创建一个链表 1.3.2 向链表中插入结点 1.3.3 从链表中删除结点 1.3.4 销毁一个链表 1.3.5 实例与分析 1.4 栈 1.4.1 栈的定义 ...

    传智播客扫地僧视频讲义源码

    20_课堂答疑_函数调用流程入栈出栈过程 21_指针也是一种数据类型_基础 22_指针也是一种数据类型_强化_传智扫地僧 源码及文档 01_课程回顾 02_作业题强化和野指针 03_向null地址copy数据和不断改变指针指向强化 04_...

    学生成绩管理系统--c语言写的-数据结构

    1.用顺序表n个学生的学号和成绩录入; 思想: 在主函数里完成学生人数限定,和定义学生的结构体指针,调用录入函数。 用结构体指针完成学生信息录入。 2.用选择排序法对n个学生的成绩按照降序排列; 思想: ...

    数据结构第三章作业答案参考(C语言)

    7. 向顺序存储的循环队列 Q 中插入新元素的过程分为三步: ( )。 A.进行队列是否空的判断,存入新元素,移动队尾指针 B.进行队列是否满的判断,移动队尾指针,存入新元素 C.进行队列是否空的判断,移动队尾...

    数据结构课程设计---停车场管理

    此程序演示的是停车场管理问题,通过使用顺序栈模拟停车场,链队列模拟车场外的便道,实现车辆入栈,出栈,入队列,出队列,信息输出等功能。 关键字:顺序栈 链队列 停车场 前 言 栈和队列是两种特殊的线性表,...

    数据结构实验报告2.docx

    1、定义栈可以是顺序存取结构或链式存储结构 2、分别定义栈的基本操作(初始化栈、判栈为空、出栈、入栈等) 3、定义一个函数用来实现上面问题: 十进制整数 X 和 R 作为形参 初始化栈 只要 X 不为 0 重复做下列动作...

    数据结构课程设计--迷你计算器设计

    在计算器用到的算法中,c语言算法可读性很强,一方面,是因为c语言是高级语言,是面向程序员的语言,二是c语言的功能是很完备的,可以达到事半功倍的效果,和其他语言相比量是比较少。栈的应用使该程序更出色。 ...

    如何使用visual studio2019创建简单的MFC窗口(使用C++)

    本文介绍了如何使用visual studio2019创建...//CALLBACK 代表_stdcall 参数的传递顺序:从右到左依次入栈,并且函数返回前清空堆栈 LRESULT CALLBACK WindowProc(HWND hand, //消息所属窗口句柄 UINT uMsg, //具体消息

    数据结构C严蔚敏版_全注释源码_线性表队列栈监视哨查找折半直接插入排序冒泡快速选择

    //从栈底依次对栈中每个元素调用函数visit(),主要用于输出 //关于visit的解释参考 List.cpp Status StackTraverse(SqStack &S,Status(* visit)(SElemType)){ int l = S.top-S.base; S.top=S.base; //从栈底...

    一些C面试题,希望能对大家有帮助

    2.对于一个频繁使用的短小函数,在C语言中应用什么实现,在C++中应用什么实现? c用宏定义,c++用inline 3.直接链接两个信令点的一组链路称作什么? PPP点到点连接 4.接入网用的是什么接口? 5.voip都用了那些协议? 6....

Global site tag (gtag.js) - Google Analytics