在编程语言中,方法对于参数的调用分为传值调用和传引用调用。
传值调用(Call by Value)
传值调用是指方法在调用参数时,不是对原参数进行操作,而是创建参数的拷贝并对其进行操作,这种调用有利于保护数据.其在JAVA中的实现如下:
public class Test {
public static void main(String[] args) {
int a = 0;
int b = 1;
swap(a, b);
}
//交换i j的值
public static void swap(int i, int j) {
int temp = i;
i = j;
j = temp;
}
}
程序输出结果:
a : 0 b : 1
a : 0 b : 1
也就是说,其实方法的运行并没有改变a,b的值,让我们深入JVM的内存中看看是怎么回事:
先看看JVM的存储区(图1)
对于swap(a, b)的方法调用,可以这样理解,a,b两个引用存储在Heap内,他们的int值0和1存储在Stack内,在调用swap方法时,新建了i,j两个引用
i,j也指向int值0和1,在方法内互换的是i,j所指向的值,所以a,b所指向的并未发生改变
JAVA中的方法,只能对封装在类内部的
变量的值进行操作,例子:
1.MyClass类封装variable
public class MyClass {
public int variable = 0;
public void setVariable(int i) {
variable = i;
}
}
2.测试类Test
public class Test {
public static void main(String[] args) {
MyClass mc1 = new MyClass();
MyClass mc2 = new MyClass();
mc2.setVariable(1); // mc2.variable的值设为1
swapOne(mc1, mc2); // 这行代码等于无效
swapTwo(mc1, mc2); // 这行代码交换了mc1和mc2的variable的值
}
public static void swapOne(MyClass mc1k, MyClass mc2k) {
MyClass temp = mc1k;
mc1k = mc2k;
mc2k = temp;
}
public static void swapTwo(MyClass mc1k, MyClass mc2k) {
int temp = mc1k.variable;
mc1k.variable = mc2k.variable;
mc2k.variable = temp;
}
}
程序输出结果 :
mc1's variable is 0
mc2's variable is 1
mc1's variable is 1
mc2's variable is 0
解析:方法的拷贝出mc1和mc2的引用mc1k和mc2k.
mc1与mc1k指向同一个实例MyClass(其中实例内的variable == 0);
mc2与mc2k指向同一个实例MyClass(其中实例内的variable == 1);
swapOne方法交换了mc1k和mc2k所指向的对象,但是mc1k和mc2k在方法结束后被JVM回收了,mc1和mc2没有改变
swapTwo方法通过mc1k和mc2k互换了指向的对象MyClass里面的
变量variable的值,mc1和mc2的指向的实例并未改变,但是指向的实例内的变量的值改变了,所以看起来好像是mc1和mc2所指向的实例互换了.
在C语言中,被调用函数不能直接修改主调用函数中变量的值,而只能修改其私有的临时副本的值。
传值调用,即传递给被调用函数的参数值存放在临时变量中,而不是存放在原来的变量中。
例如求幂:
#include
调用函数:
int power(int,int );//函数声明,即函数原型,其中的参数类型不可省略,但参数名是可选的
int main()
{
int i;
for(i=0;i<10;++i)
getchar();
}
以下是函数定义;n>=0
每次调用时,
main函数向power函数传递2个参数,在调用执行完成时,power函数向main函数返回一个格式化的整数并打印。
被调用函数①
int power(int base,int n)
{
int i,p;
p=1;
for(i=1;i<=n;++i)
p=p*base;
return p;
}
函数也可以定义成以下模式、
被调用函数②:
int power(int base,int n)
{
int p;
for(p=1;n>0;--n)
p=p*base;
return p;
}
函数②中n是调用函数main传递给被调用函数power的,在for循环中n被当成临时变量直到自减为不大于0而退出循环;这种方法称为参数的‘传值调用’。显然函数②比函数①少用了一个变量i,这样程序也更紧凑简洁。