函数的参数传引用、指针、值的本质区别和不同
参数传入引用时,实际上是一个标签化的过程,一般需要传入的是一个变量,即可以作为左值的东西。有这样一种解释:在数值(注意数值和变量的区别)传入的过程中,会先将参数赋值给一个const 类型的变量,然后再由该变量将值传给函数中的参数。这样一来,如果函数的参数类型不是const的,则会发生错误,因为const的变量不允许赋给非const的变量。假设有这样一个函数的定义及调用:
int fun(int &i){};//定义
int a=10;//定义一个整形变量并赋值
fun(a*3);//传入参数a*3
在这样的使用中,被认为是错误的。原因就是fun()函数的参数是引用但不是const,传入这样的一个值(i*3这是一个值)会先赋给一个临时的const变量,然后才会将之赋给参数&i,而这个&i又不是const的,说明在该函数中可以将这个值进行改变,但是该引用指向的是一个const的变量,这是不允许的,故而出错。所以,可以这样改:
int fun(const int &i){};
int a=10;
fun(a*3);
这样一来,就可以传入非左值了。但是往往不这样使用,而是使用以下的方式:
int fun(int &i){};
int a=10;
a*=3;
fun(a);
这样就遵循了只能传入左值的规则。
引用还可以这样使用:
int array[size];
int &fun(int i){//定义一个函数,返回引用
return array[i];
}
fun = 10;//由于返回的array[i]是定义外部的,所以实际上是给array[i]赋了值。
但是
,如果是这样:
int &fun(){//定义一个函数,返回引用
int i=10;
return i;
}
fun = 10;//这个函数的定义就是错误的,因为返回了一个本地变量。原因是当函数使用完时,其堆栈会清空(我们知道i是存放在为函数建立的堆栈之中的),返回引用时,将不知道该引用指向何处。指针的使用也是类似的。以下就不再详谈。
指针及值传递
传入指针时,实际上传入的是一个地址,此时只是简单的让参数的指针变量指向了传入的指针指向的对象,不会说会在给机器的内存带来多大的压力,因为如果采用传值,假设该值是一个特别大的对象,就会发生这样的事:由于传入的是一个函数,会将该对象拷贝一份给该函数,函数采用的是堆栈的方式在机器内工作,所以函数的堆栈中会存放这个大的对象,会给内存带来很大的压力。但是如果采用指针或引用,则堆栈中这回存放指向使用的对象的指针和引用,从而大大减少了内存的压力,所以,参数传入指针和引用是被倡导的。