`
freewxy
  • 浏览: 342762 次
  • 性别: 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-->

分享到:
评论

相关推荐

    c/C++可变参数函数的参数传递机制剖析

    本文深入探讨了C/C++语言中可变参数函数的参数传递机制,并提出了一种更加精确且灵活的设计方法来处理这类函数。通过分析,我们不仅理解了如何在函数内部访问这些可变参数,还了解了实现这一功能的具体步骤和技术...

    深入剖析C++函数的参数传递机制

    通过上述分析可以看出,C++中的参数传递机制有三种:值传递、指针传递和引用传递。每种方式都有其特点和适用场景: - **值传递**:适合于不需要修改原始数据的情况,尤其是对于内置类型或较小的对象。 - **指针传递...

    关于C语言中函数调用和参数传递机制的探讨.txt

    ### 关于C语言中函数调用和参数传递机制的探讨 在C语言中,函数是程序的基本构建单元之一,它们不仅能够实现代码的重用,还能通过参数传递机制实现数据的有效交互。本文将深入探讨C语言中的函数调用机制以及参数...

    线程间通信方式2:参数传递方式

    本文将详细探讨“线程间通信方式2:参数传递方式”,并通过对不同创建线程方法的分析,展示如何有效地传递参数。 1. **线程创建方法** 在Windows API中,我们通常使用以下三种方法创建线程: - **CreateThread...

    易语言多线程传递多参数

    总之,易语言多线程传递多参数是一项关键的编程技能,它涉及到线程的创建、管理和参数传递。理解并掌握这些知识,能够帮助开发者编写出更高效、更稳定的程序。对于易语言的学习者来说,研究这个源码将是一个宝贵的...

    JAVA语言中参数传递的深入剖析.pdf

    本文对Java语言中参数传递机制进行了深入的剖析,首先从Java的变量内存分配机制开始,对不同的参数传递机制进行了分析,并得出了最合理的结论。 Java语言中参数传递机制可以分为两种情况,即按值传递和引用传递。按...

    深入分析C语言中函数参数传递.pdf

    C语言是最基础的编程语言之一,对于初学者来说,理解C语言的函数参数传递机制是非常重要的。本文将深入分析C语言中函数参数传递的机制,探讨函数调用时数据的传递关系,并通过实例来解释C语言函数参数传递的三种方式...

    VC编程时CPU中参数的传递的方法与总结

    本项目通过实例分析,深入探讨了指针、结构体和数组在CPU参数传递中的工作原理,以及如何进行内存分配、释放和使用。下面我们将详细解析这些知识点。 首先,我们来理解CPU参数传递的基本原则。在C++编程中,函数...

    页面之间传递参数

    通过合理的参数传递机制,可以使用户在浏览网站时体验更加流畅、高效。本文将详细解析页面间参数传递的方式及其应用场景,并结合提供的代码片段进行深入分析。 #### 一、URL参数传递 在Web开发中,最常见的一种...

    Silverlight参数传递

    通过有效的参数传递机制,开发者能够确保数据的一致性和准确性,同时也能够提高程序的可维护性和扩展性。例如,在一个电子商务应用中,当用户从商品列表页面点击某个商品时,系统需要将该商品的信息传递到详情页面,...

    java 参数传递

    Java 参数传递机制详解 Java 中的参数传递机制是一个经久不息的讨论...Java 参数传递机制详解,揭开了 Java 中的参数传递机制的奥秘,详细分析了基本类型和对象作为参数传递的机制,并揭开了对象作为参数传递的迷惑。

    QTP中action之前的参数传递详解

    本文将详细解析QTP中Action之间的参数传递机制,结合具体示例进行深入探讨。 ### QTP中Action参数传递的概念 Action参数传递是指在一个Action执行完毕后,将其执行过程中生成的数据作为参数传递给下一个Action,...

    采用图示分析法剖析C语言函数参数传递规律.pdf

    在C语言中,函数参数的传递是程序设计中的一个重要概念。本文通过内存图示分析法,系统地剖析了...通过本文的分析,我们可以更深入地掌握C语言中函数参数传递的机制,从而在实际编程中更加灵活和高效地运用这些知识。

    ARM汇编与C的参数传递

    下面我们通过两个具体的例子来进一步分析这种参数传递机制。 ### 实例1:传递四个参数 **汇编代码(test_asm_args.asm)** ```assembly IMPORT test_c_args; 调用C函数test_c_args AREA TEST_ASM, CODE, READONLY...

    易语言DLL传递数组测试程序源码,易语言向DLL传递数组参数的实现

    4. **传递数组**:在调用`调用动态链接库`命令时,将创建的数组对象作为参数传递。易语言会自动处理数组的地址,使得DLL能够正确访问到数组内容。 5. **处理返回值**:如果DLL函数有返回值,记得接收并处理这个...

    C语言教学中函数参数传递问题探讨.pdf

    C语言是一种广泛使用的编程语言,其函数参数传递是编程中的一个核心概念。在教学过程中,对于初学者而言,准确理解函数参数的传递方式尤为重要,但时常因为概念不清晰而造成理解上的困难。本文探讨了C语言中函数参数...

    Java零基础-参数传递-1.md

    本文旨在深入解析Java语言中的参数传递机制。作为一门广泛使用的编程语言,Java提供了多种处理数据的方法,其中参数传递是函数(方法)间数据交互的基础。本文将重点讨论Java中方法调用时的基本类型和引用类型参数...

    weka 中参数传递的使用方法

    对于学习者和研究者而言,掌握Weka中的参数传递机制至关重要,这不仅能够提升模型训练的效率,还能帮助优化模型性能,达到更佳的预测效果。 #### Weka参数传递的核心概念 参数传递是Weka软件中一个关键的概念,它...

    浅析Java引用类型和方法参数传递

    - Java中的方法参数传递机制遵循“按值传递”的原则。 - 当传递值类型时,方法内部对参数的任何修改都不会影响原始变量。 - 当传递引用类型时,尽管仍然遵循按值传递的原则,但由于传递的是引用的值,因此对引用所...

    C语言程序设计中函数参数传递的研究.pdf

    数组作为一种数据类型,在完成函数参数传递时,编译系统会将形参数组处理为指针变量,所以数组在参数传递中与指针传递是相同的。 函数调用中参数传递的本质是函数调用时,实参和形参存放在两个不同的存储单元中。...

Global site tag (gtag.js) - Google Analytics