`
freewxy
  • 浏览: 336725 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

四种参数传递机制的比较与分析

阅读更多

 

  一、所有程序设计语言都有关于过程的概念,但是在这些过程如何获取它们的参数方面,不同的语言之间有所不同。使用哪一种传递机制决定了调用代码序列如何处理参数。下面是就我个人的理解对四种参数传递机制的简单分析与比较。

    1)值调用/按值传递

    2)引用调用/按址传递

    3)名调用/换名调用

    4)复制恢复

 

  1>值调用/按值传递(call by value):

       值调用中,会对实在参数求值(如果是表达式)或者拷贝(如果它是变量)。这些值被放在属于被调用过程的相应形式参数的内存位置上。效果是,被调用过程所做的所有有关形式参数(在过程定义中使用的参数)的计算都局限于这个过程,相应的实在参数(在调用过程时使用的参数)本身不会被改变。

       在按传值调用时,过程的形式参数取得的是实际参数的值。在这种情况下,形式参数实际上是过程中的局部变量,其值的改变不会导致调用点所传送实际参数的值发生改变,也就是说数据的传送是单向的。

      java:按值传递在每次传递参数时,把参数的原始数据拷贝一份,把新拷贝出来的数值传递到方法内部,在方法内部修改时,修改的是拷贝出来的值,而原始值不发生改变。

      使用这种传递方式,参数的原始值不发生改变。

  2>引用调用/按址传递(call by address)

      在引用调用中,实在参数的地址作为相应的形式参数的值被传递给被调用者。在被调用者的代码中使用形式参数时,实现方法是沿着这个指针找到调用者指明的内存位置。因此,改变心事参数看起来就像是改变了实在参数一样。

      在引用调用时,过程的形式参数取得的是实际参数所在单元的地址。在过程中,对该形式参数的引用相当于对实际参数所在的存储单元的地址引用。任何改变形式参数值得操作会反映在该存储单元中,也就是反映在该存储单元中,也就是反映在实际参数中,因此,数据的传送是双向的。

      java:按址传递指每次传递参数时,把参数在内存中的存储地址传递到方法内部,在方法内部通过存储地址改变对应存储区域的内容。由于内存中固定地址的值只有一个,所以当方法内部修改了参数的值之后,参数原始的值也会发生变化。

      使用这种传递方式,在方法内部修改参数的同时,参数原始的值也发生改变。

  3>名调用/换名调用

      要求被调用者的运行方式好像是用实在参数以字面方式替换了被调用者代码中的形式参数一样。这么做就好像形式参数是一个代表了实在参数的宏。当实在参数是一个表达式而不是一个变量时,会发生一些和直觉不符的问题。

     严格讲,名调用并不能算作真正的过程调用和参数传递。名调用被早期的程序设计语言Algol60使用(我第一次听说)。这种调用方式告诉你,眼见未必为实!

   4>复制恢复

     该机制下,参数在被子程序调用时只是对实在参数的拷贝进行操作,实在参数不发生改变,这是复制后操作。子程序操作完成后进行恢复,形式参数的值恢复到实在参数,即将实在参数的结果改为形式参数的最终值。

 

下面是一个简单的例子:

   主程序: A:=2;B:=3;

            P(A+B,A,A);

            PRINT A;

   子程序:Px,y,z){

           y=y+1;

           Z=x+5;

           }

 

   四种传递机制的结果:

 

    1>值传递

    主:                                       

 

A

2

B

3

A+B  

5

    子:

 

x

5

y

3

7

<!--EndFragment-->

    2>址传递

    主:                                       

 

A

8

B

3

A+B  

5

    子:

 

x

(A+B)

y

A

A

 

 

    3>复制恢复

    主:                                       

 

A

7

B

3

A+B  

5

    子:

 

x

5

y

3

7

 

 

    4>

    主:                                       

 

A

11

B

3

A+B  

5

    子:

A=A+1=3

A=A+B+5

 

二、下面着重对比一下java中的参数传递机制:

  java中,参数传递一般有两种方法:按值传递和按址传递。每种数据类型的传递方式都是固定的。

  1、按值传递的数据类型有:八种基本数据类型和String(事实上,String是按址传递的,但string对象和其他对象不同的是,string对象是不能被改变的,内容改变就会产生新的对象)  

  2、按址传递的数据类型:除String以外的所有复合数据类型,包括数组类和接口。

  下面是一个简单的java示例:

 

public class Test0 {

	/**参数传递机制测试
	 * @param args
	 */
	public static void main(String[] args) {
		int m=10;
		int a[]={100,200,300};
		System.out.println("调用前: m:"+m+" a[1]:"+a[1]);
		test(m,a);
		System.out.println("调用后: m:"+m+" a[1]:"+a[1]);
	}

	private static void test(int m, int[] a) {
		m=20;
		a[1]=2000;
	}
}

 

 

  凡事无绝对,参数传递机制也并非呆板固定的,下面两个有趣的例子说明这一点:

public class Test1 {

	/**参数传递测试
	 * @param args
	 */
	public static void main(String[] args) {
		//1、按值传递的类型通过返回值修改参数的值
		int m=10;
		System.out.println("m修改前:"+m);
		//通过修改以后的参数n(test1的形参)的返回值,来为变量m赋值,从而达到修正参数的目的。
		m=test1(m);//手动赋值
		System.out.println("m修改后:"+m);
		
		//2、按址传递通过重新生成变量避免修改参数的值:
		int a[]={1,2,3};
		System.out.println("a[1]修改前:"+a[1]);
		//通过在方法内部新创建一个数组,并且把传入数组的每个参数的值都付给新创建的数组,
		//从而实现复制数组内容,然后在修改复制后数组中的值时,原来的参数内容就不发生改变了。
		test2(a);
		System.out.println("a[1]修改后:"+a[1]);
	}
  
	private static int test1(int n) {
		n=20;
		return n;
	}
	  
	private static void test2(int[] m) {
		int n[]=new int[m.length];
		for(int i=0;i<m.length;i++){
			n[i]=m[i];
		}
		n[1]=100;
	}
}

 

 

ps:感谢《编译原理》和互联网的支持!

<!--EndFragment-->

分享到:
评论

相关推荐

    Java方法的参数传递机制实例详解

    主要介绍了Java方法的参数传递机制,结合实例形式详细分析了java方法参数传递机制原理、实现方法及操作注意事项,需要的朋友可以参考下

    基于信号传递博弈的供应链需求信息共享机制

    运用信号传递博弈理论,设计一种分离均衡的利润共享契约机制,利润共享参数起到了传递信息的信号作用.分析表明,此契约机制不仅可以实现信息共享,而且克服了以往研究中存在的不足,同时实现了供应链系统绩效的最优化....

    python 函数传参之传值还是传引用的分析

    基本的参数传递机制有两种:值传递和引用传递。  值传递(passl-by-value)过程中,被调函数的形式参数作为被调函数的局部变量处理,即在堆栈中开辟了内存空间以存放由主调函数放进来的实参的值,从而成为了实参的...

    论文研究-访问验证保护级安全操作系统审计机制研究.pdf

    论述了基于B3级安全操作系统审计报警模块增强策略与方法。...通过审计事件多角度分析、安全字段参数控制、审计序列关联分析、由时间戳控制隐蔽通道阈值、引入干扰等阻止信息传递策略,增强了系统的安全性能。

    Android View刷新机制实例分析

    1).ViewGroup的addView方法,理解参数的意义和传递 invalidate调用父类View的方法 addViewInner方法主要做的事情是 view的dispatchAttachedToWindow(AttachInfo info, int visibility)方法 1).View的invalidate方法...

    裂殖壶菌发酵产DHA 过程呼吸参数的在线检测分析 (2013年)

    通过呼吸参数在线检测分析,从氧消耗机制方面解释了双阶段氧传递控制工艺能获得较高生物量?油脂和DHA 含量的原因,从而为该工艺过程提供了理论指导。根据发酵过程中菌体生长不同时期的呼吸参数的变化情况,建立了...

    编译原理--龙书

    7.5 参数传递机制 292 7.5.1 值传递 293 7.5.2 引用传递 294 7.5.3 值结果传递 295 7.5.4 名字传递 295 7.6 TINY语言的运行时环境 296 练习 297 编程练习 303 注意与参考 304 第8章 代码生成 305 8.1 中间...

    PPC和MIPS指令集下二进制代码中函数参数个数的识别方法

    Findargs从PPC和MIPS指令集的函数调用特点出发,利用函数调用关系和参数传递分析,识别函数参数的个数,为函数原型的恢复提供帮助。为了评估Findargs的识别效果,选取大型的二进制文件进行了测试,并与radare2进行了...

    《编译原理及实践》电子书下载

    7.5 参数传递机制 292 7.5.1 值传递 293 7.5.2 引用传递 294 7.5.3 值结果传递 295 7.5.4 名字传递 295 7.6 TINY语言的运行时环境 296 练习 297 编程练习 303 注意与参考 304 第8章 代码生成 305 8.1 中间代码和用于...

    编译原理中文版

    7.5 参数传递机制 292 7.5.1 值传递 293 7.5.2 引用传递 294 7.5.3 值结果传递 295 7.5.4 名字传递 295 7.6 TINY语言的运行时环境 296 练习 297 编程练习 303 注意与参考 304 第8章 代码生成 305 8.1 中间代码和用于...

    《编译原理》 清华 第二版

    7.5 参数传递机制 292 7.5.1 值传递 293 7.5.2 引用传递 294 7.5.3 值结果传递 295 7.5.4 名字传递 295 7.6 TINY语言的运行时环境 296 练习 297 编程练习 303 注意与参考 304 第8章 代码生成 305 8.1 中间代码和用于...

    C#编译原理 ZIP 压缩文件

    7.5 参数传递机制 292 7.5.1 值传递 293 7.5.2 引用传递 294 7.5.3 值结果传递 295 7.5.4 名字传递 295 7.6 TINY语言的运行时环境 296 练习 297 编程练习 303 注意与参考 304 第8章 代码生成 305 8.1 中间代码和用于...

    煤中伴生金属元素对煤低温氧化特性的影响

    计算氧化动力学参数,并结合自由基反应理论,分析了7种金属元素对煤自燃作用机制。研究结果表明,Mg、Zn、Ca、Al、K、Na等元素阻化率在9.5%~57.9%,在60~180 ℃的低温氧化活化能最大增加29.6%,上述金属无机盐与...

    编译原理(china-pub) 高清

    7.5 参数传递机制 292 7.5.1 值传递 293 7.5.2 引用传递 294 7.5.3 值结果传递 295 7.5.4 名字传递 295 7.6 TINY语言的运行时环境 296 练习 297 编程练习 303 注意与参考 304 第8章 代码生成 305 8.1 中间代码和用于...

    编译原理及实践

    7.5 参数传递机制 292 7.5.1 值传递 293 7.5.2 引用传递 294 7.5.3 值结果传递 295 7.5.4 名字传递 295 7.6 TINY语言的运行时环境 296 练习 297 编程练习 303 注意与参考 304 第8章 代码生成 305 8.1 中间代码和用于...

    编译原理及实践 附有目录

    7.5 参数传递机制 292 7.5.1 值传递 293 7.5.2 引用传递 294 7.5.3 值结果传递 295 7.5.4 名字传递 295 7.6 TINY语言的运行时环境 296 练习 297 编程练习 303 注意与参考 304 第8章 代码生成 305 8.1 中间代码和用于...

    编译原理及实现

    7.5 参数传递机制 292 7.5.1 值传递 293 7.5.2 引用传递 294 7.5.3 值结果传递 295 7.5.4 名字传递 295 7.6 TINY语言的运行时环境 296 练习 297 编程练习 303 注意与参考 304 第8章 代码生成 305 8.1 中间代码和用于...

    面向网络化的机械产品参数化协同设计研究 (2012年)

    针对系列化产品设计中信息共享程度低、信息传递速度慢、重复劳动多的问题,提出了一种面向网络化的参数化协同设计方法。分析了分布式协同设计中共享冲突和网络异构的问题,提出了基于PDMWorks workgroup协同设计平台...

    揭秘数据解密的关键技术

    1.9.4 算数运算指令 1.9.5 逻辑运算指令 1.9.6 移位指令 1.9.7 条件转移指令 1.9.8 函数调用指令 1.1 0函数调用约定 1.1 0.1 3种常用的调用约定 1.1 0.2 调用约定的参数传递顺序 1.1 1字节码 1.1 1.1 代码和数据的...

    编译原理及实践(需要了解编译原理的可以看看)

    7.5 参数传递机制 292 7.5.1 值传递 293 7.5.2 引用传递 294 7.5.3 值结果传递 295 7.5.4 名字传递 295 7.6 TINY语言的运行时环境 296 练习 297 编程练习 303 注意与参考 304 第8章 代码生成 305 8.1 中间代码和用于...

Global site tag (gtag.js) - Google Analytics