在本人的《C语言可变参数函数的实现方法》一文中,介绍了如何建立自己的可变参数函数。

下面继续介绍可变参数函数的实现原理。

在汇编语言程序设计中,详细介绍了子程序的实现思想:

(1)子程序只是一段代码的起始地址;

(2)调用子程序之前,主程序将一些数据存入栈中;

(3)子程序被调用后,从栈中取出数据;

(4)栈底为高地址,栈顶为低地址;

(5)入栈时栈顶指针向低地址方向移动,出栈时,栈顶指针向高地址方向移动。

那C函数各个参数入栈的顺序是怎样的?

我们用一个程序来测试一下参数入栈顺序

程序的代码为:

#include void TestOrder(int iFirst, int iSecond, int iThird){    printf("First: %ld", (unsigned long)&iFirst);    printf("Second: %ld", (unsigned long)&iSecond);    printf("Third: %ld", (unsigned long)&iThird);}void main(){    TestOrder(1, 2, 3);}

这是程序的某次运行结果:

First: 140724053717020Second: 140724053717016Third: 140724053717012

入栈时,由于机器的栈顶指针是从高地址向低地址移动。所以我们可以得出结论:

默认情况下,C语言的参数入栈,是从左往右,依次入栈。

因此,main函数调用TestOrder函数时,参数入栈的顺序为:

  • 值“1”入栈;
  • 值“2”入栈;
  • 值“3”入栈。

TestOrder函数则直接通过栈的地址,获得传入参数,原理是这样的:

  • 栈顶第一个元素的地址,就是iThird形参的地址;
  • 栈顶第二个元素的地址,就是iSecond形参的地址;
  • 栈顶第三个元素的地址,就是iFirst形参的地址。

如果函数的参数列表是固定的,上面的过程,由编译器帮我们完成,我们体会不到内部的细节。

如果函数的参数列表是可变的,上面的过程,编译器已经无能为力,必须由我们自己来完成。

这就是我们使用这套奇怪的标识符的原因了:

  • va_list
  • va_start
  • va_arg
  • va_end

本文先讲解C函数参数的实现原理,下文将详细解析这套奇怪的标识符。

谢谢!

#科技新星创作营#

c语言怎样获得函数内参数的值_C语言可变参数函数的实现原理相关推荐

  1. c语言链表查找的代码与题目,链表的C语言实现之单链表的查找运算_c语言

    建立了一个单链表之后,如果要进行一些如插入.删除等操作该怎么办?所以还须掌握一些单链表的基本算法,来实现这些操作.单链表的基本运算包括:查找.插入和删除.下面我们就一一介绍这三种基本运算的算法,并结合 ...

  2. c语言 方程改main的值_c语言main函数里的参数argv和argc解析

    前言 一般我们平时写main函数的话,一般都是写不带参数的比较多,而且也习惯了这样写:其实标准的形式写法,main函数是带两个参数的,这两个参数分别是:argc和argv,那么这两个参数是表示什么意思 ...

  3. c语言命令行参数怎么输入_C语言程序设计——这个函数原型你看懂了吗

    虽然过去了好多年,但我仍然清楚地记得自己第一次看到signal函数原型时的惊讶. 学习UNIX环境C编程的朋友都知道,信号是绕不过去的一道坎,而信号处理的第一重要函数就是signal(). 什么都不说 ...

  4. mysql 聚合函数内比较运算符_关于常用 MYSQL 聚合函数,其他函数 ,类型转换,运算符 总结...

    /* 关于MYSQL 聚合函数,其他函数 ,类型转换,运算符 总结,*/ -- 1 运算符优先级  /* 12.1.1. 操作符优先级 以下列表显示了操作符优先级的由低到高的顺序.排列在同一行的操作符 ...

  5. c#语言怎么定义函数,C#方法方法用法 _C#语言-w3school教程

    C#语言 的 C#方法 C#中的方法是一组执行任务的语句. 每个 C# 程序至少有一个类包含一个名称为Main()的方法. 要使用方法,需要: 定义方法 调用方法 C# 中定义方法 当要定义一个方法时 ...

  6. C++两个函数可以相互递归吗_C语言“最难啃”的三块硬骨头!你知道吗?

    提到C语言很多初学者都觉得,学到中间就进行不下去了,因为碰到了几个硬骨头死活翻不过去,于是很多人给C语言下结论太难了,太靠近底层了,特别是那几块难啃的骨头,直接理解不了,进行不下去. 今天就来说下,最 ...

  7. c语言自定义函数多个返回值,C语言函数返回值

    C语言函数返回值教程 如果,我们希望函数不返回任何值,那么我们需要显式的指明其返回类型为 C语言函数不返回值 语法 void funcName(paramType1 param1, paramType ...

  8. python展开 c函数中的宏预处理_C 语言常用的预处理-宏函数

    #include // 宏函数 三目运算符 #define MAX(A, B) A>B?A:B //宏函数 多行 添加\直接回车 #define LOOP(FROM, TO, CONTENT)\ ...

  9. html中函数传递多个值,JavaScript 实战开发经验!函数多参数传参技巧

    HTML5学堂-码匠:掌握JavaScript代码的你,一定编写封装过函数,为了提升函数的控制性,必不可少的就是参数,必选可选的一大堆参数罗列出来,函数调用貌似变得麻烦起来~~~ Tips: 必选参数 ...

最新文章

  1. inno setup修改properties格式内容_linux内核修炼之setup
  2. 在Rancher 1.6上部署Traefik负载均衡器
  3. 第十一回:琴房外度曲生慕意 书店里软语救阿四[林大帅作品集]
  4. 5位随机数重复的概率 php_PHP产生不重复随机数的5个方法总结
  5. Asp.net MVC使用Filter解除Session, Cookie等依赖
  6. 共享的网络如何让自己比别人快_ipfs网络的分布式数据是如何做到数据共享的?...
  7. 程序设计中的一些感悟
  8. 【React】JSX
  9. Shutdown In Period 1.0
  10. ACM-百度之星资格赛之Energy Conversion——hdu4823
  11. 软件推荐之 QttabBar
  12. 微信公众号获取永久素材
  13. 教大家做蛋黄酥的做法
  14. 细胞衰老——酪氨酸激酶抑制剂
  15. iOS音效和音乐播放
  16. 配置计算机名和工作组,TCP/IP地址配置,网络连通性测
  17. 计算机制图孔中心线,机械制图教程—1-5绘图方法和步骤
  18. python爬虫爬取虎牙数据(简单利用requests库以及Beautifulsoup)
  19. 有几个男生敢对女生说出这样的话
  20. Android的autobahn框架使用实例:实现WebSocket的长连接

热门文章

  1. linux6.2 网络yum,配置RHEL6.2的YUM源
  2. 判断字符为空_算法题:字符串转换整数 (atoi)
  3. C++中 Vector使用方法
  4. 485转换器产品功能特点及技术参数介绍
  5. 【渝粤教育】国家开放大学2018年春季 0703-21T经济学基础 参考试题
  6. 怎么设置php的css颜色代码,CSS的文本字体颜色如何设置
  7. 投资最重要的事读后感_《投资最重要的事》读书笔记分享
  8. fanuc机器人与视觉通信_要说工厂干起活来:工业机器人和数控机床才是真正的一对!...
  9. Java部分A+B正整数A的“DA(为1位整数)部分”定义为由A中所有DA组成的新整数PA。例如:给定A = 3862767,DA = 6,则A的“6部分”PA是66,因为A中有2个6。现给定A、DA
  10. 对mysql的总结与反思_一次DB故障引起的反思和MySQL Operator选型