函数传递参数的本质

研究实验5

问题引出:我们经过之前的研究已经知道了函数就是汇编中的子程序这样一个概念,那么但是函数的参数是如何传递呢,是汇编语言学习中参数传递的哪种方式呢?

问题研究:

图1-2  a.exe汇编代码

从图中的汇编代码我们可以清晰的发现,C语言中传递参数是通过栈来传递参数,这在之前汇编语言中是有介绍的。

  

图3  b.exe对应汇编代码

从图中的汇编代码可以看出,showchar 是根据第一个变量n值来确定要显示多少个字符的。

下面来研究这样一个问题:printf函数功能很强大,原因在于它对于参数个数不限制,它到底是怎么样来处理这样一个过程的?

观察printf函数,我们其实容易发现,无论我们用printf函数对屏幕输出什么,printf()函数括弧中第一个量总是一个字符串,所以,我们在此推测,字符串是printf函数的第一个变量(虽然C语言中没有字符串变量)。而且根据我们已知的事实是:”…”字符串中的内容决定了其后面变量的个数(之前学习C语言时我们发现如果类似于%d这样的输出符,如果其个数和后面变量的个数不匹配,那么编译器就会报错)。并且根据我们已经掌握的C语言知识,我们发现,%字符的个数决定了其后面变量的个数,即%字符为0个时,其后没有变量,%字符为n个的时候,其后的变量个数为n。

基于此原理我们编写一个伪printf函数

详情见附件2

实验结果只能显示字符串以及大于零的数,尚需改进

改进中!!!!!!!

未解决问题:

虽然知道了传递参数是通过栈的方式,但是如何知道要入栈多少个数,是否是编辑器决定的?

研究总结

通过这个实验最大的收获是,知道了函数传参是通过栈的方式进行参数传递的,知道了printf函数的接受参数的机制。但是想提出的一个问题是,为什么要对printf函数进行研究,其对于后期学习有什么作用影响?

补充总结部分:

在此,再次补充一下调用函数过程机制:

首先需要明确一点,C语言中函数都是带括号的,其次,括号中的逗号隔开的都是参数!!,事实上,这一点是十分重要的。比如printf函数第一个字符串也是一个参数,我们不能忽略了它是参数这样一个事实!!这就是说,在入栈的时候,它也入栈了(入栈的是首地址)

从这里也能看出用指针指向字符串的优越性。

下面介绍一下调用函数的机制:

首先,在遇到一个即将被调用的函数时:

第一步:将所有的参数入栈(括号最右边的参数最先入栈),可以认为是准备工作

第二步:开始调用函数,即call ,将IP入栈

第三步:进入子函数,首先将BP入栈。

所以我们在取参数的时候,务必要十分明确上述过程才可以,尤其是printf函数的实现过程,必须要深入理解上述原理!

时间: 2024-10-03 14:24:31

函数传递参数的本质的相关文章

js中函数传递参数,究竟是值传递还是引用传递?

记住真理: js函数传递参数,不管是简单数据类型,还是引用数据类型,都是值传递!! 下面是js红包书里面的例子: function setName(obj) { obj.name = "Nicholas"; obj = new Object(); obj.name = "Greg"; } var person = new Object(); setName(person); alert(person.name); // "Nicholas" 肯定

Delphi过程、函数传递参数的八种方式

Delphi过程函数传递参数的八种方式 Delphi过程.函数传递参数的八种方式,布布扣,bubuko.com

给wxPython事件处理函数传递参数

给wxPython事件处理函数传递参数 2014-04-30 07:47:08segmentfault-博客--点击数:39 最近捣鼓Python,也就自然捣鼓上了wxPython.我曾经用过Qt和Gtk+写GUI,但几乎所有的Python书都告诉我说最好用的是wxPython,我没有尝试PyQt和PyGtk就开始研究wxPython了.在Qt和Gtk+之间我更喜欢Qt,因为它跨平台做得很好,而且商业化也不错.但wxWidget给人的感觉就完全不同了. 如果说wxWidgets相对于Qt有什么优

javascript如何给事件处理函数传递参数

javascript如何给事件处理函数传递参数:在应用中可能需要给注册的事件处理函数传递参数,但是会发现好像无法实现直接传递,下面就简单介绍一下如何给事件处理函数传递参数.先看一段代码实例: <!DOCTYPE html> <html> <head> <meta charset=" utf-8"> <meta name="author" content="http://www.softwhy.com/&

向线程函数传递参数

向线程函数传递参数在构造线程对象时即可完成.但是要记住,默认情况下是把参数拷贝到线程内部,即使在函数中使用的是引用.例如 void f(int i,std::string const &s); std::thread t(f,3,"hello");</span> 上面代码中,函数f的第二个参数是std::string,传递的是char const *会转换为string. 当使用指针指向自动变量时,要特别注意: <span style="font-s

js函数传递参数时,如果是路径类型的参数,里边包含:&#39;\&#39;字符报错

在函数中,传递的参数中有“\”字符,js会将它默认为转义字符串,如果没有出现与他匹配的转义字符串,就会缺失,例如: 将这样的一个字符串作为一个参数:C:\Program Files (x86)\MySQL\MySQL Server 5.7\data\ 传递到函数里边的值就会被默认转化为:C:Program Files (x86)MySQLMySQL Server 5.7data 如果要实现这个参数的精确传递,就需要将字符串进行处理,一般会有两种方式: ①:将字符串里边的 ‘\’ 字符替换成 ‘/

利用call与apply向函数传递参数

Js中函数对象都有call与apply两个方法属性,二者使用方法和功能一样,只是传递参数的格式不同,call逐个传递单个参数,apply一次性传递一个参数数组. 这两个方法可以改变函数的调用对象,并且向函数中传递参数.如: function send(str,speak){ speak.call(this,str); //send(~)==window.speak(str),这句话会立即调用执行此函数 } send("你好!",function(strword){ //这里以匿名函数对

Ubuntu 下 kdevelop下 怎么向主函数传递参数

1.打开工程 2.点击窗口上的运行"--"配置启动器" 3.左栏选择要传递参数的工程名,在参数一栏中,输入参数"ubuntu.png",再输入"工作目录".点击OK,运行就可以了. 原文地址:https://www.cnblogs.com/feifanrensheng/p/8330927.html

Java调用函数传递参数到底是值传递还是引用传递

今天翻看微信上有关Java技术的公众号时,看到了一篇关于Java中值传递的问题,文章讨论了在Java中调用函数进行传参的时候到底是值传递还是引用传递这个面试时会问到的问题.之前也接触过类似的问题,但只是知道是值传递,具体到为什么,一直不是太清楚.今天看了一下,算是明白了,写个博客记录一下. 首先先声明一下,在Java中函数传参是值传递,不是引用传递.要弄清楚这个问题之前要先弄清楚什么是值传递,什么是引用传递. 值传递(pass by value):是指在调用函数时将实际参数复制一份传递到函数中,